From 976262c2e69f3c58c7cc5dbc62425c47d5d1b47b Mon Sep 17 00:00:00 2001 From: KtorZ Date: Wed, 17 Jul 2024 18:11:09 +0200 Subject: [PATCH] Allow discard in expect. Fixes #967. --- CHANGELOG.md | 2 ++ crates/aiken-lang/src/tests/check.rs | 43 +++++++++++++++++++++++++++- crates/aiken-lang/src/tipo/expr.rs | 2 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e77243fe..f4a2b02d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - **aiken-lang**: duplicate import lines are now automatically merged instead of raising a warning. However, imports can no longer appear anywhere in the file and must come as the first definitions. @KtorZ +- **aiken-lang**: remove warning on discarded expect, allowing to keep 'side-effects' when necessary. See #967. @KtorZ + ## v1.0.29-alpha - 2024-06-06 ### Added diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index b3bb32f0..b157d0ce 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{Definition, ModuleKind, TraceLevel, Tracing, TypedModule, UntypedModule}, + ast::{Definition, ModuleKind, Pattern, TraceLevel, Tracing, TypedModule, UntypedModule}, builtins, expr::TypedExpr, parser, @@ -2720,3 +2720,44 @@ fn if_soft_cast_not_data() { assert!(matches!(warnings[0], Warning::UseWhenInstead { .. })) } + +#[test] +fn side_effects() { + let source_code = r#" + pub fn side_effects() { + trace "Aiken, rocks!" + Void + } + + pub fn foo() { + expect _ = side_effects() + True + } + "#; + + let (warnings, ast) = check(parse(source_code)).unwrap(); + + assert!(warnings.is_empty(), "no warnings: {warnings:#?}"); + + if let Some(Definition::Fn(ref foo)) = ast.definitions().last() { + if let TypedExpr::Sequence { + ref expressions, .. + } = foo.body + { + matches!( + expressions[..], + [ + TypedExpr::Assignment { + pattern: Pattern::Discard { .. }, + .. + }, + TypedExpr::Var { .. }, + ], + ); + } else { + unreachable!(); + } + } else { + unreachable!(); + } +} diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index cc5733c7..102afa14 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -1251,7 +1251,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .check_exhaustiveness(&[&pattern], location, false) .is_ok(); - if !value_is_data && is_exaustive_pattern { + if !value_is_data && is_exaustive_pattern && !pattern.is_discard() { self.environment .warnings .push(Warning::SingleConstructorExpect {