Skip to content
Merged
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
11 changes: 8 additions & 3 deletions compiler/noirc_frontend/src/elaborator/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1035,16 +1035,21 @@ impl Elaborator<'_> {
// fn new() -> Self;
// }
//
// fn foo<O: One, T: Two<O>>() {
// fn foo<X: One, T: Two<X>>() {
// let _: T = Two::new();
// }
// ```
//
// 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<X>` 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);
Expand Down
Loading