Skip to content
Merged
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
70 changes: 0 additions & 70 deletions rust/ql/lib/codeql/rust/internal/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ newtype TType =
TStruct(Struct s) { Stages::TypeInferenceStage::ref() } or
TEnum(Enum e) or
TTrait(Trait t) or
TImpl(Impl i) or
TArrayType() or // todo: add size?
TRefType() or // todo: add mut?
TTypeParamTypeParameter(TypeParam t) or
Expand Down Expand Up @@ -132,75 +131,6 @@ class TraitType extends Type, TTrait {
override Location getLocation() { result = trait.getLocation() }
}

/**
* An `impl` block type.
*
* Although `impl` blocks are not really types, we treat them as such in order
* to be able to match type parameters from structs (or enums) with type
* parameters from `impl` blocks. For example, in
*
* ```rust
* struct S<T1>(T1);
*
* impl<T2> S<T2> {
* fn id(self) -> S<T2> { self }
* }
*
* let x : S(i64) = S(42);
* x.id();
* ```
*
* we pretend that the `impl` block is a base type mention of the struct `S`,
* with type argument `T1`. This means that from knowing that `x` has type
* `S(i64)`, we can first match `i64` with `T1`, and then by matching `T1` with
* `T2`, we can match `i64` with `T2`.
*
* `impl` blocks can also have base type mentions, namely the trait that they
* implement (if any). Example:
*
* ```rust
* struct S<T1>(T1);
*
* trait Trait<T2> {
* fn f(self) -> T2;
*
* fn g(self) -> T2 { self.f() }
* }
*
* impl<T3> Trait<T3> for S<T3> { // `Trait<T3>` is a base type mention of this `impl` block
* fn f(self) -> T3 {
* match self {
* S(x) => x
* }
* }
* }
*
* let x : S(i64) = S(42);
* x.g();
* ```
*
* In this case we can match `i64` with `T1`, `T1` with `T3`, and `T3` with `T2`,
* allowing us match `i64` with `T2`, and hence infer that the return type of `g`
* is `i64`.
*/
class ImplType extends Type, TImpl {
private Impl impl;

ImplType() { this = TImpl(impl) }

override StructField getStructField(string name) { none() }

override TupleField getTupleField(int i) { none() }

override TypeParameter getTypeParameter(int i) {
result = TTypeParamTypeParameter(impl.getGenericParamList().getTypeParam(i))
}

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

override Location getLocation() { result = impl.getLocation() }
}

/**
* An array type.
*
Expand Down
50 changes: 0 additions & 50 deletions rust/ql/lib/codeql/rust/internal/TypeMention.qll
Original file line number Diff line number Diff line change
Expand Up @@ -189,56 +189,6 @@ class TypeAliasMention extends TypeMention, TypeAlias {
override Type resolveType() { result = t }
}

/**
* Holds if the `i`th type argument of `selfPath`, belonging to `impl`, resolves
* to type parameter `tp`.
*
* Example:
*
* ```rust
* impl<T> Foo<T> for Bar<T> { ... }
* // ^^^^^^ selfPath
* // ^ tp
* ```
*/
pragma[nomagic]
private predicate isImplSelfTypeParam(
ImplItemNode impl, PathMention selfPath, int i, TypeParameter tp
) {
exists(PathMention path |
selfPath = impl.getSelfPath() and
path = selfPath.getSegment().getGenericArgList().getTypeArg(i).(PathTypeRepr).getPath() and
tp = path.resolveType()
)
}

class ImplMention extends TypeMention, ImplItemNode {
override TypeReprMention getTypeArgument(int i) { none() }

override Type resolveType() { result = TImpl(this) }

override Type resolveTypeAt(TypePath path) {
result = TImpl(this) and
path.isEmpty()
or
// For example, in
//
// ```rust
// struct S<T1>(T1);
//
// impl<T2> S<T2> { ... }
// ```
//
// We get that the type path "0" resolves to `T1` for the `impl` block,
// which is considered a base type mention of `S`.
exists(PathMention selfPath, TypeParameter tp, int i |
isImplSelfTypeParam(this, selfPath, pragma[only_bind_into](i), tp) and
result = selfPath.resolveType().getTypeParameter(pragma[only_bind_into](i)) and
path = TypePath::singleton(tp)
)
}
}

class TraitMention extends TypeMention, TraitItemNode {
override TypeMention getTypeArgument(int i) {
result = this.getTypeParam(i)
Expand Down