Skip to content

Commit

Permalink
fix: Slice coercions (#4640)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves #4639 

## Summary\*

The array to slice coercion was broken - and it seemingly has always
been so. The coercion never actually called `replace_expr` to replace
the original expression with the `as_slice(original_expr)` coercion.

## 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
jfecher authored Mar 26, 2024
1 parent 4deda65 commit c0bae17
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 5 deletions.
15 changes: 10 additions & 5 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1662,14 +1662,19 @@ fn convert_array_expression_to_slice(
let as_slice = HirExpression::Ident(HirIdent::non_trait_method(as_slice_id, location));
let func = interner.push_expr(as_slice);

let arguments = vec![expression];
// Copy the expression and give it a new ExprId. The old one
// will be mutated in place into a Call expression.
let argument = interner.expression(&expression);
let argument = interner.push_expr(argument);
interner.push_expr_type(argument, array_type.clone());
interner.push_expr_location(argument, location.span, location.file);

let arguments = vec![argument];
let call = HirExpression::Call(HirCallExpression { func, arguments, location });
let call = interner.push_expr(call);
interner.replace_expr(&expression, call);

interner.push_expr_location(call, location.span, location.file);
interner.push_expr_location(func, location.span, location.file);

interner.push_expr_type(call, target_type.clone());
interner.push_expr_type(expression, target_type.clone());

let func_type = Type::Function(vec![array_type], Box::new(target_type), Box::new(Type::Unit));
interner.push_expr_type(func, func_type);
Expand Down
7 changes: 7 additions & 0 deletions test_programs/execution_success/slice_coercion/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "slice_coercion"
type = "bin"
authors = [""]
compiler_version = ">=0.25.0"

[dependencies]
2 changes: 2 additions & 0 deletions test_programs/execution_success/slice_coercion/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
first = 3
expected = 3
19 changes: 19 additions & 0 deletions test_programs/execution_success/slice_coercion/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
struct Hasher {
fields: [Field],
}

impl Hasher {
pub fn new() -> Self {
Self { fields: [] }
}

pub fn add(&mut self, field: Field) {
self.fields = self.fields.push_back(field);
}
}

fn main(expected: pub Field, first: Field) {
let mut hasher = Hasher::new();
hasher.add(first);
assert(hasher.fields[0] == expected);
}

0 comments on commit c0bae17

Please sign in to comment.