mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Merge pull request #20119 from paldepind/rust/type-inference-assoc-type-tp
Rust: Type inference for impl trait types with type parameters
This commit is contained in:
1
rust/ql/.generated.list
generated
1
rust/ql/.generated.list
generated
@@ -288,7 +288,6 @@ lib/codeql/rust/elements/internal/IdentPatConstructor.qll 09792f5a070996b65f095d
|
||||
lib/codeql/rust/elements/internal/IfExprConstructor.qll 03088b54c8fa623f93a5b5a7eb896f680e8b0e9025488157a02c48aaebc6ad56 906f916c3690d0721a31dd31b302dcdcec4233bb507683007d82cf10793a648f
|
||||
lib/codeql/rust/elements/internal/ImplConstructor.qll 24edccca59f70d812d1458b412a45310ddc096d095332f6e3258903c54c1bb44 7eb673b3ab33a0873ee5ce189105425066b376821cce0fc9eb8ace22995f0bc7
|
||||
lib/codeql/rust/elements/internal/ImplTraitTypeReprConstructor.qll 1ed355e5e56f432b24b6f4778e4dc45c6e65095190cacb7a5015529e0c9d01f8 c8505185a042da4eb20a0cc32323194a0290c4bf821c7e0fce7351b194b10f31
|
||||
lib/codeql/rust/elements/internal/ImplTraitTypeReprImpl.qll 26259dfa599f48fb00ff7e5e17e9a8b40c29360f02cf11abc4ccbb573996f5bb 5b4c0e29e9c20c3121e3f37f1f1cba3f181d56023e9912c6dc5c481cb8ee3e4d
|
||||
lib/codeql/rust/elements/internal/IndexExprConstructor.qll 99bdc3d793c4dbd993860da60abe2b7c604345d645e86916462bc55a6939a5d1 3fe9d7da725956903707806aadbecac8d5b3874e8bed63c9bab54fff630e75dd
|
||||
lib/codeql/rust/elements/internal/InferTypeReprConstructor.qll bc5f16853401617fc9c5af8a1287a23c5921df1b615cfbe2d7c7a70145ecfcbd da93bd28ea2daade2cbb0a729be3fbf05f72bc02009565c7bb062e4f68fdb9e7
|
||||
lib/codeql/rust/elements/internal/ItemImpl.qll e3fb78d572ce1c3cc857d2671bd71ff4d7850321acfddc5f15533ff87accda79 fbabc2081e4b2773b04938d57bb51af908c80b7bc53c3127c74ab5d4fb9837bc
|
||||
|
||||
1
rust/ql/.gitattributes
generated
vendored
1
rust/ql/.gitattributes
generated
vendored
@@ -290,7 +290,6 @@
|
||||
/lib/codeql/rust/elements/internal/IfExprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ImplConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ImplTraitTypeReprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ImplTraitTypeReprImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/IndexExprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/InferTypeReprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ItemImpl.qll linguist-generated
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// generated by codegen, remove this comment if you wish to edit this file
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `ImplTraitTypeRepr`.
|
||||
*
|
||||
@@ -6,12 +5,14 @@
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.ImplTraitTypeRepr
|
||||
private import rust
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `ImplTraitTypeRepr` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
// the following QLdoc is generated: if you need to edit it, do it in the schema file
|
||||
/**
|
||||
* An `impl Trait` type.
|
||||
*
|
||||
@@ -21,5 +22,15 @@ module Impl {
|
||||
* // ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
* ```
|
||||
*/
|
||||
class ImplTraitTypeRepr extends Generated::ImplTraitTypeRepr { }
|
||||
class ImplTraitTypeRepr extends Generated::ImplTraitTypeRepr {
|
||||
/** Gets the function for which this impl trait type occurs, if any. */
|
||||
Function getFunction() {
|
||||
this.getParentNode*() = [result.getRetType().getTypeRepr(), result.getAParam().getTypeRepr()]
|
||||
}
|
||||
|
||||
/** Holds if this impl trait type occurs in the return type of a function. */
|
||||
predicate isInReturnPos() {
|
||||
this.getParentNode*() = this.getFunction().getRetType().getTypeRepr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,10 +52,21 @@ newtype TType =
|
||||
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
|
||||
TArrayTypeParameter() or
|
||||
TDynTraitTypeParameter(AstNode n) { dynTraitTypeParameter(_, n) } or
|
||||
TImplTraitTypeParameter(ImplTraitTypeRepr implTrait, TypeParam tp) {
|
||||
implTraitTypeParam(implTrait, _, tp)
|
||||
} or
|
||||
TRefTypeParameter() or
|
||||
TSelfTypeParameter(Trait t) or
|
||||
TSliceTypeParameter()
|
||||
|
||||
predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) {
|
||||
implTrait.isInReturnPos() and
|
||||
tp = implTrait.getFunction().getGenericParamList().getTypeParam(i) and
|
||||
// Only include type parameters of the function that occur inside the impl
|
||||
// trait type.
|
||||
exists(Path path | path.getParentNode*() = implTrait and resolvePath(path) = tp)
|
||||
}
|
||||
|
||||
/**
|
||||
* A type without type arguments.
|
||||
*
|
||||
@@ -263,7 +274,12 @@ class ImplTraitType extends Type, TImplTraitType {
|
||||
|
||||
override TupleField getTupleField(int i) { none() }
|
||||
|
||||
override TypeParameter getTypeParameter(int i) { none() }
|
||||
override TypeParameter getTypeParameter(int i) {
|
||||
exists(TypeParam tp |
|
||||
implTraitTypeParam(impl, i, tp) and
|
||||
result = TImplTraitTypeParameter(impl, tp)
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() { result = impl.toString() }
|
||||
|
||||
@@ -302,7 +318,7 @@ class DynTraitType extends Type, TDynTraitType {
|
||||
class ImplTraitReturnType extends ImplTraitType {
|
||||
private Function function;
|
||||
|
||||
ImplTraitReturnType() { impl = function.getRetType().getTypeRepr() }
|
||||
ImplTraitReturnType() { impl.isInReturnPos() and function = impl.getFunction() }
|
||||
|
||||
override Function getFunction() { result = function }
|
||||
}
|
||||
@@ -456,6 +472,21 @@ class DynTraitTypeParameter extends TypeParameter, TDynTraitTypeParameter {
|
||||
override Location getLocation() { result = n.getLocation() }
|
||||
}
|
||||
|
||||
class ImplTraitTypeParameter extends TypeParameter, TImplTraitTypeParameter {
|
||||
private TypeParam typeParam;
|
||||
private ImplTraitTypeRepr implTrait;
|
||||
|
||||
ImplTraitTypeParameter() { this = TImplTraitTypeParameter(implTrait, typeParam) }
|
||||
|
||||
TypeParam getTypeParam() { result = typeParam }
|
||||
|
||||
ImplTraitTypeRepr getImplTraitTypeRepr() { result = implTrait }
|
||||
|
||||
override string toString() { result = "impl(" + typeParam.toString() + ")" }
|
||||
|
||||
override Location getLocation() { result = typeParam.getLocation() }
|
||||
}
|
||||
|
||||
/** An implicit reference type parameter. */
|
||||
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
|
||||
override string toString() { result = "&T" }
|
||||
@@ -569,5 +600,7 @@ final class SelfTypeBoundTypeAbstraction extends TypeAbstraction, Name {
|
||||
}
|
||||
|
||||
final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeRepr {
|
||||
override TypeParameter getATypeParameter() { none() }
|
||||
override TypeParameter getATypeParameter() {
|
||||
implTraitTypeParam(this, _, result.(TypeParamTypeParameter).getTypeParam())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,42 +83,48 @@ private module Input1 implements InputSig1<Location> {
|
||||
|
||||
int getTypeParameterId(TypeParameter tp) {
|
||||
tp =
|
||||
rank[result](TypeParameter tp0, int kind, int id |
|
||||
rank[result](TypeParameter tp0, int kind, int id1, int id2 |
|
||||
tp0 instanceof ArrayTypeParameter and
|
||||
kind = 0 and
|
||||
id = 0
|
||||
id1 = 0 and
|
||||
id2 = 0
|
||||
or
|
||||
tp0 instanceof RefTypeParameter and
|
||||
kind = 0 and
|
||||
id = 1
|
||||
id1 = 0 and
|
||||
id2 = 1
|
||||
or
|
||||
tp0 instanceof SliceTypeParameter and
|
||||
kind = 0 and
|
||||
id = 2
|
||||
id1 = 0 and
|
||||
id2 = 2
|
||||
or
|
||||
kind = 1 and
|
||||
id =
|
||||
id1 = 0 and
|
||||
id2 =
|
||||
idOfTypeParameterAstNode([
|
||||
tp0.(DynTraitTypeParameter).getTypeParam().(AstNode),
|
||||
tp0.(DynTraitTypeParameter).getTypeAlias()
|
||||
])
|
||||
or
|
||||
kind = 2 and
|
||||
exists(AstNode node | id = idOfTypeParameterAstNode(node) |
|
||||
id1 = idOfTypeParameterAstNode(tp0.(ImplTraitTypeParameter).getImplTraitTypeRepr()) and
|
||||
id2 = idOfTypeParameterAstNode(tp0.(ImplTraitTypeParameter).getTypeParam())
|
||||
or
|
||||
kind = 3 and
|
||||
id1 = 0 and
|
||||
exists(AstNode node | id2 = idOfTypeParameterAstNode(node) |
|
||||
node = tp0.(TypeParamTypeParameter).getTypeParam() or
|
||||
node = tp0.(AssociatedTypeTypeParameter).getTypeAlias() or
|
||||
node = tp0.(SelfTypeParameter).getTrait() or
|
||||
node = tp0.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr()
|
||||
)
|
||||
or
|
||||
exists(TupleTypeParameter ttp, int maxArity |
|
||||
maxArity = max(int i | i = any(TupleType tt).getArity()) and
|
||||
tp0 = ttp and
|
||||
kind = 3 and
|
||||
id = ttp.getTupleType().getArity() * maxArity + ttp.getIndex()
|
||||
)
|
||||
kind = 4 and
|
||||
id1 = tp0.(TupleTypeParameter).getTupleType().getArity() and
|
||||
id2 = tp0.(TupleTypeParameter).getIndex()
|
||||
|
|
||||
tp0 order by kind, id
|
||||
tp0 order by kind, id1, id2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +258,12 @@ class ImplTraitTypeReprMention extends TypeMention instanceof ImplTraitTypeRepr
|
||||
override Type resolveTypeAt(TypePath typePath) {
|
||||
typePath.isEmpty() and
|
||||
result.(ImplTraitType).getImplTraitTypeRepr() = this
|
||||
or
|
||||
exists(ImplTraitTypeParameter tp |
|
||||
this = tp.getImplTraitTypeRepr() and
|
||||
typePath = TypePath::singleton(tp) and
|
||||
result = TTypeParamTypeParameter(tp.getTypeParam())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
multipleCallTargets
|
||||
| dereference.rs:61:15:61:24 | e1.deref() |
|
||||
| main.rs:2253:13:2253:31 | ...::from(...) |
|
||||
| main.rs:2254:13:2254:31 | ...::from(...) |
|
||||
| main.rs:2255:13:2255:31 | ...::from(...) |
|
||||
| main.rs:2261:13:2261:31 | ...::from(...) |
|
||||
| main.rs:2262:13:2262:31 | ...::from(...) |
|
||||
| main.rs:2263:13:2263:31 | ...::from(...) |
|
||||
| main.rs:2278:13:2278:31 | ...::from(...) |
|
||||
| main.rs:2279:13:2279:31 | ...::from(...) |
|
||||
| main.rs:2280:13:2280:31 | ...::from(...) |
|
||||
| main.rs:2286:13:2286:31 | ...::from(...) |
|
||||
| main.rs:2287:13:2287:31 | ...::from(...) |
|
||||
| main.rs:2288:13:2288:31 | ...::from(...) |
|
||||
|
||||
@@ -1913,8 +1913,10 @@ mod async_ {
|
||||
}
|
||||
|
||||
mod impl_trait {
|
||||
#[derive(Copy, Clone)]
|
||||
struct S1;
|
||||
struct S2;
|
||||
struct S3<T3>(T3);
|
||||
|
||||
trait Trait1 {
|
||||
fn f1(&self) {} // Trait1f1
|
||||
@@ -1946,6 +1948,13 @@ mod impl_trait {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> MyTrait<T> for S3<T> {
|
||||
fn get_a(&self) -> T {
|
||||
let S3(t) = self;
|
||||
t.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_a_my_trait() -> impl MyTrait<S2> {
|
||||
S1
|
||||
}
|
||||
@@ -1954,6 +1963,18 @@ mod impl_trait {
|
||||
t.get_a() // $ target=MyTrait::get_a
|
||||
}
|
||||
|
||||
fn get_a_my_trait2<T: Clone>(x: T) -> impl MyTrait<T> {
|
||||
S3(x)
|
||||
}
|
||||
|
||||
fn get_a_my_trait3<T: Clone>(x: T) -> Option<impl MyTrait<T>> {
|
||||
Some(S3(x))
|
||||
}
|
||||
|
||||
fn get_a_my_trait4<T: Clone>(x: T) -> (impl MyTrait<T>, impl MyTrait<T>) {
|
||||
(S3(x.clone()), S3(x)) // $ target=clone
|
||||
}
|
||||
|
||||
fn uses_my_trait2<A>(t: impl MyTrait<A>) -> A {
|
||||
t.get_a() // $ target=MyTrait::get_a
|
||||
}
|
||||
@@ -1967,6 +1988,10 @@ mod impl_trait {
|
||||
let a = get_a_my_trait(); // $ target=get_a_my_trait
|
||||
let c = uses_my_trait2(a); // $ type=c:S2 target=uses_my_trait2
|
||||
let d = uses_my_trait2(S1); // $ type=d:S2 target=uses_my_trait2
|
||||
let e = get_a_my_trait2(S1).get_a(); // $ target=get_a_my_trait2 target=MyTrait::get_a type=e:S1
|
||||
// For this function the `impl` type does not appear in the root of the return type
|
||||
let f = get_a_my_trait3(S1).unwrap().get_a(); // $ target=get_a_my_trait3 target=unwrap target=MyTrait::get_a type=f:S1
|
||||
let g = get_a_my_trait4(S1).0.get_a(); // $ target=get_a_my_trait4 target=MyTrait::get_a type=g:S1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2425,7 +2450,7 @@ mod tuples {
|
||||
|
||||
let pair = [1, 1].into(); // $ type=pair:(T_2) type=pair:0(2).i32 type=pair:1(2).i32 MISSING: target=into
|
||||
match pair {
|
||||
(0,0) => print!("unexpected"),
|
||||
(0, 0) => print!("unexpected"),
|
||||
_ => print!("expected"),
|
||||
}
|
||||
let x = pair.0; // $ type=x:i32
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user