Merge pull request #1125 from aiken-lang/always-typecheck-trace-label
rework trace label evaluation strategy
This commit is contained in:
commit
e872b9eb2e
|
@ -14,6 +14,7 @@
|
|||
- **aiken-lang**: Change default placeholder for `trace` to `Void` instead of `todo`. @KtorZ
|
||||
- **aiken-lang**: Disallow (parse error) dangling colon `:` in traces. See [#1113](https://github.com/aiken-lang/aiken/issues/1113). @KtorZ
|
||||
- **aiken-lang**: Fix `aiken blueprint apply` wrongly overriding all validators handlers names & ABI to the mint's one. See [#1099](https://github.com/aiken-lang/aiken/issues/1099). @KtorZ
|
||||
- **aiken-lang**: Always type-check trace label irrespective of the trace level, to avoid unnecessary warnings in compact or silent mode. See [#1122](https://github.com/aiken-lang/aiken/issues/1122). @KtorZ
|
||||
- **aiken-lang**: Formatter was removing comments from function type annotation args @rvcas
|
||||
- **aiken-lang**: Parser wrongly merged two adjacent sequences together, effectively fusioning scopes. @KtorZ
|
||||
- **aiken-lang**: Fix hint when suggesting to use named fields, wrongly suggesting args in lexicographical order instead of definition order. @KtorZ
|
||||
|
|
|
@ -1321,8 +1321,8 @@ fn trace_non_string_label_compact() {
|
|||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
check_with_verbosity(parse(source_code), TraceLevel::Compact),
|
||||
Err((_, Error::CouldNotUnify { .. }))
|
||||
&check_with_verbosity(parse(source_code), TraceLevel::Compact),
|
||||
Ok((warnings, _)) if warnings == &[Warning::CompactTraceLabelIsNotstring { location: Span::create(40, 7) }],
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -1865,6 +1865,15 @@ pub enum Warning {
|
|||
location: Span,
|
||||
suggestion: UntypedPattern,
|
||||
},
|
||||
|
||||
#[error("I noticed a (compact) dynamic trace label which is not a string")]
|
||||
#[diagnostic(help("Compiling with a compact trace-level, you are probably expecting compact traces although here, the entire label will need to be serialise *at runtime* which will add a significant overhead.\n\nAs a reminder, trace arguments are fully ignored in compact tracing. Hence, you probably want to put a cute little label here and move the current trace as argument!"))]
|
||||
#[diagnostic(code("trace::label_is_not_string"))]
|
||||
#[diagnostic(url("https://aiken-lang.org/language-tour/troubleshooting#traces"))]
|
||||
CompactTraceLabelIsNotstring {
|
||||
#[label("compact trace label is not String")]
|
||||
location: Span,
|
||||
},
|
||||
}
|
||||
|
||||
impl ExtraData for Warning {
|
||||
|
@ -1884,6 +1893,7 @@ impl ExtraData for Warning {
|
|||
| Warning::UnusedVariable { .. }
|
||||
| Warning::DiscardedLetAssignment { .. }
|
||||
| Warning::ValidatorInLibraryModule { .. }
|
||||
| Warning::CompactTraceLabelIsNotstring { .. }
|
||||
| Warning::UseWhenInstead { .. } => None,
|
||||
Warning::Utf8ByteArrayIsValidHexString { value, .. } => Some(value.clone()),
|
||||
Warning::UnusedImportedModule { location, .. } => {
|
||||
|
|
|
@ -2506,6 +2506,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn infer_trace_arg(&mut self, arg: UntypedExpr) -> Result<TypedExpr, Error> {
|
||||
let location = arg.location();
|
||||
let typed_arg = self.infer(arg)?;
|
||||
match self.unify(
|
||||
Type::string(),
|
||||
|
@ -2514,6 +2515,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
false,
|
||||
) {
|
||||
Err(_) => {
|
||||
if matches!(self.tracing.trace_level(false), TraceLevel::Compact) {
|
||||
self.environment
|
||||
.warnings
|
||||
.push(Warning::CompactTraceLabelIsNotstring { location });
|
||||
}
|
||||
|
||||
self.unify(Type::data(), typed_arg.tipo(), typed_arg.location(), true)?;
|
||||
Ok(diagnose_expr(typed_arg))
|
||||
}
|
||||
|
@ -2546,44 +2553,38 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
})
|
||||
}
|
||||
|
||||
let label = self.infer_trace_arg(label)?;
|
||||
|
||||
let text = if typed_arguments.is_empty() {
|
||||
label.clone()
|
||||
} else {
|
||||
let delimiter = |ix| TypedExpr::String {
|
||||
location: Span::empty(),
|
||||
tipo: Type::string(),
|
||||
value: if ix == 0 { ": " } else { ", " }.to_string(),
|
||||
};
|
||||
typed_arguments
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.fold(label.clone(), |text, (ix, arg)| {
|
||||
append_string_expr(append_string_expr(text, delimiter(ix)), arg)
|
||||
})
|
||||
};
|
||||
|
||||
match self.tracing.trace_level(false) {
|
||||
TraceLevel::Silent => Ok(then),
|
||||
TraceLevel::Compact => {
|
||||
let text = self.infer(label)?;
|
||||
self.unify(Type::string(), text.tipo(), text.location(), false)?;
|
||||
Ok(TypedExpr::Trace {
|
||||
location,
|
||||
tipo,
|
||||
then: Box::new(then),
|
||||
text: Box::new(text),
|
||||
})
|
||||
}
|
||||
TraceLevel::Verbose => {
|
||||
let label = self.infer_trace_arg(label)?;
|
||||
|
||||
let text = if typed_arguments.is_empty() {
|
||||
label
|
||||
} else {
|
||||
let delimiter = |ix| TypedExpr::String {
|
||||
location: Span::empty(),
|
||||
tipo: Type::string(),
|
||||
value: if ix == 0 { ": " } else { ", " }.to_string(),
|
||||
};
|
||||
typed_arguments
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.fold(label, |text, (ix, arg)| {
|
||||
append_string_expr(append_string_expr(text, delimiter(ix)), arg)
|
||||
})
|
||||
};
|
||||
|
||||
Ok(TypedExpr::Trace {
|
||||
location,
|
||||
tipo,
|
||||
then: Box::new(then),
|
||||
text: Box::new(text),
|
||||
})
|
||||
}
|
||||
TraceLevel::Compact => Ok(TypedExpr::Trace {
|
||||
location,
|
||||
tipo,
|
||||
then: Box::new(then),
|
||||
text: Box::new(label),
|
||||
}),
|
||||
TraceLevel::Verbose => Ok(TypedExpr::Trace {
|
||||
location,
|
||||
tipo,
|
||||
then: Box::new(then),
|
||||
text: Box::new(text),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue