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
14 changes: 13 additions & 1 deletion compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ impl<'a> Resolver<'a> {
fn resolve_type_inner(&mut self, typ: UnresolvedType, new_variables: &mut Generics) -> Type {
use UnresolvedTypeData::*;

match typ.typ {
let resolved_type = match typ.typ {
FieldElement => Type::FieldElement,
Array(size, elem) => {
let elem = Box::new(self.resolve_type_inner(*elem, new_variables));
Expand Down Expand Up @@ -510,7 +510,18 @@ impl<'a> Resolver<'a> {
Type::MutableReference(Box::new(self.resolve_type_inner(*element, new_variables)))
}
Parenthesized(typ) => self.resolve_type_inner(*typ, new_variables),
};

if let Type::Struct(_, _) = resolved_type {
if let Some(unresolved_span) = typ.span {
// Record the location of the type reference
self.interner.push_type_ref_location(
resolved_type.clone(),
Location::new(unresolved_span, self.file),
);
}
}
resolved_type
}

fn find_generic(&self, target_name: &str) -> Option<&(Rc<String>, TypeVariable, Span)> {
Expand Down Expand Up @@ -714,6 +725,7 @@ impl<'a> Resolver<'a> {
if resolved_type.is_nested_slice() {
self.errors.push(ResolverError::NestedSlices { span: span.unwrap() });
}

resolved_type
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub enum Type {
TypeVariable(TypeVariable, TypeVariableKind),

/// `impl Trait` when used in a type position.
/// These are only matched based on the TraitId. The trait name paramer is only
/// These are only matched based on the TraitId. The trait name parameter is only
/// used for displaying error messages using the name of the trait.
TraitAsType(TraitId, /*name:*/ Rc<String>, /*generics:*/ Vec<Type>),

Expand Down
10 changes: 9 additions & 1 deletion compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ pub struct NodeInterner {
/// A list of all type aliases that are referenced in the program.
/// Searched by LSP to resolve [Location]s of [TypeAliasType]s
pub(crate) type_alias_ref: Vec<(TypeAliasId, Location)>,

/// Stores the [Location] of a [Type] reference
pub(crate) type_ref_locations: Vec<(Type, Location)>,
}

/// A trait implementation is either a normal implementation that is present in the source
Expand Down Expand Up @@ -455,6 +458,7 @@ impl Default for NodeInterner {
struct_methods: HashMap::new(),
primitive_methods: HashMap::new(),
type_alias_ref: Vec::new(),
type_ref_locations: Vec::new(),
};

// An empty block expression is used often, we add this into the `node` on startup
Expand Down Expand Up @@ -607,6 +611,11 @@ impl NodeInterner {
self.id_to_type.insert(definition_id.into(), typ);
}

/// Store [Location] of [Type] reference
pub fn push_type_ref_location(&mut self, typ: Type, location: Location) {
self.type_ref_locations.push((typ, location));
}

pub fn push_global(&mut self, stmt_id: StmtId, ident: Ident, local_id: LocalModuleId) {
self.globals.insert(stmt_id, GlobalInfo { ident, local_id });
}
Expand Down Expand Up @@ -1186,7 +1195,6 @@ impl NodeInterner {
}

/// Adds a trait implementation to the list of known implementations.
#[tracing::instrument(skip(self))]
pub fn add_trait_implementation(
&mut self,
object_type: Type,
Expand Down
13 changes: 12 additions & 1 deletion compiler/noirc_frontend/src/resolve_locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl NodeInterner {
.and_then(|index| self.resolve_location(index, return_type_location_instead))
.or_else(|| self.try_resolve_trait_impl_location(location))
.or_else(|| self.try_resolve_trait_method_declaration(location))
.or_else(|| self.try_resolve_type_ref(location))
.or_else(|| self.try_resolve_type_alias(location))
}

Expand Down Expand Up @@ -196,7 +197,17 @@ impl NodeInterner {
})
}

#[tracing::instrument(skip(self), ret)]
/// Attempts to resolve [Location] of [Type] based on [Location] of reference in code
pub(crate) fn try_resolve_type_ref(&self, location: Location) -> Option<Location> {
self.type_ref_locations
.iter()
.find(|(_typ, type_ref_location)| type_ref_location.contains(&location))
.and_then(|(typ, _)| match typ {
Type::Struct(struct_typ, _) => Some(struct_typ.borrow().location),
_ => None,
})
}

fn try_resolve_type_alias(&self, location: Location) -> Option<Location> {
self.type_alias_ref
.iter()
Expand Down