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
	
	 Matthias Benkort
						Matthias Benkort