From 870977b1aec5949b35f38fd45251e2260c9d890c Mon Sep 17 00:00:00 2001 From: Koby Date: Tue, 16 Jan 2024 18:33:51 +0100 Subject: [PATCH 1/3] feat(lsp): goto type alias --- .../src/hir/resolution/resolver.rs | 1 + compiler/noirc_frontend/src/hir_def/types.rs | 4 ++-- compiler/noirc_frontend/src/node_interner.rs | 10 ++++++++-- .../noirc_frontend/src/resolve_locations.rs | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index b9770f34e1e..50ea665a42f 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -537,6 +537,7 @@ impl<'a> Resolver<'a> { let result = self.interner.get_type_alias(id).get_type(&args); + self.interner.add_type_alias_ref(id, Location::new(span, self.file)); // Because there is no ordering to when type aliases (and other globals) are resolved, // it is possible for one to refer to an Error type and issue no error if it is set // equal to another type alias. Fixing this fully requires an analysis to create a DFG diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index 981d7e41b6e..d057aa7495b 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -280,7 +280,7 @@ pub struct TypeAliasType { pub id: TypeAliasId, pub typ: Type, pub generics: Generics, - pub span: Span, + pub span: Location, } impl std::hash::Hash for TypeAliasType { @@ -312,7 +312,7 @@ impl TypeAliasType { pub fn new( id: TypeAliasId, name: Ident, - span: Span, + span: Location, typ: Type, generics: Generics, ) -> TypeAliasType { diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index f9d273d774f..7776b98cd71 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -78,7 +78,7 @@ pub struct NodeInterner { // // Map type aliases to the actual type. // When resolving types, check against this map to see if a type alias is defined. - type_aliases: Vec, + pub(crate) type_aliases: Vec, // Trait map. // @@ -142,6 +142,8 @@ pub struct NodeInterner { // For trait implementation functions, this is their self type and trait they belong to func_id_to_trait: HashMap, + + pub(crate) type_alias_ref: Vec<(TypeAliasId, Location)>, } /// A trait implementation is either a normal implementation that is present in the source @@ -437,6 +439,7 @@ impl Default for NodeInterner { globals: HashMap::new(), struct_methods: HashMap::new(), primitive_methods: HashMap::new(), + type_alias_ref: Vec::new(), }; // An empty block expression is used often, we add this into the `node` on startup @@ -534,7 +537,7 @@ impl NodeInterner { self.type_aliases.push(TypeAliasType::new( type_id, typ.type_alias_def.name.clone(), - typ.type_alias_def.span, + Location::new(typ.type_alias_def.span, typ.file_id), Type::Error, vecmap(&typ.type_alias_def.generics, |_| { let id = TypeVariableId(0); @@ -545,6 +548,9 @@ impl NodeInterner { type_id } + pub fn add_type_alias_ref(&mut self, type_id: TypeAliasId, location: Location) { + self.type_alias_ref.push((type_id, location)); + } pub fn update_struct(&mut self, type_id: StructId, f: impl FnOnce(&mut StructType)) { let mut value = self.structs.get_mut(&type_id).unwrap().borrow_mut(); f(&mut value); diff --git a/compiler/noirc_frontend/src/resolve_locations.rs b/compiler/noirc_frontend/src/resolve_locations.rs index 95ced906984..8358b9677a2 100644 --- a/compiler/noirc_frontend/src/resolve_locations.rs +++ b/compiler/noirc_frontend/src/resolve_locations.rs @@ -38,6 +38,7 @@ impl NodeInterner { .and_then(|index| self.resolve_location(index)) .or_else(|| self.try_resolve_trait_impl_location(location)) .or_else(|| self.try_resolve_trait_method_declaration(location)) + .or_else(|| self.try_resolve_type_alias(location)) } pub fn get_declaration_location_from(&self, location: Location) -> Option { @@ -167,4 +168,21 @@ impl NodeInterner { method.map(|method| method.location) }) } + + #[tracing::instrument(skip(self), ret)] + fn try_resolve_type_alias(&self, location: Location) -> Option { + self.type_alias_ref + .iter() + .find(|(type_alias_id, named_type_location)| { + tracing::debug!( + "Trying type alias {:?}, type_id {:?}", + named_type_location, + type_alias_id + ); + named_type_location.span.contains(&location.span) + }) + .and_then(|(type_alias_id, _found_location)| { + Some(self.get_type_alias(*type_alias_id).span) + }) + } } From f34146955f6ad59b6f2b3285d819743bcb0cf48e Mon Sep 17 00:00:00 2001 From: Koby Date: Thu, 18 Jan 2024 12:37:50 +0100 Subject: [PATCH 2/3] chore: review nits --- compiler/noirc_frontend/src/hir/resolution/resolver.rs | 3 +++ compiler/noirc_frontend/src/hir_def/types.rs | 6 +++--- compiler/noirc_frontend/src/node_interner.rs | 4 ++++ compiler/noirc_frontend/src/resolve_locations.rs | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 50ea665a42f..a4a42a5e995 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -537,7 +537,10 @@ impl<'a> Resolver<'a> { let result = self.interner.get_type_alias(id).get_type(&args); + // Collecting Type Alias references [Location]s to be used by LSP in order + // to resolve the definition of the type alias self.interner.add_type_alias_ref(id, Location::new(span, self.file)); + // Because there is no ordering to when type aliases (and other globals) are resolved, // it is possible for one to refer to an Error type and issue no error if it is set // equal to another type alias. Fixing this fully requires an analysis to create a DFG diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index d057aa7495b..0aa69739009 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -280,7 +280,7 @@ pub struct TypeAliasType { pub id: TypeAliasId, pub typ: Type, pub generics: Generics, - pub span: Location, + pub location: Location, } impl std::hash::Hash for TypeAliasType { @@ -312,11 +312,11 @@ impl TypeAliasType { pub fn new( id: TypeAliasId, name: Ident, - span: Location, + location: Location, typ: Type, generics: Generics, ) -> TypeAliasType { - TypeAliasType { id, typ, name, span, generics } + TypeAliasType { id, typ, name, location, generics } } pub fn set_type_and_generics(&mut self, new_typ: Type, new_generics: Generics) { diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 7776b98cd71..ac2a59fb018 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -143,6 +143,8 @@ pub struct NodeInterner { // For trait implementation functions, this is their self type and trait they belong to func_id_to_trait: HashMap, + /// 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)>, } @@ -548,6 +550,8 @@ impl NodeInterner { type_id } + /// Adds [TypeLiasId] and [Location] to the type_alias_ref vector + /// So that we can later resolve [Location]s type aliases from the LSP requests pub fn add_type_alias_ref(&mut self, type_id: TypeAliasId, location: Location) { self.type_alias_ref.push((type_id, location)); } diff --git a/compiler/noirc_frontend/src/resolve_locations.rs b/compiler/noirc_frontend/src/resolve_locations.rs index 8358b9677a2..94758a54ee2 100644 --- a/compiler/noirc_frontend/src/resolve_locations.rs +++ b/compiler/noirc_frontend/src/resolve_locations.rs @@ -182,7 +182,7 @@ impl NodeInterner { named_type_location.span.contains(&location.span) }) .and_then(|(type_alias_id, _found_location)| { - Some(self.get_type_alias(*type_alias_id).span) + Some(self.get_type_alias(*type_alias_id).location) }) } } From 68bf2f7fc19117701bc0e2a5466c6a3378061b1a Mon Sep 17 00:00:00 2001 From: Koby Date: Thu, 18 Jan 2024 19:13:42 +0100 Subject: [PATCH 3/3] chore: clippy --- compiler/noirc_frontend/src/resolve_locations.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/compiler/noirc_frontend/src/resolve_locations.rs b/compiler/noirc_frontend/src/resolve_locations.rs index 320804acc1f..02325de4da8 100644 --- a/compiler/noirc_frontend/src/resolve_locations.rs +++ b/compiler/noirc_frontend/src/resolve_locations.rs @@ -200,16 +200,7 @@ impl NodeInterner { fn try_resolve_type_alias(&self, location: Location) -> Option { self.type_alias_ref .iter() - .find(|(type_alias_id, named_type_location)| { - tracing::debug!( - "Trying type alias {:?}, type_id {:?}", - named_type_location, - type_alias_id - ); - named_type_location.span.contains(&location.span) - }) - .and_then(|(type_alias_id, _found_location)| { - Some(self.get_type_alias(*type_alias_id).location) - }) + .find(|(_, named_type_location)| named_type_location.span.contains(&location.span)) + .map(|(type_alias_id, _found_location)| self.get_type_alias(*type_alias_id).location) } }