diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index a13c7771909..be542ecf759 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -1035,7 +1035,7 @@ impl Elaborator<'_> { // fn new() -> Self; // } // - // fn foo>() { + // fn foo>() { // let _: T = Two::new(); // } // ``` @@ -1043,8 +1043,13 @@ impl Elaborator<'_> { // when type-checking `Two::new` we'll have a return type `'2` which is constrained by `'2: Two<'1>`. // Then the definition for `new` has a constraint on it, `O: One`, which translates to `'1: One`. // - // If we try to find a trait implementation for `'1` before finding one for `'2` we'll never find it: - // once we find one for `'2`, `'1` will become bound and a trait implementation will be found. + // Because of the explicit type in the `let`, `'2` will be unified with `T`. + // Then we must first verify the constraint `'2: Two<'1>`, which is now `T: Two<'1>`, to find + // that the implementation is the assumed one `T: Two` so that `'1` is bound to `X`. + // Then we can successfully verify the constraint `'1: One` which now became `X: One` which holds + // because of the assumed constraint. + // + // If we try to find a trait implementation for `'1` before finding one for `'2` we'll never find it. if let Some(definition) = self.interner.try_definition(ident.id) { if let DefinitionKind::Function(function) = definition.kind { let function = self.interner.function_meta(&function);