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

fix: double alias in path #6855

Merged
merged 2 commits into from
Dec 18, 2024
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
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();
}
Loading