Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lsp): goto type alias #4061

Merged
merged 5 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
// 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
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
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

Check warning on line 67 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (paramer)
/// used for displaying error messages using the name of the trait.
TraitAsType(TraitId, /*name:*/ Rc<String>),

Expand Down Expand Up @@ -280,7 +280,7 @@
pub id: TypeAliasId,
pub typ: Type,
pub generics: Generics,
pub span: Span,
pub span: Location,
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
}

impl std::hash::Hash for TypeAliasType {
Expand Down Expand Up @@ -312,7 +312,7 @@
pub fn new(
id: TypeAliasId,
name: Ident,
span: Span,
span: Location,
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
typ: Type,
generics: Generics,
) -> TypeAliasType {
Expand Down Expand Up @@ -1411,7 +1411,7 @@
Type::String(Box::new(size))
}
Type::FmtString(size, fields) => {
let size = size.substitute_helper(type_bindings, substitute_bound_typevars);

Check warning on line 1414 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevarsn)
let fields = fields.substitute_helper(type_bindings, substitute_bound_typevars);
Type::FmtString(Box::new(size), Box::new(fields))
}
Expand All @@ -1426,7 +1426,7 @@
});
Type::Struct(fields.clone(), args)
}
Type::Tuple(fields) => {

Check warning on line 1429 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevarsfined)
let fields = vecmap(fields, |field| {
field.substitute_helper(type_bindings, substitute_bound_typevars)
});
Expand Down
10 changes: 8 additions & 2 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TypeAliasType>,
pub(crate) type_aliases: Vec<TypeAliasType>,

// Trait map.
//
Expand Down Expand Up @@ -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<FuncId, (Type, TraitId)>,

pub(crate) type_alias_ref: Vec<(TypeAliasId, Location)>,
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
}

/// A trait implementation is either a normal implementation that is present in the source
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -545,6 +548,9 @@ impl NodeInterner {
type_id
}

pub fn add_type_alias_ref(&mut self, type_id: TypeAliasId, location: Location) {
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
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);
Expand Down
18 changes: 18 additions & 0 deletions compiler/noirc_frontend/src/resolve_locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
.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<Location> {
Expand Down Expand Up @@ -143,7 +144,7 @@
///
/// ### Example:
/// ```nr
/// trait Fieldable {

Check warning on line 147 in compiler/noirc_frontend/src/resolve_locations.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (Fieldable)
/// fn to_field(self) -> Field;
/// ^------------------------------\
/// } |
Expand All @@ -167,4 +168,21 @@
method.map(|method| method.location)
})
}

#[tracing::instrument(skip(self), ret)]
fn try_resolve_type_alias(&self, location: Location) -> Option<Location> {
self.type_alias_ref
.iter()
.find(|(type_alias_id, named_type_location)| {
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
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)
})
}
}
Loading