Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 11 additions & 22 deletions compiler/noirc_frontend/src/elaborator/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,11 @@ impl Elaborator<'_> {
// Each parameter of the enum variant function is used as a parameter of the enum
// constructor expression
let arguments = vecmap(&parameters.0, |(pattern, typ, _)| match pattern {
HirPattern::Identifier(ident) => {
let id = self.interner.push_expr(HirExpression::Ident(ident.clone(), None));
self.interner.push_expr_type(id, typ.clone());
self.interner.push_expr_location(id, location);
id
}
HirPattern::Identifier(ident) => self.interner.push_expr_full(
HirExpression::Ident(ident.clone(), None),
location,
typ.clone(),
),
_ => unreachable!(),
});

Expand All @@ -376,12 +375,9 @@ impl Elaborator<'_> {
variant_index,
});

let body = self.interner.push_expr(constructor);
let enum_generics = self_type.borrow().generic_types();
let typ = Type::DataType(self_type.clone(), enum_generics);
self.interner.push_expr_type(body, typ);
self.interner.push_expr_location(body, location);
body
self.interner.push_expr_full(constructor, location, typ)
}

fn make_enum_variant_parameters(
Expand Down Expand Up @@ -1271,9 +1267,7 @@ impl<'elab, 'ctx> MatchCompiler<'elab, 'ctx> {
let variable = HirIdent::non_trait_method(variable, location);

let rhs = HirExpression::Ident(HirIdent::non_trait_method(rhs, location), None);
let rhs = self.elaborator.interner.push_expr(rhs);
self.elaborator.interner.push_expr_type(rhs, rhs_type);
self.elaborator.interner.push_expr_location(rhs, location);
let rhs = self.elaborator.interner.push_expr_full(rhs, location, rhs_type);

let let_ = HirStatement::Let(HirLetStatement {
pattern: HirPattern::Identifier(variable),
Expand All @@ -1285,17 +1279,12 @@ impl<'elab, 'ctx> MatchCompiler<'elab, 'ctx> {
});

let body_type = self.elaborator.interner.id_type(body);
let let_ = self.elaborator.interner.push_stmt(let_);
let body = self.elaborator.interner.push_stmt(HirStatement::Expression(body));

self.elaborator.interner.push_stmt_location(let_, location);
self.elaborator.interner.push_stmt_location(body, location);
let let_ = self.elaborator.interner.push_stmt_full(let_, location);
let body =
self.elaborator.interner.push_stmt_full(HirStatement::Expression(body), location);

let block = HirExpression::Block(HirBlockExpression { statements: vec![let_, body] });
let block = self.elaborator.interner.push_expr(block);
self.elaborator.interner.push_expr_type(block, body_type);
self.elaborator.interner.push_expr_location(block, location);
block
self.elaborator.interner.push_expr_full(block, location, body_type)
}

/// Any case that isn't branched to when the match is finished must be covered by another
Expand Down
78 changes: 38 additions & 40 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use crate::{
},
node_interner::{
DefinitionId, DefinitionKind, ExprId, FuncId, InternedStatementKind, StmtId, TraitItemId,
pusher::{HasLocation, PushedExpr},
},
shared::Signedness,
signed_field::SignedField,
Expand Down Expand Up @@ -108,9 +109,7 @@ impl Elaborator<'_> {
}
ExpressionKind::TypePath(path) => return self.elaborate_type_path(*path),
};
let id = self.interner.push_expr(hir_expr);
self.interner.push_expr_location(id, expr.location);
self.interner.push_expr_type(id, typ.clone());
let id = self.interner.push_expr_full(hir_expr, expr.location, typ.clone());

if is_integer_literal {
self.push_integer_literal_expr_id(id);
Expand Down Expand Up @@ -450,10 +449,9 @@ impl Elaborator<'_> {
self.handle_hir_ident(&hir_ident, var_scope_index, *location);

let hir_expr = HirExpression::Ident(hir_ident.clone(), None);
let expr_id = self.interner.push_expr(hir_expr);
self.interner.push_expr_location(expr_id, *location);
let typ = self.type_check_variable(hir_ident, expr_id, None);
self.interner.push_expr_type(expr_id, typ.clone());
let expr_id = self.intern_expr(hir_expr, *location);
let typ = self.type_check_variable(hir_ident, &expr_id, None);
let expr_id = self.intern_expr_type(expr_id, typ.clone());

capture_types.push(typ);
fmt_str_idents.push(expr_id);
Expand Down Expand Up @@ -499,8 +497,7 @@ impl Elaborator<'_> {
trait_method_id,
skip: skip_op,
});
let expr_id = self.interner.push_expr(expr);
self.interner.push_expr_location(expr_id, location);
let expr_id = self.intern_expr(expr, location);

let typ = if skip_op {
rhs_type
Expand All @@ -510,12 +507,12 @@ impl Elaborator<'_> {
result,
&rhs_type,
trait_method_id,
expr_id,
*expr_id,
location,
)
};

self.interner.push_expr_type(expr_id, typ.clone());
let expr_id = self.intern_expr_type(expr_id, typ.clone());
(expr_id, typ)
}

