Skip to content

Commit

Permalink
feat: Make generic impls callable (#3297)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfecher authored and guipublic committed Oct 30, 2023
1 parent b9e5b5f commit 7950bc9
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
17 changes: 9 additions & 8 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ pub struct UnresolvedTraitImpl {
pub trait_path: Path,
pub object_type: UnresolvedType,
pub methods: UnresolvedFunctions,
pub generics: UnresolvedGenerics,
}

#[derive(Clone)]
Expand Down Expand Up @@ -529,6 +530,7 @@ fn collect_trait_impl(
let path_resolver = StandardPathResolver::new(module);
let file = def_maps[&crate_id].file_id(trait_impl.module_id);
let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file);
resolver.add_generics(&trait_impl.generics);
let typ = resolver.resolve_type(unresolved_type);
errors.extend(take_errors(trait_impl.file_id, resolver));

Expand Down Expand Up @@ -964,24 +966,23 @@ fn resolve_trait_impls(

let self_type_span = unresolved_type.span;

let self_type = {
let mut resolver =
Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id);
resolver.resolve_type(unresolved_type.clone())
};

let maybe_trait_id = trait_impl.trait_id;
let mut resolver =
Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id);
resolver.add_generics(&trait_impl.generics);
let self_type = resolver.resolve_type(unresolved_type.clone());
let generics = resolver.get_generics().to_vec();

let mut impl_methods = resolve_function_set(
interner,
crate_id,
&context.def_maps,
trait_impl.methods.clone(),
Some(self_type.clone()),
vec![], // TODO
generics,
errors,
);

let maybe_trait_id = trait_impl.trait_id;
if let Some(trait_id) = maybe_trait_id {
for (_, func) in &impl_methods {
interner.set_function_trait(*func, self_type.clone(), trait_id);
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ impl<'a> ModCollector<'a> {
trait_path: trait_name,
methods: unresolved_functions,
object_type: trait_impl.object_type,
generics: trait_impl.impl_generics,
trait_id: None, // will be filled later
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,22 @@ fn main() {
// Types matching multiple impls will currently choose
// the first matching one instead of erroring
assert(z.foo() == 32);

// Ensure we can call a generic impl
let x: u8 = 7;
let y: i8 = 8;
let s2_u8 = S2 { x };
let s2_i8 = S2 { x: y };
assert(s2_u8.t2().x == 7);
assert(s2_i8.t2().x == 8);
}

trait T2 {
fn t2(self) -> Self;
}

struct S2<T> { x: T }

impl<T> T2 for S2<T> {
fn t2(self) -> Self { self }
}

0 comments on commit 7950bc9

Please sign in to comment.