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
32 changes: 18 additions & 14 deletions rust/ql/lib/codeql/rust/internal/PathResolution.qll
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ abstract class ItemNode extends Locatable {
pragma[nomagic]
ItemNode getImmediateParent() { this = result.getADescendant() }

/** Gets a child item of this item, if any. */
ItemNode getAChild() { this = result.getImmediateParent() }

/** Gets the immediately enclosing module (or source file) of this item. */
pragma[nomagic]
ModuleLikeNode getImmediateParentModule() {
Expand Down Expand Up @@ -300,10 +303,13 @@ abstract class ItemNode extends Locatable {
typeImplEdge(this, _, name, kind, result, useOpt)
or
// trait items with default implementations made available in an implementation
exists(ImplItemNodeImpl impl, ItemNode trait |
exists(ImplItemNodeImpl impl, TraitItemNode trait |
this = impl and
trait = impl.resolveTraitTyCand() and
result = trait.getASuccessor(name, kind, useOpt) and
// do not inherit default implementations from super traits; those are inherited by
// their `impl` blocks
result = trait.getAssocItem(name) and
result.(AssocItemNode).hasImplementation() and
kind.isExternalOrBoth() and
not impl.hasAssocItem(name)
Expand Down Expand Up @@ -363,8 +369,14 @@ abstract class ItemNode extends Locatable {
this instanceof SourceFile and
builtin(name, result)
or
name = "Self" and
this = result.(ImplOrTraitItemNode).getAnItemInSelfScope()
exists(ImplOrTraitItemNode i |
name = "Self" and
this = i.getAnItemInSelfScope()
|
result = i.(Trait)
or
result = i.(ImplItemNodeImpl).resolveSelfTyCand()
)
or
name = "crate" and
this = result.(CrateItemNode).getASourceFile()
Expand Down Expand Up @@ -695,7 +707,7 @@ abstract class ImplOrTraitItemNode extends ItemNode {
Path getASelfPath() {
Stages::PathResolutionStage::ref() and
isUnqualifiedSelfPath(result) and
this = unqualifiedPathLookup(result, _, _)
result = this.getAnItemInSelfScope().getADescendant()
}

/** Gets an associated item belonging to this trait or `impl` block. */
Expand Down Expand Up @@ -921,7 +933,7 @@ private class ImplItemNodeImpl extends ImplItemNode {
result = this.resolveSelfTyBuiltin()
}

TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
TraitItemNodeImpl resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
}

private class StructItemNode extends TypeItemNode, ParameterizableItemNode instanceof Struct {
Expand Down Expand Up @@ -1773,15 +1785,7 @@ private module DollarCrateResolution {

pragma[nomagic]
private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
exists(ItemNode res |
res = unqualifiedPathLookup(path, ns, _) and
if
not any(RelevantPath parent).getQualifier() = path and
isUnqualifiedSelfPath(path) and
res instanceof ImplItemNode
then result = res.(ImplItemNodeImpl).resolveSelfTyCand()
else result = res
)
result = unqualifiedPathLookup(path, ns, _)
or
DollarCrateResolution::resolveDollarCrate(path, result) and
ns = result.getNamespace()
Expand Down
14 changes: 14 additions & 0 deletions rust/ql/lib/codeql/rust/internal/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ TypeParamTypeParameter getPtrTypeParameter() {
/** A type parameter. */
abstract class TypeParameter extends Type {
override TypeParameter getPositionalTypeParameter(int i) { none() }

abstract ItemNode getDeclaringItem();
}

private class RawTypeParameter = @type_param or @trait or @type_alias or @impl_trait_type_repr;
Expand All @@ -400,6 +402,8 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {

TypeParam getTypeParam() { result = typeParam }

override ItemNode getDeclaringItem() { result.getTypeParam(_) = typeParam }

override string toString() { result = typeParam.toString() }

override Location getLocation() { result = typeParam.getLocation() }
Expand Down Expand Up @@ -433,6 +437,8 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
/** Gets the trait that contains this associated type declaration. */
TraitItemNode getTrait() { result.getAnAssocItem() = typeAlias }

override ItemNode getDeclaringItem() { result = this.getTrait() }

override string toString() { result = typeAlias.getName().getText() }

override Location getLocation() { result = typeAlias.getLocation() }
Expand Down Expand Up @@ -465,6 +471,8 @@ class DynTraitTypeParameter extends TypeParameter, TDynTraitTypeParameter {
result = [this.getTypeParam().toString(), this.getTypeAlias().getName().toString()]
}

override ItemNode getDeclaringItem() { none() }

override string toString() { result = "dyn(" + this.toStringInner() + ")" }

override Location getLocation() { result = n.getLocation() }
Expand All @@ -480,6 +488,8 @@ class ImplTraitTypeParameter extends TypeParameter, TImplTraitTypeParameter {

ImplTraitTypeRepr getImplTraitTypeRepr() { result = implTrait }

override ItemNode getDeclaringItem() { none() }

override string toString() { result = "impl(" + typeParam.toString() + ")" }

override Location getLocation() { result = typeParam.getLocation() }
Expand All @@ -499,6 +509,8 @@ class SelfTypeParameter extends TypeParameter, TSelfTypeParameter {

Trait getTrait() { result = trait }

override ItemNode getDeclaringItem() { result = trait }

override string toString() { result = "Self [" + trait.toString() + "]" }

override Location getLocation() { result = trait.getLocation() }
Expand Down Expand Up @@ -526,6 +538,8 @@ class ImplTraitTypeTypeParameter extends ImplTraitType, TypeParameter {

ImplTraitTypeTypeParameter() { impl = function.getAParam().getTypeRepr() }

override ItemNode getDeclaringItem() { none() }

override Function getFunction() { result = function }

override TypeParameter getPositionalTypeParameter(int i) { none() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ import TypeInference::Consistency

query predicate illFormedTypeMention(TypeMention tm) {
Consistency::illFormedTypeMention(tm) and
not tm instanceof PathTypeReprMention and // avoid overlap with `PathTypeMention`
// avoid overlap with `PathTypeMention`
not tm instanceof PathTypeReprMention and
// known limitation for type mentions that would mention an escaping type parameter
not tm =
any(PathTypeMention ptm |
exists(ptm.resolvePathTypeAt(TypePath::nil())) and
not exists(ptm.resolveType())
) and
// Only include inconsistencies in the source, as we otherwise get
// inconsistencies from library code in every project.
tm.fromSource()
Expand Down
22 changes: 18 additions & 4 deletions rust/ql/lib/codeql/rust/internal/TypeMention.qll
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,19 @@ class SliceTypeReprMention extends TypeMention instanceof SliceTypeRepr {
}
}

abstract class PathTypeMention extends TypeMention, Path { }
abstract class PathTypeMention extends TypeMention, Path {
abstract Type resolvePathTypeAt(TypePath typePath);

final override Type resolveTypeAt(TypePath typePath) {
result = this.resolvePathTypeAt(typePath) and
(
not result instanceof TypeParameter
or
// Prevent type parameters from escaping their scope
this = result.(TypeParameter).getDeclaringItem().getAChild*().getADescendant()
)
}
}

class AliasPathTypeMention extends PathTypeMention {
TypeAlias resolved;
Expand All @@ -94,7 +106,7 @@ class AliasPathTypeMention extends PathTypeMention {
* Holds if this path resolved to a type alias with a rhs. that has the
* resulting type at `typePath`.
*/
override Type resolveTypeAt(TypePath typePath) {
override Type resolvePathTypeAt(TypePath typePath) {
result = rhs.resolveTypeAt(typePath) and
not result = pathGetTypeParameter(resolved, _)
or
Expand Down Expand Up @@ -275,7 +287,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
result = TAssociatedTypeTypeParameter(resolved)
}

override Type resolveTypeAt(TypePath typePath) {
override Type resolvePathTypeAt(TypePath typePath) {
typePath.isEmpty() and
result = this.resolveRootType()
or
Expand Down Expand Up @@ -307,7 +319,9 @@ class ImplSelfMention extends PathTypeMention {

ImplSelfMention() { this = impl.getASelfPath() }

override Type resolveTypeAt(TypePath typePath) { result = resolveImplSelfTypeAt(impl, typePath) }
override Type resolvePathTypeAt(TypePath typePath) {
result = resolveImplSelfTypeAt(impl, typePath)
}
}

class PathTypeReprMention extends TypeMention, PathTypeRepr {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ multipleCallTargets
| main.rs:126:9:126:11 | f(...) |
| main.rs:366:9:368:16 | ...::f(...) |
| main.rs:369:9:371:16 | ...::f(...) |
| main.rs:448:9:452:16 | ...::f(...) |
| main.rs:453:9:457:16 | ...::f(...) |
| main.rs:450:9:454:16 | ...::f(...) |
| main.rs:455:9:459:16 | ...::f(...) |
29 changes: 26 additions & 3 deletions rust/ql/test/library-tests/path-resolution/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,9 @@ mod m16 {
> {
fn f(&self) -> T; // $ item=I84

fn g(&self) -> T // $ item=I84
; // I85
fn g(&self) -> T {// $ item=I84
self.f() // $ item=f
} // I85

fn h(&self) -> T { // $ item=I84
Self::g(&self); // $ item=I85
Expand Down Expand Up @@ -436,8 +437,9 @@ mod m16 {
> // $ item=I89
for S { // $ item=I90
fn f(&self) -> S { // $ item=I90
Self::g(&self); // $ item=I92
println!("m16::<S as Trait2<S>>::f"); // $ item=println
Self::c // $ MISSING: item=I95
Self::c // $ item=I95
} // I93
}

Expand Down Expand Up @@ -466,6 +468,27 @@ mod m16 {
> // $ item=I86
>::c; // $ MISSING: item=I95
} // I83

trait Trait3 {
fn f(&self);
}

trait Trait4 {
fn g(&self);
}

struct S2;

impl Trait3 for S2 { // $ item=Trait3 item=S2
fn f(&self) { } // S2asTrait3::f
}

impl Trait4 for S2 { // $ item=Trait4 item=S2
fn g(&self) {
Self::f(&self); // $ item=S2asTrait3::f
S2::f(&self); // $ item=S2asTrait3::f
}
}
}

mod trait_visibility {
Expand Down
Loading