Skip to content

Commit

Permalink
fix(frontend): Ban type vars bound to a reference from passing the un…
Browse files Browse the repository at this point in the history
…constrained boundary (#5949)

# Description

## Problem\*

Resolves <!-- Link to GitHub Issue -->

Quick fix found while searching for other bugs

## Summary\*

I have provided an example test which would previously panic during ACIR
gen about all references not being resolved. However, we should have
been allowing the code in the first place as it was attempting to pass a
mutable reference from the constrained boundary to the unconstrained
boundary.

## Additional Context



## Documentation\*

Check one:
- [X] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
vezenovm authored Sep 5, 2024
1 parent 344dd5e commit ce34fbd
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
10 changes: 8 additions & 2 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,13 +1099,19 @@ impl Type {
| Type::Unit
| Type::Constant(_)
| Type::Slice(_)
| Type::TypeVariable(_, _)
| Type::NamedGeneric(_, _, _)
| Type::Function(_, _, _, _)
| Type::FmtString(_, _)
| Type::InfixExpr(..)
| Type::Error => true,

Type::TypeVariable(type_var, _) | Type::NamedGeneric(type_var, _, _) => {
if let TypeBinding::Bound(typ) = &*type_var.borrow() {
typ.is_valid_for_unconstrained_boundary()
} else {
true
}
}

// Quoted objects only exist at compile-time where the only execution
// environment is the interpreter. In this environment, they are valid.
Type::Quoted(_) => true,
Expand Down
29 changes: 29 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3424,3 +3424,32 @@ fn errors_on_unused_function() {
assert_eq!(ident.to_string(), "foo");
assert_eq!(*item_type, "function");
}

#[test]
fn constrained_reference_to_unconstrained() {
let src = r#"
fn main(mut x: u32, y: pub u32) {
let x_ref = &mut x;
if x == 5 {
unsafe {
mut_ref_input(x_ref, y);
}
}
assert(x == 10);
}
unconstrained fn mut_ref_input(x: &mut u32, y: u32) {
*x = y;
}
"#;

let errors = get_program_errors(src);
assert_eq!(errors.len(), 1);

let CompilationError::TypeError(TypeCheckError::ConstrainedReferenceToUnconstrained { .. }) =
&errors[0].0
else {
panic!("Expected an error about passing a constrained reference to unconstrained");
};
}

0 comments on commit ce34fbd

Please sign in to comment.