Skip to content

Rust: Disambiguate types inferred from trait bounds - #21464

Merged
hvitved merged 5 commits into
github:mainfrom
hvitved:rust/type-inference-trait-bound-impl-overlap
Mar 20, 2026
Merged

Rust: Disambiguate types inferred from trait bounds#21464
hvitved merged 5 commits into
github:mainfrom
hvitved:rust/type-inference-trait-bound-impl-overlap

Conversation

@hvitved

@hvitvedhvitved commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Preliminary work needed for #21206.

In certain cases where a type implements the same trait but with different type arguments, we may infer overlapping types from trait bounds (see examples in first commit).

In order to disambiguate, this PR takes the same approach as #21420, but lifting the idea from that PR (implemented inside the getPathConcreteAssocTypeAt prediate in TypeMention.qll) into the shared type inference library, so it applies to both resolution of <Foo as Bar<...>> paths as well as constraints on type parameters inside functions. In order to do this, the existing SatisfiesConstraint module is generalized from constraints being Types to being HasTypeTreeSigs, for example in

foo<T1, T2 : Trait<T1, i32>(...) -> T2::Output { ... }

we will now restrict applicable traits to only those that are compatible with a second type argument being i32.

The old SatisfiesConstraint module is replaced with a new SatisfiesType module, which is a simple wrapper around SatisfiesConstraint.

Moreover, since we may actually know the instantiation of T1 at a given call to foo above, we can restrict further based on that type, which means a further generalization of SatisfiesConstraint to a new SatisfiesConstraintWithTypeMatching module. SatisfiesConstraint is then itself also a simple wrapper (around SatisfiesConstraintWithTypeMatching).

@github-actionsgithub-actionsBot added the Rust Pull requests that update Rust code label Mar 12, 2026
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch 2 times, most recently from 4d48515 to 902e953CompareMarch 17, 2026 10:18
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch from 902e953 to 1dbd888CompareMarch 17, 2026 10:44
Comment threadshared/typeinference/codeql/typeinference/internal/TypeInference.qll Dismissed
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch from 1dbd888 to 7a5a89aCompareMarch 17, 2026 14:01
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch 4 times, most recently from 9300d8d to e14936fCompareMarch 18, 2026 09:26
@hvitvedhvitved changed the title Rust: Only infer types from trait bounds when their implementation is unambigousRust: Disambiguate types inferred from trait boundsMar 18, 2026
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch from 98a7ca6 to be2a49bCompareMarch 18, 2026 16:55
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch from be2a49b to 03a444dCompareMarch 18, 2026 18:53
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch 3 times, most recently from b33051e to c5af080CompareMarch 19, 2026 08:53
@hvitvedhvitved added the no-change-note-required This PR does not need a change note label Mar 19, 2026
@hvitved
hvitved marked this pull request as ready for review March 19, 2026 09:24
@hvitved
hvitved requested review from a team as code ownersMarch 19, 2026 09:24
CopilotAI review requested due to automatic review settings March 19, 2026 09:24

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR improves Rust type inference in cases where multiple trait impls overlap on the same receiver type but differ in trait type arguments, by lifting disambiguation logic into the shared type inference library so it applies both to <Foo as Bar<...>>::Assoc path resolution and to trait-bound constraints on function type parameters.

Changes:

  • Generalize constraint satisfaction in the shared type inference library to support non-Type constraints and optional type-parameter matching for disambiguation.
  • Extend Rust’s internal type inference to use the generalized shared machinery (including sibling-impl ambiguity checks) and refine associated-type string rendering for inherited associated types.
  • Add/adjust Rust library tests to cover overlapping impls from trait bounds and update expected results.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
shared/util/codeql/util/UnboundList.qllAdds a more efficient prefix check helper used by new disambiguation logic.
shared/typeinference/codeql/typeinference/internal/TypeInference.qllGeneralizes SatisfiesConstraint and introduces type-matching-enabled disambiguation support.
rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qllAdapts <Type as Trait>::Assoc resolution to use the shared disambiguation approach.
rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qllRefactors Rust instantiation of shared type inference modules and updates call sites to new APIs.
rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qllRefactors sibling-impl detection to be parameterized over type-mention resolution kind.
rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qllSwitches blanket-constraint satisfaction to the new SatisfiesType wrapper.
rust/ql/lib/codeql/rust/internal/typeinference/Type.qllAdjusts associated-type parameter representation and stringification (incl. inherited-from info).
rust/ql/test/library-tests/type-inference/overloading.rsAdds a regression test module covering overlapping impls via trait bounds.
rust/ql/test/library-tests/type-inference/type-inference.expectedUpdates expected inference output to reflect the improved disambiguation.
Comments suppressed due to low confidence (1)

rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll:66

  • Typo in comment: "superflous" should be "superfluous".
 // In principle the second conjunct below should be superflous, but we still
// have ill-formed type mentions for types that we don't understand. For

Comment threadrust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll Outdated
Comment threadshared/typeinference/codeql/typeinference/internal/TypeInference.qll Outdated
@hvitved
hvitved requested a review from paldepindMarch 19, 2026 09:43
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch from b08dbe0 to c607500CompareMarch 19, 2026 11:56
@hvitved
hvitvedforce-pushed the rust/type-inference-trait-bound-impl-overlap branch from c607500 to 7fc1d53CompareMarch 19, 2026 11:57

@paldepindpaldepind left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@hvitved
hvitved merged commit f99f26f into github:mainMar 20, 2026
146 of 150 checks passed
@hvitved
hvitved deleted the rust/type-inference-trait-bound-impl-overlap branch March 20, 2026 14:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-requiredThis PR does not need a change noteRustPull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@hvitved@paldepind@github-advanced-security