From cc5ab63922ef7c36992609b00349361825d4c08c Mon Sep 17 00:00:00 2001 From: Hare Date: Mon, 22 Jun 2026 17:37:51 +0900 Subject: [PATCH] Improve composition diagnostics --- crates/decodal-cli/src/main.rs | 9 + crates/decodal-core/src/constraints.rs | 244 ++++++++----- crates/decodal-core/src/diagnostic.rs | 18 +- crates/decodal-core/src/eval.rs | 338 ++++++++++++++---- crates/decodal-core/src/runtime.rs | 12 +- crates/decodal-wasm/src/lib.rs | 11 +- .../design/composition-and-materialization.md | 6 + .../souce/design/diagnostics-and-fallback.md | 42 ++- doc/manual/souce/design/runtime-model.md | 13 +- .../src/wasm/decodal_wasm_bg.wasm | Bin 218822 -> 228514 bytes 10 files changed, 518 insertions(+), 175 deletions(-) diff --git a/crates/decodal-cli/src/main.rs b/crates/decodal-cli/src/main.rs index 7aa0626..024e946 100644 --- a/crates/decodal-cli/src/main.rs +++ b/crates/decodal-cli/src/main.rs @@ -148,6 +148,15 @@ fn print_diagnostic(error: &Diagnostic) { end = error.span.end, message = error.message, ); + for label in &error.labels { + eprintln!( + " note {source}:{start}..{end}: {message}", + source = label.span.source.0, + start = label.span.start, + end = label.span.end, + message = label.message, + ); + } } fn print_data(data: &Data, indent: usize) { diff --git a/crates/decodal-core/src/constraints.rs b/crates/decodal-core/src/constraints.rs index 8f7c748..3ba6098 100644 --- a/crates/decodal-core/src/constraints.rs +++ b/crates/decodal-core/src/constraints.rs @@ -3,103 +3,154 @@ use alloc::{string::String, vec::Vec}; use crate::{ Diagnostic, DiagnosticKind, Span, ast::CompareOp, - runtime::{Constraint, LiteralValue, PrimitiveType}, + runtime::{Constraint, ConstraintEntry, LiteralValue, PrimitiveType}, }; pub fn normalize_constraints( - constraints: Vec, + constraints: Vec, span: Span, -) -> crate::Result> { - let mut primitive = None; - let mut lower: Option = None; - let mut upper: Option = None; +) -> crate::Result> { + let mut primitive: Option<(PrimitiveType, Span)> = None; + let mut lower: Option<(Bound, Span)> = None; + let mut upper: Option<(Bound, Span)> = None; let mut rest = Vec::new(); - for constraint in constraints { - match constraint { + for entry in constraints { + match entry.constraint { Constraint::Type(next) => match primitive { - Some(current) if current != next => { + Some((current, current_span)) if current != next => { return Err(Diagnostic::new( DiagnosticKind::Conflict, span, "primitive type constraints conflict", - )); + ) + .with_label(current_span, "first primitive constraint") + .with_label(entry.span, "conflicting primitive constraint")); } Some(_) => {} - None => primitive = Some(next), + None => primitive = Some((next, entry.span)), }, Constraint::Compare(op, value) => { let number = Number::from_literal(&value).ok_or_else(|| { Diagnostic::new( DiagnosticKind::TypeMismatch, - span, + entry.span, "comparison constraints require numeric literals", ) })?; match op { - CompareOp::Gt => merge_lower(&mut lower, Bound::new(number, false)), - CompareOp::Gte => merge_lower(&mut lower, Bound::new(number, true)), - CompareOp::Lt => merge_upper(&mut upper, Bound::new(number, false)), - CompareOp::Lte => merge_upper(&mut upper, Bound::new(number, true)), + CompareOp::Gt => { + merge_lower(&mut lower, (Bound::new(number, false), entry.span)) + } + CompareOp::Gte => { + merge_lower(&mut lower, (Bound::new(number, true), entry.span)) + } + CompareOp::Lt => { + merge_upper(&mut upper, (Bound::new(number, false), entry.span)) + } + CompareOp::Lte => { + merge_upper(&mut upper, (Bound::new(number, true), entry.span)) + } CompareOp::Eq => { - merge_lower(&mut lower, Bound::new(number, true)); - merge_upper(&mut upper, Bound::new(number, true)); + merge_lower(&mut lower, (Bound::new(number, true), entry.span)); + merge_upper(&mut upper, (Bound::new(number, true), entry.span)); } } } - Constraint::Regex(pattern) => rest.push(Constraint::Regex(pattern)), - Constraint::BuiltinPredicate(name) => rest.push(Constraint::BuiltinPredicate(name)), + Constraint::Regex(pattern) => rest.push(ConstraintEntry { + constraint: Constraint::Regex(pattern), + span: entry.span, + }), + Constraint::BuiltinPredicate(name) => rest.push(ConstraintEntry { + constraint: Constraint::BuiltinPredicate(name), + span: entry.span, + }), } } - if matches!(primitive, Some(PrimitiveType::String | PrimitiveType::Bool)) - && (lower.is_some() || upper.is_some()) + if matches!( + primitive, + Some((PrimitiveType::String | PrimitiveType::Bool, _)) + ) && (lower.is_some() || upper.is_some()) { - return Err(Diagnostic::new( + let mut diagnostic = Diagnostic::new( DiagnosticKind::Conflict, span, "numeric comparison constraints conflict with non-numeric primitive type", - )); + ); + if let Some((_, primitive_span)) = primitive { + diagnostic = diagnostic.with_label(primitive_span, "non-numeric primitive constraint"); + } + if let Some((_, lower_span)) = lower { + diagnostic = diagnostic.with_label(lower_span, "numeric comparison constraint"); + } + if let Some((_, upper_span)) = upper { + diagnostic = diagnostic.with_label(upper_span, "numeric comparison constraint"); + } + return Err(diagnostic); } - if primitive == Some(PrimitiveType::Int) + if matches!(primitive, Some((PrimitiveType::Int, _))) && lower .iter() .chain(upper.iter()) - .any(|bound| !matches!(bound.number, Number::Int(_))) + .any(|(bound, _)| !matches!(bound.number, Number::Int(_))) { - return Err(Diagnostic::new( + let mut diagnostic = Diagnostic::new( DiagnosticKind::Conflict, span, "Int comparison constraints must use integer literals", - )); + ); + if let Some((_, primitive_span)) = primitive { + diagnostic = diagnostic.with_label(primitive_span, "Int primitive constraint"); + } + if let Some((bound, bound_span)) = lower { + if !matches!(bound.number, Number::Int(_)) { + diagnostic = diagnostic.with_label(bound_span, "non-integer comparison constraint"); + } + } + if let Some((bound, bound_span)) = upper { + if !matches!(bound.number, Number::Int(_)) { + diagnostic = diagnostic.with_label(bound_span, "non-integer comparison constraint"); + } + } + return Err(diagnostic); } ensure_bounds_non_empty(primitive, lower, upper, span)?; let mut normalized = Vec::new(); - if let Some(primitive) = primitive { - normalized.push(Constraint::Type(primitive)); + if let Some((primitive, primitive_span)) = primitive { + normalized.push(ConstraintEntry { + constraint: Constraint::Type(primitive), + span: primitive_span, + }); } - if let Some(lower) = lower { - normalized.push(Constraint::Compare( - if lower.inclusive { - CompareOp::Gte - } else { - CompareOp::Gt - }, - lower.number.into_literal(), - )); + if let Some((lower, lower_span)) = lower { + normalized.push(ConstraintEntry { + constraint: Constraint::Compare( + if lower.inclusive { + CompareOp::Gte + } else { + CompareOp::Gt + }, + lower.number.into_literal(), + ), + span: lower_span, + }); } - if let Some(upper) = upper { - normalized.push(Constraint::Compare( - if upper.inclusive { - CompareOp::Lte - } else { - CompareOp::Lt - }, - upper.number.into_literal(), - )); + if let Some((upper, upper_span)) = upper { + normalized.push(ConstraintEntry { + constraint: Constraint::Compare( + if upper.inclusive { + CompareOp::Lte + } else { + CompareOp::Lt + }, + upper.number.into_literal(), + ), + span: upper_span, + }); } normalized.extend(rest); Ok(normalized) @@ -147,18 +198,22 @@ impl Number { } } -fn merge_lower(current: &mut Option, next: Bound) { +fn merge_lower(current: &mut Option<(Bound, Span)>, next: (Bound, Span)) { match current { None => *current = Some(next), - Some(current_bound) if is_stricter_lower(next, *current_bound) => *current_bound = next, + Some((current_bound, _)) if is_stricter_lower(next.0, *current_bound) => { + *current = Some(next) + } Some(_) => {} } } -fn merge_upper(current: &mut Option, next: Bound) { +fn merge_upper(current: &mut Option<(Bound, Span)>, next: (Bound, Span)) { match current { None => *current = Some(next), - Some(current_bound) if is_stricter_upper(next, *current_bound) => *current_bound = next, + Some((current_bound, _)) if is_stricter_upper(next.0, *current_bound) => { + *current = Some(next) + } Some(_) => {} } } @@ -178,28 +233,32 @@ fn is_stricter_upper(next: Bound, current: Bound) -> bool { } fn ensure_bounds_non_empty( - primitive: Option, - lower: Option, - upper: Option, + primitive: Option<(PrimitiveType, Span)>, + lower: Option<(Bound, Span)>, + upper: Option<(Bound, Span)>, span: Span, ) -> crate::Result<()> { - if primitive == Some(PrimitiveType::Int) { - let min = lower.map(int_lower_bound).unwrap_or(i128::from(i64::MIN)); - let max = upper.map(int_upper_bound).unwrap_or(i128::from(i64::MAX)); + if matches!(primitive, Some((PrimitiveType::Int, _))) { + let min = lower + .map(|(bound, _)| int_lower_bound(bound)) + .unwrap_or(i128::from(i64::MIN)); + let max = upper + .map(|(bound, _)| int_upper_bound(bound)) + .unwrap_or(i128::from(i64::MAX)); if min > max { - return Err(empty_numeric_bounds(span)); + return Err(empty_numeric_bounds(span, lower, upper)); } return Ok(()); } - if let (Some(lower), Some(upper)) = (lower, upper) { - let lower_value = lower.number.as_f64(); - let upper_value = upper.number.as_f64(); + if let (Some((lower_bound, _)), Some((upper_bound, _))) = (lower, upper) { + let lower_value = lower_bound.number.as_f64(); + let upper_value = upper_bound.number.as_f64(); if lower_value > upper_value { - return Err(empty_numeric_bounds(span)); + return Err(empty_numeric_bounds(span, lower, upper)); } - if lower_value == upper_value && !(lower.inclusive && upper.inclusive) { - return Err(empty_numeric_bounds(span)); + if lower_value == upper_value && !(lower_bound.inclusive && upper_bound.inclusive) { + return Err(empty_numeric_bounds(span, lower, upper)); } } Ok(()) @@ -227,12 +286,23 @@ fn int_upper_bound(bound: Bound) -> i128 { } } -fn empty_numeric_bounds(span: Span) -> Diagnostic { - Diagnostic::new( +fn empty_numeric_bounds( + span: Span, + lower: Option<(Bound, Span)>, + upper: Option<(Bound, Span)>, +) -> Diagnostic { + let mut diagnostic = Diagnostic::new( DiagnosticKind::Conflict, span, String::from("numeric comparison constraints have an empty intersection"), - ) + ); + if let Some((_, lower_span)) = lower { + diagnostic = diagnostic.with_label(lower_span, "lower bound constraint"); + } + if let Some((_, upper_span)) = upper { + diagnostic = diagnostic.with_label(upper_span, "upper bound constraint"); + } + diagnostic } #[cfg(test)] @@ -240,13 +310,20 @@ mod tests { use super::*; use crate::runtime::LiteralValue; + fn entry(constraint: Constraint) -> ConstraintEntry { + ConstraintEntry { + constraint, + span: Span::default(), + } + } + #[test] fn detects_primitive_conflict() { assert!( normalize_constraints( alloc::vec![ - Constraint::Type(PrimitiveType::Int), - Constraint::Type(PrimitiveType::String), + entry(Constraint::Type(PrimitiveType::Int)), + entry(Constraint::Type(PrimitiveType::String)), ], Span::default(), ) @@ -259,9 +336,9 @@ mod tests { assert!( normalize_constraints( alloc::vec![ - Constraint::Type(PrimitiveType::Int), - Constraint::Compare(CompareOp::Gt, LiteralValue::Int(10)), - Constraint::Compare(CompareOp::Lt, LiteralValue::Int(11)), + entry(Constraint::Type(PrimitiveType::Int)), + entry(Constraint::Compare(CompareOp::Gt, LiteralValue::Int(10))), + entry(Constraint::Compare(CompareOp::Lt, LiteralValue::Int(5))), ], Span::default(), ) @@ -270,15 +347,16 @@ mod tests { } #[test] - fn keeps_regex_constraints_without_intersection_check() { - let constraints = normalize_constraints( - alloc::vec![ - Constraint::Regex(String::from("^a$")), - Constraint::Regex(String::from("^b$")), - ], - Span::default(), - ) - .unwrap(); - assert_eq!(constraints.len(), 2); + fn detects_non_integer_int_bound() { + assert!( + normalize_constraints( + alloc::vec![ + entry(Constraint::Type(PrimitiveType::Int)), + entry(Constraint::Compare(CompareOp::Gt, LiteralValue::Float(1.5))), + ], + Span::default(), + ) + .is_err() + ); } } diff --git a/crates/decodal-core/src/diagnostic.rs b/crates/decodal-core/src/diagnostic.rs index 033bb81..2caf4c2 100644 --- a/crates/decodal-core/src/diagnostic.rs +++ b/crates/decodal-core/src/diagnostic.rs @@ -1,4 +1,4 @@ -use alloc::string::String; +use alloc::{string::String, vec::Vec}; use crate::span::Span; @@ -9,6 +9,13 @@ pub struct Diagnostic { pub kind: DiagnosticKind, pub span: Span, pub message: String, + pub labels: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DiagnosticLabel { + pub span: Span, + pub message: String, } impl Diagnostic { @@ -17,12 +24,21 @@ impl Diagnostic { kind, span, message: message.into(), + labels: Vec::new(), } } pub fn syntax(span: Span, message: impl Into) -> Self { Self::new(DiagnosticKind::Syntax, span, message) } + + pub fn with_label(mut self, span: Span, message: impl Into) -> Self { + self.labels.push(DiagnosticLabel { + span, + message: message.into(), + }); + self + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/crates/decodal-core/src/eval.rs b/crates/decodal-core/src/eval.rs index d376ff2..6220ad6 100644 --- a/crates/decodal-core/src/eval.rs +++ b/crates/decodal-core/src/eval.rs @@ -9,9 +9,9 @@ use crate::{ module::{EmptyLoader, LoadedSource, Module, SourceLoader}, parse_source_with_source_id, runtime::{ - AbstractValue, Binding, ConcreteValue, Constraint, Data, DataField, Env, EnvId, ExprRef, - FunctionParam, FunctionValue, LiteralValue, ModuleId, ObjectField, ObjectValue, - PrimitiveType, RuntimeValue, Thunk, ThunkId, ThunkKind, ThunkState, + AbstractValue, Binding, ConcreteValue, Constraint, ConstraintEntry, Data, DataField, Env, + EnvId, ExprRef, FunctionParam, FunctionValue, LiteralValue, ModuleId, ObjectField, + ObjectValue, PrimitiveType, RuntimeValue, Thunk, ThunkId, ThunkKind, ThunkState, }, }; @@ -84,6 +84,14 @@ impl Engine { } pub fn materialize(&mut self, value: &RuntimeValue) -> Result { + self.materialize_with_path(value, &mut Vec::new()) + } + + fn materialize_with_path( + &mut self, + value: &RuntimeValue, + path: &mut Vec, + ) -> Result { match value { RuntimeValue::Concrete(value) => match value { ConcreteValue::String(value) => Ok(Data::String(value.clone())), @@ -94,7 +102,7 @@ impl Engine { let mut data = Vec::new(); for item in items { let value = self.force(*item)?; - data.push(self.materialize(&value)?); + data.push(self.materialize_with_path(&value, path)?); } Ok(Data::Array(data)) } @@ -102,30 +110,51 @@ impl Engine { let mut fields = Vec::new(); for field in &object.fields { let value = self.force(field.value)?; + path.push(field.name.clone()); + let value = self.materialize_with_path(&value, path); + path.pop(); fields.push(DataField { name: field.name.clone(), - value: self.materialize(&value)?, + value: value?, }); } Ok(Data::Object(fields)) } - ConcreteValue::Function(_) => Err(Diagnostic::new( - DiagnosticKind::Materialize, - Span::default(), - "cannot materialize function value", + ConcreteValue::Function(_) => Err(self.with_path_context( + Diagnostic::new( + DiagnosticKind::Materialize, + Span::default(), + "cannot materialize function value", + ), + "materializing", + path, )), }, RuntimeValue::Abstract(abstract_value) => { let Some(default) = abstract_value.default else { - return Err(Diagnostic::new( + let mut diagnostic = Diagnostic::new( DiagnosticKind::Materialize, - Span::default(), + constraint_primary_span(&abstract_value.constraints), "cannot materialize unresolved abstract value without default", - )); + ); + for constraint in &abstract_value.constraints { + diagnostic = diagnostic.with_label( + constraint.span, + "constraint still requires a concrete value or default", + ); + } + return Err(self.with_path_context(diagnostic, "materializing", path)); }; + let default_span = self.thunk_span(default); let value = self.force(default)?; - self.ensure_satisfies(&value, &abstract_value.constraints, Span::default())?; - self.materialize(&value) + self.ensure_satisfies( + &value, + &abstract_value.constraints, + default_span, + Some((default_span, "default value checked here")), + ) + .map_err(|diag| self.with_path_context(diag, "materializing", path))?; + self.materialize_with_path(&value, path) } } } @@ -475,12 +504,18 @@ impl Engine { ) })?; Ok(RuntimeValue::Abstract(AbstractValue { - constraints: vec![Constraint::Compare(op, value)], + constraints: vec![ConstraintEntry { + constraint: Constraint::Compare(op, value), + span, + }], default: None, })) } Expr::RegexConstraint(pattern) => Ok(RuntimeValue::Abstract(AbstractValue { - constraints: vec![Constraint::Regex(pattern)], + constraints: vec![ConstraintEntry { + constraint: Constraint::Regex(pattern), + span, + }], default: None, })), Expr::Wildcard => Err(Diagnostic::new( @@ -494,7 +529,10 @@ impl Engine { fn eval_ident(&mut self, name: &str, env: EnvId, span: Span) -> Result { if let Some(primitive) = primitive_type(name) { return Ok(RuntimeValue::Abstract(AbstractValue { - constraints: vec![Constraint::Type(primitive)], + constraints: vec![ConstraintEntry { + constraint: Constraint::Type(primitive), + span, + }], default: None, })); } @@ -503,7 +541,10 @@ impl Engine { } if name.chars().next().is_some_and(char::is_uppercase) { return Ok(RuntimeValue::Abstract(AbstractValue { - constraints: vec![Constraint::BuiltinPredicate(String::from(name))], + constraints: vec![ConstraintEntry { + constraint: Constraint::BuiltinPredicate(String::from(name)), + span, + }], default: None, })); } @@ -551,7 +592,7 @@ impl Engine { )); } if path.len() == 1 { - let value = self.add_expr_thunk(ExprRef { module, expr }, env); + let value = self.add_expr_thunk_with_span(ExprRef { module, expr }, env, span); if object.fields.iter().any(|field| field.name == path[0]) { return Err(Diagnostic::new( DiagnosticKind::Conflict, @@ -562,6 +603,7 @@ impl Engine { object.fields.push(ObjectField { name: path[0].clone(), value, + span, }); return Ok(()); } @@ -577,8 +619,10 @@ impl Engine { )); }; self.insert_field(&mut nested, module, &path[1..], expr, env, span)?; - object.fields[index].value = - self.add_value_thunk(RuntimeValue::Concrete(ConcreteValue::Object(nested))); + object.fields[index].value = self.add_value_thunk_with_span( + RuntimeValue::Concrete(ConcreteValue::Object(nested)), + span, + ); return Ok(()); } @@ -586,7 +630,11 @@ impl Engine { self.insert_field(&mut nested, module, &path[1..], expr, env, span)?; object.fields.push(ObjectField { name: name.clone(), - value: self.add_value_thunk(RuntimeValue::Concrete(ConcreteValue::Object(nested))), + value: self.add_value_thunk_with_span( + RuntimeValue::Concrete(ConcreteValue::Object(nested)), + span, + ), + span, }); Ok(()) } @@ -646,6 +694,7 @@ impl Engine { value, &abstract_value.constraints, self.expr_span(pattern), + None, ) .map(|_| true) .or_else(|diag| match diag.kind { @@ -673,12 +722,17 @@ impl Engine { (RuntimeValue::Abstract(mut lhs), RuntimeValue::Abstract(rhs)) => { lhs.constraints.extend(rhs.constraints); lhs.constraints = normalize_constraints(lhs.constraints, span)?; - lhs.default = merge_default(lhs.default, rhs.default, span)?; + lhs.default = self.merge_default(lhs.default, rhs.default, span)?; Ok(RuntimeValue::Abstract(lhs)) } (RuntimeValue::Abstract(abstract_value), concrete @ RuntimeValue::Concrete(_)) | (concrete @ RuntimeValue::Concrete(_), RuntimeValue::Abstract(abstract_value)) => { - self.ensure_satisfies(&concrete, &abstract_value.constraints, span)?; + self.ensure_satisfies( + &concrete, + &abstract_value.constraints, + span, + Some((span, "concrete value being composed here")), + )?; Ok(concrete) } ( @@ -711,10 +765,17 @@ impl Engine { .iter() .position(|lhs_field| lhs_field.name == rhs_field.name) { + let lhs_field_span = lhs.fields[index].span; let lhs_value = self.force(lhs.fields[index].value)?; let rhs_value = self.force(rhs_field.value)?; - let value = self.compose_and(lhs_value, rhs_value, span)?; - lhs.fields[index].value = self.add_value_thunk(value); + let value = self + .compose_and(lhs_value, rhs_value, span) + .map_err(|diag| { + diag.with_label(span, format!("while composing field `{}`", rhs_field.name)) + .with_label(lhs_field_span, format!("left field `{}`", rhs_field.name)) + .with_label(rhs_field.span, format!("right field `{}`", rhs_field.name)) + })?; + lhs.fields[index].value = self.add_value_thunk_with_span(value, rhs_field.span); } else { lhs.fields.push(rhs_field); } @@ -742,7 +803,8 @@ impl Engine { let lhs_value = self.force(lhs.fields[index].value)?; let rhs_value = self.force(rhs_field.value)?; let value = self.patch(lhs_value, rhs_value)?; - lhs.fields[index].value = self.add_value_thunk(value); + lhs.fields[index].value = self.add_value_thunk_with_span(value, rhs_field.span); + lhs.fields[index].span = rhs_field.span; } else { lhs.fields.push(rhs_field); } @@ -753,11 +815,12 @@ impl Engine { fn ensure_satisfies( &mut self, value: &RuntimeValue, - constraints: &[Constraint], + constraints: &[ConstraintEntry], span: Span, + value_label: Option<(Span, &'static str)>, ) -> Result<()> { for constraint in constraints { - self.satisfies(value, constraint, span)?; + self.satisfies(value, constraint, span, value_label)?; } Ok(()) } @@ -765,17 +828,20 @@ impl Engine { fn satisfies( &mut self, value: &RuntimeValue, - constraint: &Constraint, + constraint: &ConstraintEntry, span: Span, + value_label: Option<(Span, &'static str)>, ) -> Result<()> { - match constraint { + let constraint_value = &constraint.constraint; + match constraint_value { Constraint::Type(primitive) => { if value_matches_primitive(value, *primitive) { Ok(()) } else { - Err(Diagnostic::new( - DiagnosticKind::ConstraintViolation, + Err(self.constraint_violation( + constraint, span, + value_label, "value does not satisfy primitive type constraint", )) } @@ -783,18 +849,69 @@ impl Engine { Constraint::Compare(op, expected) => compare_value(value, *op, expected) .then_some(()) .ok_or_else(|| { - Diagnostic::new( - DiagnosticKind::ConstraintViolation, + self.constraint_violation( + constraint, span, + value_label, "value does not satisfy comparison constraint", ) }), - Constraint::Regex(pattern) => satisfies_regex(value, pattern, span), + Constraint::Regex(pattern) => { + satisfies_regex(value, pattern, constraint.span).map_err(|diag| { + let diag = diag.with_label(constraint.span, "regex constraint declared here"); + if let Some((span, message)) = value_label { + diag.with_label(span, message) + } else { + diag + } + }) + } Constraint::BuiltinPredicate(name) => Err(Diagnostic::new( DiagnosticKind::UnsupportedFeature, - span, + constraint.span, format!("builtin predicate `{name}` is not implemented"), - )), + ) + .with_label(span, "constraint checked during this operation")), + } + } + + fn constraint_violation( + &self, + constraint: &ConstraintEntry, + operation_span: Span, + value_label: Option<(Span, &'static str)>, + message: &'static str, + ) -> Diagnostic { + let mut diagnostic = Diagnostic::new( + DiagnosticKind::ConstraintViolation, + constraint.span, + message, + ) + .with_label(constraint.span, "constraint declared here") + .with_label(operation_span, "constraint checked during this operation"); + if let Some((span, message)) = value_label { + diagnostic = diagnostic.with_label(span, message); + } + diagnostic + } + + fn merge_default( + &self, + lhs: Option, + rhs: Option, + span: Span, + ) -> Result> { + match (lhs, rhs) { + (None, None) => Ok(None), + (Some(value), None) | (None, Some(value)) => Ok(Some(value)), + (Some(lhs), Some(rhs)) if lhs == rhs => Ok(Some(lhs)), + (Some(lhs), Some(rhs)) => Err(Diagnostic::new( + DiagnosticKind::DefaultConflict, + span, + "conflicting defaults", + ) + .with_label(self.thunk_span(lhs), "left default value") + .with_label(self.thunk_span(rhs), "right default value")), } } @@ -831,6 +948,7 @@ impl Engine { object.fields.push(ObjectField { name: field.name, value, + span: Span::default(), }); } Ok(RuntimeValue::Concrete(ConcreteValue::Object(object))) @@ -845,6 +963,13 @@ impl Engine { } else { None }; + let constraints = constraints + .into_iter() + .map(|constraint| ConstraintEntry { + constraint, + span: Span::default(), + }) + .collect(); let constraints = normalize_constraints(constraints, Span::default())?; Ok(RuntimeValue::Abstract(AbstractValue { constraints, @@ -906,7 +1031,12 @@ impl Engine { } fn add_expr_thunk(&mut self, expr: ExprRef, env: EnvId) -> ThunkId { - self.add_thunk(ThunkKind::Expr { expr, env }) + let span = self.expr_span(expr); + self.add_expr_thunk_with_span(expr, env, span) + } + + fn add_expr_thunk_with_span(&mut self, expr: ExprRef, env: EnvId, span: Span) -> ThunkId { + self.add_thunk(ThunkKind::Expr { expr, env }, span) } fn add_constrained_thunk( @@ -916,23 +1046,32 @@ impl Engine { value: ExprRef, value_env: EnvId, ) -> ThunkId { - self.add_thunk(ThunkKind::Constrained { - constraint, - constraint_env, - value, - value_env, - }) + let span = self.expr_span(value); + self.add_thunk( + ThunkKind::Constrained { + constraint, + constraint_env, + value, + value_env, + }, + span, + ) } fn add_value_thunk(&mut self, value: RuntimeValue) -> ThunkId { - self.add_thunk(ThunkKind::Value(value)) + self.add_value_thunk_with_span(value, Span::default()) } - fn add_thunk(&mut self, kind: ThunkKind) -> ThunkId { + fn add_value_thunk_with_span(&mut self, value: RuntimeValue, span: Span) -> ThunkId { + self.add_thunk(ThunkKind::Value(value), span) + } + + fn add_thunk(&mut self, kind: ThunkKind, span: Span) -> ThunkId { let id = ThunkId(self.thunks.len() as u32); self.thunks.push(Thunk { kind, state: ThunkState::Unevaluated, + span, }); id } @@ -977,9 +1116,28 @@ impl Engine { } fn expr_span(&self, reference: ExprRef) -> Span { - self.modules[reference.module.0 as usize] - .ast - .span(reference.expr) + self.modules + .get(reference.module.0 as usize) + .map(|module| module.ast.span(reference.expr)) + .unwrap_or_default() + } + + fn thunk_span(&self, thunk: ThunkId) -> Span { + self.thunks[thunk.0 as usize].span + } + + fn with_path_context( + &self, + diagnostic: Diagnostic, + phase: &'static str, + path: &[String], + ) -> Diagnostic { + if path.is_empty() { + diagnostic + } else { + let span = diagnostic.span; + diagnostic.with_label(span, format!("while {phase} `{}`", path.join("."))) + } } } @@ -1005,6 +1163,13 @@ fn primitive_type(name: &str) -> Option { } } +fn constraint_primary_span(constraints: &[ConstraintEntry]) -> Span { + constraints + .first() + .map(|constraint| constraint.span) + .unwrap_or_default() +} + fn literal_to_concrete(literal: Literal) -> ConcreteValue { match literal { Literal::String(value) => ConcreteValue::String(value), @@ -1343,23 +1508,6 @@ fn concrete_scalar_eq(lhs: &ConcreteValue, rhs: &ConcreteValue) -> bool { } } -fn merge_default( - lhs: Option, - rhs: Option, - span: Span, -) -> Result> { - match (lhs, rhs) { - (None, None) => Ok(None), - (Some(value), None) | (None, Some(value)) => Ok(Some(value)), - (Some(lhs), Some(rhs)) if lhs == rhs => Ok(Some(lhs)), - (Some(_), Some(_)) => Err(Diagnostic::new( - DiagnosticKind::DefaultConflict, - span, - "conflicting defaults", - )), - } -} - #[cfg(test)] mod tests { use super::*; @@ -1372,6 +1520,62 @@ mod tests { engine.materialize(&value).unwrap() } + #[test] + fn constraint_violation_reports_related_spans() { + let parsed = parse_source("port = Int & > 443 default 80;").unwrap(); + let mut engine = Engine::from_parse(parsed.ast, parsed.root); + let value = engine.eval_root().unwrap(); + let error = engine.materialize(&value).unwrap_err(); + assert_eq!(error.kind, DiagnosticKind::ConstraintViolation); + assert!( + error + .labels + .iter() + .any(|label| label.message.contains("constraint declared here")) + ); + assert!( + error + .labels + .iter() + .any(|label| label.message.contains("default value checked here")) + ); + } + + #[test] + fn object_composition_conflict_reports_both_fields() { + let parsed = parse_source("{ port = 80; } & { port = 443; }").unwrap(); + let mut engine = Engine::from_parse(parsed.ast, parsed.root); + let error = engine.eval_root().unwrap_err(); + assert_eq!(error.kind, DiagnosticKind::Conflict); + assert!( + error + .labels + .iter() + .any(|label| label.message == "left field `port`") + ); + assert!( + error + .labels + .iter() + .any(|label| label.message == "right field `port`") + ); + } + + #[test] + fn materialize_error_reports_field_path() { + let parsed = parse_source("service.port = Int;").unwrap(); + let mut engine = Engine::from_parse(parsed.ast, parsed.root); + let value = engine.eval_root().unwrap(); + let error = engine.materialize(&value).unwrap_err(); + assert_eq!(error.kind, DiagnosticKind::Materialize); + assert!( + error + .labels + .iter() + .any(|label| label.message.contains("while materializing `service.port`")) + ); + } + #[test] fn materializes_default() { let data = eval_data("port = Int & >= 1 default 8080;"); diff --git a/crates/decodal-core/src/runtime.rs b/crates/decodal-core/src/runtime.rs index efd9c9b..2366e8f 100644 --- a/crates/decodal-core/src/runtime.rs +++ b/crates/decodal-core/src/runtime.rs @@ -1,6 +1,6 @@ use alloc::{string::String, vec::Vec}; -use crate::{ExprId, ast::CompareOp}; +use crate::{ExprId, Span, ast::CompareOp}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ModuleId(pub u32); @@ -37,6 +37,7 @@ pub struct ObjectValue { pub struct ObjectField { pub name: String, pub value: ThunkId, + pub span: Span, } #[derive(Debug, Clone, PartialEq)] @@ -54,10 +55,16 @@ pub struct FunctionParam { #[derive(Debug, Clone, PartialEq)] pub struct AbstractValue { - pub constraints: Vec, + pub constraints: Vec, pub default: Option, } +#[derive(Debug, Clone, PartialEq)] +pub struct ConstraintEntry { + pub constraint: Constraint, + pub span: Span, +} + #[derive(Debug, Clone, PartialEq)] pub enum Constraint { Type(PrimitiveType), @@ -108,6 +115,7 @@ pub struct EnvId(pub u32); pub struct Thunk { pub kind: ThunkKind, pub state: ThunkState, + pub span: Span, } #[derive(Debug, Clone)] diff --git a/crates/decodal-wasm/src/lib.rs b/crates/decodal-wasm/src/lib.rs index 4a8090f..a67d12f 100644 --- a/crates/decodal-wasm/src/lib.rs +++ b/crates/decodal-wasm/src/lib.rs @@ -125,14 +125,21 @@ fn normalize_path(path: &str) -> Option { } fn format_diagnostic(diagnostic: decodal_core::Diagnostic) -> String { - format!( + let mut out = format!( "{:?} at {}:{}..{}: {}", diagnostic.kind, diagnostic.span.source.0, diagnostic.span.start, diagnostic.span.end, diagnostic.message, - ) + ); + for label in diagnostic.labels { + out.push_str(&format!( + "\nnote at {}:{}..{}: {}", + label.span.source.0, label.span.start, label.span.end, label.message, + )); + } + out } fn format_data(data: &Data, indent: usize) -> String { diff --git a/doc/manual/souce/design/composition-and-materialization.md b/doc/manual/souce/design/composition-and-materialization.md index 686c0f2..6792737 100644 --- a/doc/manual/souce/design/composition-and-materialization.md +++ b/doc/manual/souce/design/composition-and-materialization.md @@ -117,3 +117,9 @@ Abstract { constraints, default: None } materialize は default を採用する唯一の段階である。 通常評価中に明示値が得られた場合、default は採用されない。 + +## Diagnostic context + +Composition and materialization keep source spans for object fields, constraints, defaults, and thunks where possible. +When a conflict occurs, the diagnostic should identify the operation span and related participant spans, such as the left field, right field, constraint, or default value. +For object materialization errors, diagnostics also include the field path being processed when known. diff --git a/doc/manual/souce/design/diagnostics-and-fallback.md b/doc/manual/souce/design/diagnostics-and-fallback.md index 99a259a..40323b4 100644 --- a/doc/manual/souce/design/diagnostics-and-fallback.md +++ b/doc/manual/souce/design/diagnostics-and-fallback.md @@ -10,10 +10,19 @@ Diagnostic { kind: DiagnosticKind span: Span message: String - notes: Vec + labels: Vec +} + +DiagnosticLabel { + span: Span + message: String } ``` +`span` は primary location を示す。 +`labels` は同じ error に関係する追加 location を示す。 +合成や materialize の失敗では、衝突した constraint、value、default、または処理中 field path を label に含める。 + 代表的な diagnostic kind: - syntax error @@ -38,6 +47,18 @@ Result これにより、制約違反、未定義識別子、循環依存、import 失敗などが通常値として流れることを避ける。 +## 合成と materialize の diagnostic + +合成や materialize の失敗は、以下を示す。 + +1. どの段階で失敗したか: composition、patch、materialization +2. どの field path を処理中だったか +3. どの constraint、value、default が衝突したか +4. なぜ合成または materialize できないか + +例えば default が constraint を満たさない場合は、constraint の位置と default value の位置の両方を label として持つ。 +object field の合成で concrete value が衝突する場合は、左辺 field と右辺 field の位置を label として持つ。 + ## `try / catch` は core に入れない 汎用 `try / catch` は core に入れない。 @@ -47,21 +68,6 @@ fallback は有限で明示的な仕組みに限定する。 - `default`: 未指定値の fallback。 - `match`: 有限 pattern に基づく分岐。 -- optional import: ファイル不存在など、限定された失敗だけを fallback 可能にする候補。 -- optional field access: field 不在だけを fallback 可能にする候補。 -- union / tagged schema: 複数 schema の選択を明示的に表す将来候補。 -## optional fallback の扱い - -optional import や optional field access を導入する場合も、捕捉できる失敗は限定する。 - -例として optional import は、ファイル不存在だけを fallback 可能にし、parse error や import 先の制約違反は diagnostic として報告する方がよい。 - -```text -optional import: - file not found -> fallback - parse error -> diagnostic - eval error -> diagnostic -``` - -この方針により、fallback は通常の値選択として扱い、エラー内容に依存した実行時分岐は避ける。 +Decodal は `unknown` / `any` を持たないため、field 不在や未解決 identifier を fallback 可能な通常値として扱わない。 +それらは diagnostic として報告する。 diff --git a/doc/manual/souce/design/runtime-model.md b/doc/manual/souce/design/runtime-model.md index b097b7d..a52bfbe 100644 --- a/doc/manual/souce/design/runtime-model.md +++ b/doc/manual/souce/design/runtime-model.md @@ -36,7 +36,11 @@ object は concrete structure として扱う。 ```text ObjectValue: - fields: Map + fields: Map + +ObjectField: + value: ThunkId + span: Span ``` 例えば以下の schema object は、object 自体は concrete だが、field の値は abstract value になる。 @@ -61,9 +65,14 @@ Concrete(Object { ```text AbstractValue { - constraints: Vec + constraints: Vec default: Option } + +ConstraintEntry { + constraint: Constraint + span: Span +} ``` `default` は `AbstractValue` にだけ存在する。 diff --git a/site/decodal-site/src/wasm/decodal_wasm_bg.wasm b/site/decodal-site/src/wasm/decodal_wasm_bg.wasm index c613ab312f9654f3b25d15eea859a79b960be10a..25635b8701f4c7917b845f7d1d7634732fe0c0b9 100644 GIT binary patch delta 93643 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