Rust: Minor tweaks and improvements

This commit is contained in:
Simon Friis Vindum
2026-02-02 12:07:18 +01:00
parent 2cb0e81da0
commit 18576838d4
2 changed files with 30 additions and 23 deletions

View File

@@ -110,7 +110,7 @@ pragma[nomagic]
private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind kind) {
item = result.getImmediateParent() and
name = result.getName() and
// Associated types in `impl` and `trait` blocks are handled elsewhere
// Associated items in `impl` and `trait` blocks are handled elsewhere
not (item instanceof ImplOrTraitItemNode and result instanceof AssocItem) and
// type parameters are only available inside the declaring item
if result instanceof TypeParam
@@ -324,13 +324,14 @@ abstract class ItemNode extends Locatable {
)
)
or
exists(TraitItemNodeImpl trait | this = trait |
result = trait.getAssocItem(name)
or
// a trait has access to the associated items of its supertraits
not trait.hasAssocItem(name) and
result = trait.resolveABoundCand().getASuccessor(name).(AssocItemNode)
) and
this =
any(TraitItemNodeImpl trait |
result = trait.getAssocItem(name)
or
// a trait has access to the associated items of its supertraits
not trait.hasAssocItem(name) and
result = trait.resolveABoundCand().getASuccessor(name).(AssocItemNode)
) and
kind.isExternal() and
useOpt.isNone()
or
@@ -1788,6 +1789,8 @@ private ItemNode resolvePathCand0(PathExt path, Namespace ns) {
exists(ItemNode res |
res = unqualifiedPathLookup(path, ns, _) and
if
// `Self` paths that are not used as qualifiers (for instance `Self` in
// `fn(..) -> Self`) should resolve to the type being implemented.
not any(PathExt parent).getQualifier() = path and
isUnqualifiedSelfPath(path) and
res instanceof ImplItemNode
@@ -2191,7 +2194,7 @@ private predicate externCrateEdge(
/**
* Holds if `typeItem` is the implementing type of `impl` and the implementation
* makes `assoc` available as `name` at `kind`.
* makes `assoc` available as `name`.
*/
private predicate typeImplEdge(
TypeItemNode typeItem, ImplItemNodeImpl impl, string name, AssocItemNode assoc
@@ -2201,7 +2204,7 @@ private predicate typeImplEdge(
// Functions in `impl` blocks are made available on the implementing type
// (e.g., `S::fun` is valid) but associated types are not (e.g., `S::Output`
// is invalid).
(assoc instanceof FunctionItemNode or assoc instanceof ConstItemNode)
not assoc instanceof TypeAlias
}
pragma[nomagic]

View File

@@ -7,6 +7,12 @@ private import Type
private import TypeAbstraction
private import TypeInference
bindingset[trait, name]
pragma[inline_late]
private TypeAlias getTraitAssocType(TraitItemNode trait, string name) {
result = trait.getAssocItem(name)
}
private signature Type getAdditionalPathTypeAtSig(Path p, TypePath typePath);
/**
@@ -286,11 +292,6 @@ private module MkTypeMention<getAdditionalPathTypeAtSig/2 getAdditionalPathTypeA
)
}
bindingset[name]
private TypeAlias getResolvedAlias(string name) {
result = resolved.(TraitItemNode).getAssocItem(name)
}
bindingset[name]
private TypeAlias getResolvedTraitAssocType(string name) {
result = resolved.(TraitItemNode).getASuccessor(name)
@@ -322,7 +323,7 @@ private module MkTypeMention<getAdditionalPathTypeAtSig/2 getAdditionalPathTypeA
this = impl.getTraitPath() and
alias = impl.getASuccessor(name) and
result = alias.getTypeRepr() and
tp = TAssociatedTypeTypeParameter(resolved, this.getResolvedAlias(name))
tp = TAssociatedTypeTypeParameter(resolved, getTraitAssocType(resolved, name))
)
}
@@ -651,7 +652,9 @@ class PreTypeMention = PreTypeMention::TypeMention;
* Holds if `path` accesses an associated type `alias` from `trait` on a
* concrete type given by `tm`.
*/
predicate pathConcreteTypeAssocType(Path path, PreTypeMention tm, Trait trait, TypeAlias alias) {
private predicate pathConcreteTypeAssocType(
Path path, PreTypeMention tm, Trait trait, TypeAlias alias
) {
exists(Path qualifier |
qualifier = path.getQualifier() and
not resolvePath(tm.(PathTypeRepr).getPath()) instanceof TypeParam
@@ -659,10 +662,10 @@ predicate pathConcreteTypeAssocType(Path path, PreTypeMention tm, Trait trait, T
// path of the form `<Type as Trait>::AssocType`
// ^^^ tm ^^^^^^^^^ name
exists(string name |
name = path.getSegment().getIdentifier().getText() and
tm = qualifier.getSegment().getTypeRepr() and
name = path.getText() and
trait = resolvePath(qualifier.getSegment().getTraitTypeRepr().getPath()) and
trait.(TraitItemNode).getAssocItem(name) = alias
getTraitAssocType(trait, name) = alias and
tm = qualifier.getSegment().getTypeRepr()
)
or
// path of the form `Self::AssocType` within an `impl` block
@@ -676,12 +679,14 @@ predicate pathConcreteTypeAssocType(Path path, PreTypeMention tm, Trait trait, T
)
}
private module PathSatisfiesConstraint implements SatisfiesConstraintInputSig<PreTypeMention> {
private module PathSatisfiesConstraintInput implements SatisfiesConstraintInputSig<PreTypeMention> {
predicate relevantConstraint(PreTypeMention tm, Type constraint) {
pathConcreteTypeAssocType(_, tm, constraint.(TraitType).getTrait(), _)
}
}
module PathSatisfiesConstraint = SatisfiesConstraint<PreTypeMention, PathSatisfiesConstraintInput>;
/**
* Gets the type of `path` at `typePath` when `path` accesses an associated type
* on a concrete type.
@@ -689,8 +694,7 @@ private module PathSatisfiesConstraint implements SatisfiesConstraintInputSig<Pr
private Type getPathConcreteAssocTypeAt(Path path, TypePath typePath) {
exists(PreTypeMention tm, TraitItemNode t, TypeAlias alias, TypePath path0 |
pathConcreteTypeAssocType(path, tm, t, alias) and
SatisfiesConstraint<PreTypeMention, PathSatisfiesConstraint>::satisfiesConstraintType(tm,
TTrait(t), path0, result) and
PathSatisfiesConstraint::satisfiesConstraintType(tm, TTrait(t), path0, result) and
path0.isCons(TAssociatedTypeTypeParameter(t, alias), typePath)
)
}