diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 00582e584f8..7e77669cc4f 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -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] diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qll index f7dc0420f6a..13809bce7da 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qll @@ -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::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 { +private module PathSatisfiesConstraintInput implements SatisfiesConstraintInputSig { predicate relevantConstraint(PreTypeMention tm, Type constraint) { pathConcreteTypeAssocType(_, tm, constraint.(TraitType).getTrait(), _) } } +module PathSatisfiesConstraint = SatisfiesConstraint; + /** * 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::satisfiesConstraintType(tm, - TTrait(t), path0, result) and + PathSatisfiesConstraint::satisfiesConstraintType(tm, TTrait(t), path0, result) and path0.isCons(TAssociatedTypeTypeParameter(t, alias), typePath) ) }