Skip to content

Commit

Permalink
fix: double alias in path (#6855)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Dec 18, 2024
1 parent 73ccd45 commit 82f595b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 21 deletions.
31 changes: 18 additions & 13 deletions compiler/noirc_frontend/src/elaborator/path_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::hir::resolution::visibility::item_in_module_is_visible;

use crate::locations::ReferencesTracker;
use crate::node_interner::{FuncId, GlobalId, StructId, TraitId, TypeAliasId};
use crate::Type;
use crate::{Shared, Type, TypeAlias};

use super::types::SELF_TYPE_NAME;
use super::Elaborator;
Expand Down Expand Up @@ -218,18 +218,8 @@ impl<'context> Elaborator<'context> {
),
ModuleDefId::TypeAliasId(id) => {
let type_alias = self.interner.get_type_alias(id);
let type_alias = type_alias.borrow();

let module_id = match &type_alias.typ {
Type::Struct(struct_id, _generics) => struct_id.borrow().id.module_id(),
Type::Error => {
return Err(PathResolutionError::Unresolved(last_ident.clone()));
}
_ => {
// For now we only allow type aliases that point to structs.
// The more general case is captured here: https://github.com/noir-lang/noir/issues/6398
panic!("Type alias in path not pointing to struct not yet supported")
}
let Some(module_id) = get_type_alias_module_def_id(&type_alias) else {
return Err(PathResolutionError::Unresolved(last_ident.clone()));
};

(
Expand Down Expand Up @@ -345,3 +335,18 @@ fn merge_intermediate_path_resolution_item_with_module_def_id(
},
}
}

fn get_type_alias_module_def_id(type_alias: &Shared<TypeAlias>) -> Option<ModuleId> {
let type_alias = type_alias.borrow();

match &type_alias.typ {
Type::Struct(struct_id, _generics) => Some(struct_id.borrow().id.module_id()),
Type::Alias(type_alias, _generics) => get_type_alias_module_def_id(type_alias),
Type::Error => None,
_ => {
// For now we only allow type aliases that point to structs.
// The more general case is captured here: https://github.com/noir-lang/noir/issues/6398
panic!("Type alias in path not pointing to struct not yet supported")
}
}
}
21 changes: 13 additions & 8 deletions compiler/noirc_frontend/src/elaborator/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,17 +604,11 @@ impl<'context> Elaborator<'context> {
alias_generics
};

// Now instantiate the underlying struct with those generics, the struct might
// Now instantiate the underlying struct or alias with those generics, the struct might
// have more generics than those in the alias, like in this example:
//
// type Alias<T> = Struct<T, i32>;
let typ = type_alias.get_type(&generics);
let Type::Struct(_, generics) = typ else {
// See https://github.com/noir-lang/noir/issues/6398
panic!("Expected type alias to point to struct")
};

generics
get_type_alias_generics(&type_alias, &generics)
}
PathResolutionItem::TraitFunction(trait_id, Some(generics), _func_id) => {
let trait_ = self.interner.get_trait(trait_id);
Expand Down Expand Up @@ -880,3 +874,14 @@ impl<'context> Elaborator<'context> {
(id, typ)
}
}

fn get_type_alias_generics(type_alias: &TypeAlias, generics: &[Type]) -> Vec<Type> {
let typ = type_alias.get_type(generics);
match typ {
Type::Struct(_, generics) => generics,
Type::Alias(type_alias, generics) => {
get_type_alias_generics(&type_alias.borrow(), &generics)
}
_ => panic!("Expected type alias to point to struct or alias"),
}
}
28 changes: 28 additions & 0 deletions compiler/noirc_frontend/src/tests/aliases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,31 @@ fn alias_in_let_pattern() {
"#;
assert_no_errors(src);
}

#[test]
fn double_alias_in_path() {
let src = r#"
struct Foo {}
impl Foo {
fn new() -> Self {
Self {}
}
}
type FooAlias1 = Foo;
type FooAlias2 = FooAlias1;
fn main() {
let _ = FooAlias2::new();
}
"#;
assert_no_errors(src);
}

#[test]
fn double_generic_alias_in_path() {
let src = r#"
"#;
assert_no_errors(src);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "double_generic_alias_in_path"
type = "bin"
authors = [""]
compiler_version = ">=0.32.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
struct Foo<T> {}

impl<T> Foo<T> {
fn new() -> Self {
Self {}
}
}

type FooAlias1 = Foo<i32>;
type FooAlias2 = FooAlias1;

fn main() {
let _ = FooAlias2::new();
}

0 comments on commit 82f595b

Please sign in to comment.