Expand Down Expand Up @@ -721,8 +718,9 @@ impl Elaborator<'_> {
);

let func_type =
self.type_check_variable(function_name.clone(), function_id, generics.clone());
self.interner.push_expr_type(function_id, func_type.clone());
self.type_check_variable(function_name.clone(), &function_id, generics.clone());

let function_id = self.intern_expr_type(function_id, func_type.clone());

let func_arg_types =
if let Type::Function(args, _, _, _) = &func_type { Some(args) } else { None };
Expand Down Expand Up @@ -863,9 +861,7 @@ impl Elaborator<'_> {
let type_hint =
if let Some(Type::Function(func_args, _, _, _)) = typ { Some(func_args) } else { None };
let (hir_expr, typ) = self.elaborate_lambda_with_parameter_type_hints(*lambda, type_hint);
let id = self.interner.push_expr(hir_expr);
self.interner.push_expr_location(id, location);
self.interner.push_expr_type(id, typ.clone());
let id = self.interner.push_expr_full(hir_expr, location, typ.clone());
(id, typ)
}

Expand Down Expand Up @@ -1110,15 +1106,23 @@ impl Elaborator<'_> {
// `is_offset` is only used when lhs is a reference and we want to return a reference to rhs
let access = HirMemberAccess { lhs, rhs, is_offset };
let expr_id = self.intern_expr(HirExpression::MemberAccess(access.clone()), location);
let typ = self.type_check_member_access(access, expr_id, lhs_type, rhs_location);
self.interner.push_expr_type(expr_id, typ.clone());
let typ = self.type_check_member_access(access, *expr_id, lhs_type, rhs_location);
let expr_id = self.intern_expr_type(expr_id, typ.clone());
(expr_id, typ, is_offset && is_reference)
}

pub fn intern_expr(&mut self, expr: HirExpression, location: Location) -> ExprId {
let id = self.interner.push_expr(expr);
self.interner.push_expr_location(id, location);
id
/// Push a [HirExpression] with its [Location], with the [Type] to be followed up later.
pub fn intern_expr(
&mut self,
expr: HirExpression,
location: Location,
) -> PushedExpr<HasLocation> {
self.interner.push_expr(expr).push_location(self.interner, location)
}

/// Follow up [Self::intern_expr] with the [Type].
pub fn intern_expr_type(&mut self, expr_id: PushedExpr<HasLocation>, typ: Type) -> ExprId {
expr_id.push_type(self.interner, typ)
}

fn elaborate_cast(
Expand Down Expand Up @@ -1148,19 +1152,18 @@ impl Elaborator<'_> {
rhs,
});

let expr_id = self.interner.push_expr(expr);
self.interner.push_expr_location(expr_id, location);
let expr_id = self.intern_expr(expr, location);

let result = self.infix_operand_type_rules(&lhs_type, &operator, &rhs_type, location);
let typ = self.handle_operand_type_rules_result(
result,
&lhs_type,
Some(trait_id),
expr_id,
*expr_id,
location,
);

self.interner.push_expr_type(expr_id, typ.clone());
let expr_id = self.intern_expr_type(expr_id, typ.clone());
(expr_id, typ)
}

Expand Down Expand Up @@ -1279,12 +1282,9 @@ impl Elaborator<'_> {
HirMatch::Failure { missing_case: false }
});

let tree = self.interner.push_expr(tree);
self.interner.push_expr_type(tree, result_type.clone());
self.interner.push_expr_location(tree, location);
let tree = self.interner.push_expr_full(tree, location, result_type.clone());

let tree = self.interner.push_stmt(HirStatement::Expression(tree));
self.interner.push_stmt_location(tree, location);
let tree = self.interner.push_stmt_full(HirStatement::Expression(tree), location);

let block = HirExpression::Block(HirBlockExpression { statements: vec![let_, tree] });
(block, result_type)
Expand All @@ -1299,8 +1299,7 @@ impl Elaborator<'_> {

let pattern = HirPattern::Identifier(HirIdent::non_trait_method(variable, location));
let let_ = HirStatement::Let(HirLetStatement::basic(pattern, typ, expr_id));
let let_ = self.interner.push_stmt(let_);
self.interner.push_stmt_location(let_, location);
let let_ = self.interner.push_stmt_full(let_, location);
(let_, variable)
}

Expand Down Expand Up @@ -1438,9 +1437,9 @@ impl Elaborator<'_> {
let make_error = |this: &mut Self, error: InterpreterError| {
let error: CompilationError = error.into();
this.push_err(error);
let error = this.interner.push_expr(HirExpression::Error);
this.interner.push_expr_location(error, location);
(error, Type::Error)
let typ = Type::Error;
let error = this.interner.push_expr_full(HirExpression::Error, location, typ.clone());
(error, typ)
};

let value = match value {
Expand Down Expand Up @@ -1584,8 +1583,7 @@ impl Elaborator<'_> {
impl_kind: ImplKind::TraitItem(trait_item),
};

