Skip to content

Rust: Improve handling of where clauses in type inference and path resolution #20140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

paldepind
Copy link
Contributor

@paldepind paldepind commented Jul 30, 2025

It turns out that we don't handle type bounds added by where clauses in all cases in path resolution and type inference.

This PR improves the situration by adding member predicates to traits and type parameters that take all sources of bounds into account. These are then used in path resolution and type inference.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Jul 30, 2025
@paldepind paldepind force-pushed the rust/type-inference-where branch from 955ad03 to ff4cb51 Compare July 30, 2025 11:29
@paldepind paldepind marked this pull request as ready for review July 30, 2025 11:56
@Copilot Copilot AI review requested due to automatic review settings July 30, 2025 11:56
@paldepind paldepind requested a review from a team as a code owner July 30, 2025 11:56
Copy link
Contributor

@Copilot Copilot AI left a comment

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 how the Rust analyzer handles type bounds added by where clauses in both path resolution and type inference. Previously, the system didn't properly account for all sources of type bounds when resolving paths or inferring types.

  • Adds member predicates to traits and type parameters that consolidate bounds from both direct declarations and where clauses
  • Updates path resolution to use the new comprehensive bound-checking predicates
  • Updates type inference to leverage these improved bound checks

Reviewed Changes

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

Show a summary per file
File Description
rust/ql/test/library-tests/type-inference/main.rs Adds test cases for trait bounds in where clauses and associated types in supertraits
rust/ql/test/library-tests/path-resolution/main.rs Adds test case for trait bounds in where clauses
rust/ql/lib/codeql/rust/elements/internal/TypeParamImpl.qll Implements getTypeBound and getATypeBound predicates for type parameters
rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll Implements getTypeBound and getATypeBound predicates for traits
rust/ql/lib/codeql/rust/internal/TypeInference.qll Updates type inference to use new comprehensive bound predicates
rust/ql/lib/codeql/rust/internal/PathResolution.qll Updates path resolution to use new comprehensive bound predicates
Various .expected files Updated test expectations reflecting improved resolution

@paldepind paldepind added the no-change-note-required This PR does not need a change note label Jul 30, 2025
Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

Looks promising, I think I've spotted a couple of bugs (I could be wrong), and we need to review DCA when it's finished.

exists(WherePred wp |
wp = this.getWhereClause().getAPredicate() and
wp.getTypeRepr().(PathTypeRepr).getPath().getText() = "Self" and
result = wp.getTypeBoundList().getBound(index - this.nrOfDirectTypeBounds())
Copy link
Contributor

Choose a reason for hiding this comment

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

It appears to be legal to have two where predicates with Self as the path, e.g.:

    trait Subtrait
    where
        Self: Supertrait1,
        Self: Supertrait2,

I think at the moment this will break your index numbering.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, that is legal and the implementation currently does not account for that.

tbl = this.getTypeBoundList() and offset = 0
or
tbl = this.(TypeParamItemNode).getAWherePred().getTypeBoundList() and
offset = this.nrOfDirectTypeBounds()
Copy link
Contributor

Choose a reason for hiding this comment

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

Again I think the index numbering breaks if there's more than one applicable WherePred.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-change-note-required This PR does not need a change note Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants