Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ predicate pathTypeAsTraitAssoc(
/**
* Holds if `assoc` is accessed on `tp` in `path`.
*
* That is, this is the case when `path` is of the form `<tp as
* Trait>::AssocType` or `tp::AssocType`; and `AssocType` resolves to `assoc`.
* That is, this is the case when `path` is of the form `<tp as Trait>::AssocType`
* or `tp::AssocType`; and `AssocType` resolves to `assoc`.
*/
predicate tpAssociatedType(TypeParam tp, AssocType assoc, Path path) {
resolvePath(path.getQualifier()) = tp and
Expand Down
43 changes: 26 additions & 17 deletions rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qll
Original file line number Diff line number Diff line change
Expand Up @@ -699,9 +699,13 @@ class PreTypeMention = PreTypeMention::TypeMention;
/**
* Holds if `path` accesses an associated type `alias` from `trait` on a
* concrete type given by `tm`.
*
* `implOrTmTrait` is either the mention that resolves to `trait` when `path`
* is of the form `<Type as Trait>::AssocType`, or the enclosing `impl` block
* when `path` is of the form `Self::AssocType`.
Comment on lines +703 to +705
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The doc comment describes implOrTmTrait as a “mention”, but the parameter is typed as AstNode and is used as either an Impl node or the trait PathTypeRepr from <Type as Trait>::.... Consider rewording to explicitly mention the concrete AST node kinds (e.g., Impl vs trait PathTypeRepr) to avoid confusion for readers.

Suggested change
* `implOrTmTrait` is either the mention that resolves to `trait` when `path`
* is of the form `<Type as Trait>::AssocType`, or the enclosing `impl` block
* when `path` is of the form `Self::AssocType`.
* `implOrTmTrait` is the AST node corresponding to the trait in the context of
* the access: it is either the trait `PathTypeRepr` from a path of the form
* `<Type as Trait>::AssocType`, or the enclosing `Impl` node when `path` is of
* the form `Self::AssocType`.

Copilot uses AI. Check for mistakes.
*/
private predicate pathConcreteTypeAssocType(
Path path, PreTypeMention tm, TraitItemNode trait, PreTypeMention tmTrait, TypeAlias alias
Path path, PreTypeMention tm, TraitItemNode trait, AstNode implOrTmTrait, TypeAlias alias
) {
exists(Path qualifier |
qualifier = path.getQualifier() and
Expand All @@ -710,19 +714,19 @@ private predicate pathConcreteTypeAssocType(
// path of the form `<Type as Trait>::AssocType`
// ^^^ tm ^^^^^^^^^ name
exists(string name |
pathTypeAsTraitAssoc(path, tm, tmTrait, trait, name) and
pathTypeAsTraitAssoc(path, tm, implOrTmTrait, trait, name) and
getTraitAssocType(trait, name) = alias
)
or
// path of the form `Self::AssocType` within an `impl` block
// tm ^^^^ ^^^^^^^^^ name
exists(ImplItemNode impl |
alias = resolvePath(path) and
qualifier = impl.getASelfPath() and
tm = impl.(Impl).getSelfTy() and
trait.getAnAssocItem() = alias and
tmTrait = impl.getTraitPath()
)
implOrTmTrait =
any(ImplItemNode impl |
alias = resolvePath(path) and
qualifier = impl.getASelfPath() and
tm = impl.(Impl).getSelfTy() and
trait.getAnAssocItem() = alias
)
)
}

Expand All @@ -741,21 +745,26 @@ private module PathSatisfiesConstraint =
*/
private Type getPathConcreteAssocTypeAt(Path path, TypePath typePath) {
exists(
PreTypeMention tm, ImplItemNode impl, TraitItemNode trait, TraitType t, PreTypeMention tmTrait,
PreTypeMention tm, ImplItemNode impl, TraitItemNode trait, TraitType t, AstNode implOrTmTrait,
TypeAlias alias, TypePath path0
|
pathConcreteTypeAssocType(path, tm, trait, tmTrait, alias) and
pathConcreteTypeAssocType(path, tm, trait, implOrTmTrait, alias) and
t = TTrait(trait) and
PathSatisfiesConstraint::satisfiesConstraintTypeThrough(tm, impl, t, path0, result) and
path0.isCons(TAssociatedTypeTypeParameter(trait, alias), typePath)
|
tmTrait.getTypeAt(TypePath::nil()) != t
implOrTmTrait instanceof Impl
or
not exists(TypePath path1, Type t1 |
t1 = impl.getTraitPath().(PreTypeMention).getTypeAt(path1) and
not t1 instanceof TypeParameter and
t1 != tmTrait.getTypeAt(path1)
)
// When `path` is of the form `<Type as Trait>::AssocType` we need to check
// that `impl` is not more specific than the mentioned trait
implOrTmTrait =
any(PreTypeMention tmTrait |
not exists(TypePath path1, Type t1 |
t1 = impl.getTraitPath().(PreTypeMention).getTypeAt(path1) and
not t1 instanceof TypeParameter and
t1 != tmTrait.getTypeAt(path1)
)
)
)
}

Expand Down