let id = self.interner.push_expr(HirExpression::Ident(ident.clone(), None));
self.interner.push_expr_location(id, location);
let id = self.intern_expr(HirExpression::Ident(ident.clone(), None), location);

let mut bindings = TypeBindings::default();

Expand All @@ -1597,12 +1595,12 @@ impl Elaborator<'_> {

let typ = self.type_check_variable_with_bindings(
ident,
id,
&id,
None,
bindings,
push_required_type_variables,
);
self.interner.push_expr_type(id, typ.clone());
let id = self.intern_expr_type(id, typ.clone());
(id, typ)
}
}
3 changes: 1 addition & 2 deletions compiler/noirc_frontend/src/elaborator/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,7 @@ impl Elaborator<'_> {
FunctionKind::Normal => {
let return_type = func_meta.return_type();
let (block, body_type) = self.elaborate_block(body, Some(return_type));
let expr_id = self.intern_expr(block, body_location);
self.interner.push_expr_type(expr_id, body_type.clone());
let expr_id = self.interner.push_expr_full(block, body_location, body_type.clone());
(HirFunction::unchecked_from_expr(expr_id), body_type)
}
};
Expand Down
9 changes: 3 additions & 6 deletions compiler/noirc_frontend/src/elaborator/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ impl Elaborator<'_> {
let location = statement.location;
let (hir_statement, typ) =
self.elaborate_statement_value_with_target_type(statement, target_type);
let id = self.interner.push_stmt(hir_statement);
self.interner.push_stmt_location(id, location);
let id = self.interner.push_stmt_full(hir_statement, location);
(id, typ)
}

Expand Down Expand Up @@ -178,8 +177,7 @@ impl Elaborator<'_> {
if new_statements.is_empty() {
(assign, Type::Unit)
} else {
let assign = self.interner.push_stmt(assign);
self.interner.push_stmt_location(assign, expr_location);
let assign = self.interner.push_stmt_full(assign, expr_location);
new_statements.push(assign);
let block = HirExpression::Block(HirBlockExpression { statements: new_statements });
let block = self.interner.push_expr_full(block, expr_location, Type::Unit);
Expand Down Expand Up @@ -605,8 +603,7 @@ impl Elaborator<'_> {

let pattern = HirPattern::Identifier(ident);
let let_ = HirStatement::Let(HirLetStatement::basic(pattern, typ, expr));
let let_ = self.interner.push_stmt(let_);
self.interner.push_stmt_location(let_, location);
let let_ = self.interner.push_stmt_full(let_, location);
Some((let_, ident_id))
}

Expand Down
47 changes: 27 additions & 20 deletions compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,12 +1122,14 @@ impl Elaborator<'_> {
if let Type::Reference(element, _mut) = typ.follow_bindings() {
let location = self.interner.id_location(object);

let object = self.interner.push_expr(HirExpression::Prefix(HirPrefixExpression::new(
UnaryOp::Dereference { implicitly_added: true },
object,
)));
self.interner.push_expr_type(object, element.as_ref().clone());
self.interner.push_expr_location(object, location);
let object = self.interner.push_expr_full(
HirExpression::Prefix(HirPrefixExpression::new(
UnaryOp::Dereference { implicitly_added: true },
object,
)),
location,
element.as_ref().clone(),
);

// Recursively dereference to allow for converting &mut &mut T to T
self.insert_auto_dereferences(object, *element)
Expand Down Expand Up @@ -1686,16 +1688,19 @@ impl Elaborator<'_> {

let dereference_lhs = |this: &mut Self, lhs_type, element| {
let old_lhs = *access_lhs;
*access_lhs = this.interner.push_expr(HirExpression::Prefix(HirPrefixExpression::new(
UnaryOp::Dereference { implicitly_added: true },
old_lhs,
)));
this.interner.push_expr_type(old_lhs, lhs_type);
this.interner.push_expr_type(*access_lhs, element);

let old_location = this.interner.id_location(old_lhs);
let location = Location::new(location.span, old_location.file);
this.interner.push_expr_location(*access_lhs, location);

*access_lhs = this.interner.push_expr_full(
HirExpression::Prefix(HirPrefixExpression::new(
UnaryOp::Dereference { implicitly_added: true },
old_lhs,
)),
location,
element,
);

this.interner.push_expr_type(old_lhs, lhs_type);
};

// If this access is just a field offset, we want to avoid dereferencing
Expand Down Expand Up @@ -2164,12 +2169,14 @@ impl Elaborator<'_> {

// If that didn't work, then wrap the whole expression in an `&mut`
*object = new_object.unwrap_or_else(|| {
let new_object = self.interner.push_expr(HirExpression::Prefix(
HirPrefixExpression::new(UnaryOp::Reference { mutable }, *object),
));
self.interner.push_expr_type(new_object, new_type);
self.interner.push_expr_location(new_object, location);
new_object
self.interner.push_expr_full(
HirExpression::Prefix(HirPrefixExpression::new(
UnaryOp::Reference { mutable },
*object,
)),
location,
new_type,
)
});
}
// Otherwise if the object type is a mutable reference and the method is not, insert as
Expand Down
Loading
Loading