Skip to content

Conversation

@aakoshh
Copy link
Contributor

@aakoshh aakoshh commented Jan 29, 2026

Description

Problem

Resolves #11348

Summary

  • Changes lookup_trait_implementation_helper to perform an extra check before trying to unify associated types, to avoid allowing an associated type in one trait to unify with an unbound type variable that refers to another associated type in another trait.
  • Adds a Debug format for Location in the form of {file_id}/{start}:{end} to make debug formats less noisy
  • Changes the Display format of Type::NamedGeneric to use the name if its type variable is bound to an unbound type variable, which would ultimately be rendered as _, hiding information. This is to avoid error messages like expected Self::Baz but got _ instead of expected Self::Baz but got Self::Bar

(I'll look at the ambiguity aspect of inheritance separately in #11401, I just included a test to show what's wrong with it).

Additional Context

In the unit test we have this code:

    pub trait Foo {
        type Bar;
        fn foo(x: Self::Bar) -> Self::Bar;
    }

    pub trait Qux: Foo {
        type Baz;
        fn qux(x: Self::Baz) -> Self::Baz {
            <Self as Foo>::foo(x)
        }
    }

Rust rejects his, because <Self as Foo>::Bar is not the same type as <Self as Qux>::Baz, unless we add more trait constraints to say otherwise. In Noir, we accept this code, and only try to prove it works on concrete implementations.

The way it works is that:

  • Bar is a NamedGeneric Bar'1; when we introduce the constraint that Self is Foo, it is added generic as a TypeVariable, designated '6.
  • When we elaborate foo, it starts with the type forall '1 '2: Self::Bar'1 -> Self::Bar'1 (with Self'2 being the other named generic), and gets got elaborated into fn('6) -> '6.
  • When we elaborate the argument x, '6 gets bound to Self::Baz'5
  • Because of the parent Foo, a trait constraint to be resolved when the function context is popped.
  • When we try to resolve the constraint, we see that it tries to bind Self::Bar'1 to Self::Baz'5, which are different, but because it actually ends up trying to unify Self::Bar'1 against '5, which just binds '5. Instead of doing this, we now say that if '5 is still unbound, then we cannot call these equivalent.

User Documentation

Check one:

  • No user documentation needed.
  • Changes in docs/ included in this PR.
  • [For Experimental Features] Changes in docs/ to be submitted in a separate PR.

PR Checklist

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

@aakoshh aakoshh marked this pull request as ready for review January 29, 2026 11:40
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Execution Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 946ba40 Previous: c695737 Ratio
rollup-block-root-single-tx 0.003 s 0.002 s 1.50

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Test Suite Duration'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 02f0421 Previous: 413148b Ratio
test_report_zkpassport_noir-ecdsa_ 3 s 2 s 1.50
test_report_zkpassport_noir_rsa_ 2 s 1 s 2

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

@aakoshh aakoshh marked this pull request as draft January 29, 2026 14:34
@aakoshh aakoshh force-pushed the af/11348-assoc-type-mismatch-inherit branch from 1dad12f to d8394f3 Compare January 29, 2026 14:49
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Brillig Execution Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: d8394f3 Previous: 413148b Ratio
rollup-checkpoint-merge 0.002 s 0.001 s 2

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

@aakoshh aakoshh force-pushed the af/11348-assoc-type-mismatch-inherit branch from 02f0421 to c552525 Compare January 29, 2026 17:15
@aakoshh aakoshh marked this pull request as ready for review January 30, 2026 12:44
@aakoshh aakoshh changed the title fix(elaborator): Treat associated types as NamedGeneric in bind_named_generics fix(elaborator): Check that trait constraints aren't unifying unbound associated types from different traits Jan 30, 2026
@aakoshh aakoshh requested a review from a team January 30, 2026 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inheriting trait with identical associated type name not rejected

2 participants