Rust: Avoid duplicated entries in conditionSatisfiesConstraint for dyn trait types

This commit is contained in:
Simon Friis Vindum
2026-01-16 10:36:24 +01:00
parent c0b3569473
commit a11693268b
2 changed files with 30 additions and 1 deletions

View File

@@ -23,7 +23,28 @@ final class ImplTypeAbstraction extends TypeAbstraction, Impl {
}
}
private predicate idDynTraitTypeRepr(Raw::DynTraitTypeRepr x, Raw::DynTraitTypeRepr y) { x = y }
private predicate idOfDynTraitTypeRepr(Raw::DynTraitTypeRepr x, int y) =
equivalenceRelation(idDynTraitTypeRepr/2)(x, y)
private int idOfDynTraitTypeRepr(DynTraitTypeRepr node) {
idOfDynTraitTypeRepr(Synth::convertAstNodeToRaw(node), result)
}
/** Holds if `dt` is the (arbitrarily chosen) canonical dyn trait type abstraction for `trait`. */
private predicate canonicalDynTraitTypeAbstraction(DynTraitTypeRepr dt, Trait trait) {
dt = min(DynTraitTypeRepr d | d.getTrait() = trait | d order by idOfDynTraitTypeRepr(d))
}
final class DynTypeAbstraction extends TypeAbstraction, DynTraitTypeRepr {
DynTypeAbstraction() {
// We pick a "canonical" `dyn Trait` in order to avoid including multiple
// entries in `conditionSatisfiesConstraint` with the exact same effect when
// `dyn Trait` occurs multiple times for the same trait.
canonicalDynTraitTypeAbstraction(this, this.getTrait())
}
override TypeParameter getATypeParameter() {
result = any(DynTraitTypeParameter tp | tp.getTrait() = this.getTrait()).getTraitTypeParameter()
}

View File

@@ -4,6 +4,7 @@ private import rust
private import codeql.rust.internal.PathResolution
private import codeql.rust.frameworks.stdlib.Stdlib
private import Type
private import TypeAbstraction
private import TypeInference
/** An AST node that may mention a type. */
@@ -563,7 +564,14 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
private Trait trait;
DynTypeBoundListMention() {
exists(DynTraitTypeRepr dyn | this = dyn.getTypeBoundList() and trait = dyn.getTrait())
exists(DynTraitTypeRepr dyn |
// We only need this type mention when the `dyn Trait` is a type
// abstraction, that is, when it's "canonical" and used in
// `conditionSatisfiesConstraint`.
dyn instanceof DynTypeAbstraction and
this = dyn.getTypeBoundList() and
trait = dyn.getTrait()
)
}
override Type resolveTypeAt(TypePath path) {