Skip to content

Commit

Permalink
Structs in entry points should be considered as constructed
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Sep 17, 2024
1 parent 9d944b7 commit 91f5c75
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
9 changes: 5 additions & 4 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ impl<'context> Elaborator<'context> {
}
};

self.mark_struct_as_constructed(r#type.clone(), &last_segment.ident);
self.mark_struct_as_constructed(r#type.clone());

let turbofish_span = last_segment.turbofish_span();

Expand Down Expand Up @@ -564,13 +564,14 @@ impl<'context> Elaborator<'context> {
(expr, Type::Struct(struct_type, generics))
}

fn mark_struct_as_constructed(&mut self, struct_type: Shared<StructType>, name: &Ident) {
let struct_module_id = struct_type.borrow().id.module_id();
pub(super) fn mark_struct_as_constructed(&mut self, struct_type: Shared<StructType>) {
let struct_type = struct_type.borrow();
let struct_module_id = struct_type.id.module_id();
let module_data = self.get_module(struct_module_id);
let parent_local_id = module_data.parent.expect("Expected struct module parent to exist");
let parent_module_id =
ModuleId { krate: struct_module_id.krate, local_id: parent_local_id };
self.interner.usage_tracker.mark_as_used(parent_module_id, name);
self.interner.usage_tracker.mark_as_used(parent_module_id, &struct_type.name);
}

/// Resolve all the fields of a struct constructor expression.
Expand Down
55 changes: 55 additions & 0 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,10 @@ impl<'context> Elaborator<'context> {
type_span,
);

if is_entry_point {
self.mark_parameter_type_as_used(&typ);
}

let pattern = self.elaborate_pattern_and_store_ids(
pattern,
typ.clone(),
Expand Down Expand Up @@ -833,6 +837,57 @@ impl<'context> Elaborator<'context> {
self.current_item = None;
}

fn mark_parameter_type_as_used(&mut self, typ: &Type) {
match typ {
Type::Array(_n, typ) => self.mark_parameter_type_as_used(typ),
Type::Slice(typ) => self.mark_parameter_type_as_used(typ),
Type::Tuple(types) => {
for typ in types {
self.mark_parameter_type_as_used(typ);
}
}
Type::Struct(struct_type, generics) => {
self.mark_struct_as_constructed(struct_type.clone());
for generic in generics {
self.mark_parameter_type_as_used(generic);
}
}
Type::Alias(alias_type, generics) => {
self.mark_parameter_type_as_used(&alias_type.borrow().get_type(generics));
}
Type::MutableReference(typ) => {
self.mark_parameter_type_as_used(typ);
}
Type::InfixExpr(left, _op, right) => {
self.mark_parameter_type_as_used(left);
self.mark_parameter_type_as_used(right);
}
Type::FieldElement
| Type::Integer(..)
| Type::Bool
| Type::String(_)
| Type::FmtString(_, _)
| Type::Unit
| Type::Quoted(..)
| Type::Constant(_)
| Type::TraitAsType(..)
| Type::TypeVariable(..)
| Type::NamedGeneric(..)
| Type::Function(..)
| Type::Forall(..)
| Type::Error => (),
}

if let Type::Alias(alias_type, generics) = typ {
self.mark_parameter_type_as_used(&alias_type.borrow().get_type(generics));
return;
}

if let Type::Struct(struct_type, _generics) = typ {
self.mark_struct_as_constructed(struct_type.clone());
}
}

fn run_function_lints(&mut self, func: &FuncMeta, modifiers: &FunctionModifiers) {
self.run_lint(|_| lints::inlining_attributes(func, modifiers).map(Into::into));
self.run_lint(|_| lints::missing_pub(func, modifiers).map(Into::into));
Expand Down

0 comments on commit 91f5c75

Please sign in to comment.