Skip to content

Commit

Permalink
Fix incorrect warning about unused variable when softcasting without …
Browse files Browse the repository at this point in the history
…explicit right-pattern.

  See note added in code for a rationale.
  • Loading branch information
KtorZ committed Sep 20, 2024
1 parent 7155b4e commit a8b3782
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- **aiken-lang**: Fix formatter adding extra unnecessary newlines after literal lists clause values or assignments. @KtorZ
- **aiken-lang**: Fix formatting of long multi-line if/is expressions. @KtorZ
- **aiken-lang**: Fix extraneous white-space added by the formatter after multiline alternative patterns. @KtorZ
- **aiken-lang**: Fix incorrect warning about unused variable when softcasting without explicit right-pattern. @KtorZ
- **uplc**: Fix cost-models for PlutusV1 & PlutusV2. @MicroProofs

### Removed
Expand Down
19 changes: 19 additions & 0 deletions crates/aiken-lang/src/tests/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3276,3 +3276,22 @@ fn wrong_arity_on_known_builtin() {
Err((_, Error::IncorrectFunctionCallArity { .. }))
))
}

#[test]
fn softcasting_unused_let_binding() {
let source_code = r#"
pub fn is_int(data: Data) -> Bool {
if data is Int {
True
} else {
False
}
}
"#;

let result = dbg!(check(parse(source_code)));
assert!(result.is_ok());

let (warnings, _) = result.unwrap();
assert!(warnings.is_empty(), "should not contain any warnings");
}
31 changes: 30 additions & 1 deletion crates/aiken-lang/src/tipo/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,36 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
// If `expect` is explicitly used, we still check exhaustiveness but instead of returning an
// error we emit a warning which explains that using `expect` is unnecessary.
match kind {
AssignmentKind::Is => (),
AssignmentKind::Is => {
let pattern_var_name = match pattern {
Pattern::Var { ref name, .. } => Some(name),
_ => None,
};

let value_var_name = match typed_value {
TypedExpr::Var { ref name, .. } => Some(name),
_ => None,
};

// In case where we have no explicit pattern, we end up introducing a new let
// binding with the same name as the value. However, the assigned value may not
// necessarily be used, resulting in an annoying warning when one only wants to
// assert a type.
//
// if foo is Int { // foo is unused here but shouldn't generated warnings.
// True
// } else {
// False
// }
//
// The following check removes the warning by marking the new let-binding as used
// in this particular context.
if let Some(pattern_var_name) = pattern_var_name {
if Some(pattern_var_name) == value_var_name {
self.environment.increment_usage(pattern_var_name);
}
}
}
AssignmentKind::Let { .. } => {
self.environment
.check_exhaustiveness(&[&pattern], location, true)?
Expand Down

0 comments on commit a8b3782

Please sign in to comment.