From 4024add4da2e2cfbda065e0ee06274222c8113b3 Mon Sep 17 00:00:00 2001 From: rvcas Date: Mon, 16 Jan 2023 14:53:33 -0500 Subject: [PATCH] feat: error when an expression is implicitly discarded --- crates/aiken-lang/src/tipo/error.rs | 12 ++++++++++++ crates/aiken-lang/src/tipo/expr.rs | 13 ++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 772f1333..81475bc2 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -50,6 +50,9 @@ pub enum Error { #[error("I found a data type that has a function type in it. This is not allowed.")] FunctionTypeInData { location: Span }, + #[error("I found a discarded expression not bound to a variable.")] + ImplicityDiscardedExpression { location: Span }, + #[error("I saw a {} fields in a context where there should be {}.\n", given.purple(), expected.purple())] IncorrectFieldsArity { location: Span, @@ -372,6 +375,9 @@ impl Diagnostic for Error { Self::DuplicateName { .. } => Some(Box::new("duplicate_name")), Self::DuplicateTypeName { .. } => Some(Box::new("duplicate_type_name")), Self::FunctionTypeInData { .. } => Some(Box::new("function_type_in_data")), + Self::ImplicityDiscardedExpression { .. } => { + Some(Box::new("implicitly_discarded_expr")) + } Self::IncorrectFieldsArity { .. } => Some(Box::new("incorrect_fields_arity")), Self::IncorrectFunctionCallArity { .. } => Some(Box::new("incorrect_fn_arity")), Self::IncorrectPatternArity { .. } => Some(Box::new("incorrect_pattern_arity")), @@ -488,6 +494,7 @@ impl Diagnostic for Error { Self::FunctionTypeInData { .. } => Some(Box::new("Data types can't have functions in them due to how Plutus Data works.")), + Self::ImplicityDiscardedExpression { .. } => Some(Box::new("Everything is an expression and returns a value.\nTry assigning this expression to a variable.")), Self::IncorrectFieldsArity { .. } => None, Self::IncorrectFunctionCallArity { expected, .. } => Some(Box::new(formatdoc! { @@ -1149,6 +1156,10 @@ impl Diagnostic for Error { Self::FunctionTypeInData { location } => Some(Box::new( vec![LabeledSpan::new_with_span(None, *location)].into_iter(), )), + + Self::ImplicityDiscardedExpression { location, .. } => Some(Box::new( + vec![LabeledSpan::new_with_span(None, *location)].into_iter(), + )), Self::IncorrectFieldsArity { location, .. } => Some(Box::new( vec![LabeledSpan::new_with_span(None, *location)].into_iter(), )), @@ -1282,6 +1293,7 @@ impl Diagnostic for Error { Self::DuplicateName { .. } => None, Self::DuplicateTypeName { .. } => None, Self::FunctionTypeInData { .. } => None, + Self::ImplicityDiscardedExpression { .. } => None, Self::IncorrectFieldsArity { .. } => Some(Box::new( "https://aiken-lang.org/language-tour/custom-types", )), diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 4f42c8ca..ec65725a 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -171,7 +171,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { /// Emit a warning if the given expressions should not be discarded. /// e.g. because it's a literal (why was it made in the first place?) /// e.g. because it's of the `Result` type (errors should be handled) - fn expression_discarded(&mut self, discarded: &TypedExpr) { + fn _expression_discarded(&mut self, discarded: &TypedExpr) { if discarded.is_literal() { self.environment.warnings.push(Warning::UnusedLiteral { location: discarded.location(), @@ -1684,9 +1684,16 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let expression = self.infer(expression)?; // This isn't the final expression in the sequence, so call the // `expression_discarded` function to see if anything is being - // discarded that we think shouldn't be. + // discarded that we think shouldn't be. We also want to make sure + // that there are no implicitly discarded expressions if i < count - 1 { - self.expression_discarded(&expression); + // self.expression_discarded(&expression); + + if !matches!(expression, TypedExpr::Assignment { .. }) { + return Err(Error::ImplicityDiscardedExpression { + location: expression.location(), + }); + } } expressions.push(expression);