Skip to content

Commit 9a0c587

Browse files
committed
Rust: Support impl trait types in return position with function type parameters
1 parent a20fed8 commit 9a0c587

File tree

8 files changed

+68
-12
lines changed

8 files changed

+68
-12
lines changed

rust/ql/.generated.list

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/.gitattributes

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
// generated by codegen, remove this comment if you wish to edit this file
21
/**
32
* This module provides a hand-modifiable wrapper around the generated class `ImplTraitTypeRepr`.
43
*
54
* INTERNAL: Do not use.
65
*/
76

87
private import codeql.rust.elements.internal.generated.ImplTraitTypeRepr
8+
private import rust
99

1010
/**
1111
* INTERNAL: This module contains the customizable definition of `ImplTraitTypeRepr` and should not
1212
* be referenced directly.
1313
*/
1414
module Impl {
15+
// the following QLdoc is generated: if you need to edit it, do it in the schema file
1516
/**
1617
* An `impl Trait` type.
1718
*
@@ -21,5 +22,11 @@ module Impl {
2122
* // ^^^^^^^^^^^^^^^^^^^^^^^^^^
2223
* ```
2324
*/
24-
class ImplTraitTypeRepr extends Generated::ImplTraitTypeRepr { }
25+
class ImplTraitTypeRepr extends Generated::ImplTraitTypeRepr {
26+
/**
27+
* Gets the function for which this impl trait type occurs in the return
28+
* type, if any.
29+
*/
30+
Function getFunctionReturnPos() { this.getParentNode*() = result.getRetType().getTypeRepr() }
31+
}
2532
}

rust/ql/lib/codeql/rust/internal/Type.qll

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,20 @@ newtype TType =
3333
TDynTraitTypeParameter(TypeParam tp) {
3434
tp = any(DynTraitTypeRepr dt).getTrait().getGenericParamList().getATypeParam()
3535
} or
36+
TImplTraitTypeParameter(ImplTraitTypeRepr implTrait, TypeParam tp) {
37+
implTraitTypeParam(implTrait, _, tp)
38+
} or
3639
TRefTypeParameter() or
3740
TSelfTypeParameter(Trait t) or
3841
TSliceTypeParameter()
3942

43+
predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) {
44+
tp = implTrait.getFunctionReturnPos().getGenericParamList().getTypeParam(i) and
45+
// Only include type parameters of the function that occur inside the impl
46+
// trait type.
47+
exists(Path path | path.getParentNode*() = implTrait and resolvePath(path) = tp)
48+
}
49+
4050
/**
4151
* A type without type arguments.
4252
*
@@ -244,7 +254,12 @@ class ImplTraitType extends Type, TImplTraitType {
244254

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

247-
override TypeParameter getTypeParameter(int i) { none() }
257+
override TypeParameter getTypeParameter(int i) {
258+
exists(TypeParam tp |
259+
implTraitTypeParam(impl, i, tp) and
260+
result = TImplTraitTypeParameter(impl, tp)
261+
)
262+
}
248263

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

@@ -283,7 +298,7 @@ class DynTraitType extends Type, TDynTraitType {
283298
class ImplTraitReturnType extends ImplTraitType {
284299
private Function function;
285300

286-
ImplTraitReturnType() { impl = function.getRetType().getTypeRepr() }
301+
ImplTraitReturnType() { function = impl.getFunctionReturnPos() }
287302

288303
override Function getFunction() { result = function }
289304
}
@@ -417,6 +432,21 @@ class DynTraitTypeParameter extends TypeParameter, TDynTraitTypeParameter {
417432
override Location getLocation() { result = typeParam.getLocation() }
418433
}
419434

435+
class ImplTraitTypeParameter extends TypeParameter, TImplTraitTypeParameter {
436+
private TypeParam typeParam;
437+
private ImplTraitTypeRepr implTrait;
438+
439+
ImplTraitTypeParameter() { this = TImplTraitTypeParameter(implTrait, typeParam) }
440+
441+
TypeParam getTypeParam() { result = typeParam }
442+
443+
ImplTraitTypeRepr getImplTraitTypeRepr() { result = implTrait }
444+
445+
override string toString() { result = "impl(" + typeParam.toString() + ")" }
446+
447+
override Location getLocation() { result = typeParam.getLocation() }
448+
}
449+
420450
/** An implicit reference type parameter. */
421451
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
422452
override string toString() { result = "&T" }
@@ -531,5 +561,7 @@ final class SelfTypeBoundTypeAbstraction extends TypeAbstraction, Name {
531561
}
532562

533563
final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeRepr {
534-
override TypeParameter getATypeParameter() { none() }
564+
override TypeParameter getATypeParameter() {
565+
implTraitTypeParam(this, _, result.(TypeParamTypeParameter).getTypeParam())
566+
}
535567
}

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ private module Input1 implements InputSig1<Location> {
100100
id = idOfTypeParameterAstNode(tp0.(DynTraitTypeParameter).getTypeParam())
101101
or
102102
kind = 2 and
103+
id = idOfTypeParameterAstNode(tp0.(ImplTraitTypeParameter).getTypeParam())
104+
or
105+
kind = 3 and
103106
exists(AstNode node | id = idOfTypeParameterAstNode(node) |
104107
node = tp0.(TypeParamTypeParameter).getTypeParam() or
105108
node = tp0.(AssociatedTypeTypeParameter).getTypeAlias() or
@@ -110,7 +113,7 @@ private module Input1 implements InputSig1<Location> {
110113
exists(TupleTypeParameter ttp, int maxArity |
111114
maxArity = max(int i | i = any(TupleType tt).getArity()) and
112115
tp0 = ttp and
113-
kind = 3 and
116+
kind = 4 and
114117
id = ttp.getTupleType().getArity() * maxArity + ttp.getIndex()
115118
)
116119
|

rust/ql/lib/codeql/rust/internal/TypeMention.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ class ImplTraitTypeReprMention extends TypeMention instanceof ImplTraitTypeRepr
258258
override Type resolveTypeAt(TypePath typePath) {
259259
typePath.isEmpty() and
260260
result.(ImplTraitType).getImplTraitTypeRepr() = this
261+
or
262+
exists(ImplTraitTypeParameter tp |
263+
this = tp.getImplTraitTypeRepr() and
264+
typePath = TypePath::singleton(tp) and
265+
result = TTypeParamTypeParameter(tp.getTypeParam())
266+
)
261267
}
262268
}
263269

rust/ql/test/library-tests/type-inference/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,9 +1944,9 @@ mod impl_trait {
19441944
let a = get_a_my_trait(); // $ target=get_a_my_trait
19451945
let c = uses_my_trait2(a); // $ type=c:S2 target=uses_my_trait2
19461946
let d = uses_my_trait2(S1); // $ type=d:S2 target=uses_my_trait2
1947-
let e = get_a_my_trait2(S1).get_a(); // $ target=get_a_my_trait2 target=MyTrait::get_a MISSING: type=e:S1
1947+
let e = get_a_my_trait2(S1).get_a(); // $ target=get_a_my_trait2 target=MyTrait::get_a type=e:S1
19481948
// For this function the `impl` type does not appear in the root of the return type
1949-
let f = get_a_my_trait3(S1).unwrap().get_a(); // $ target=get_a_my_trait3 target=unwrap MISSING: target=MyTrait::get_a type=f:S1
1949+
let f = get_a_my_trait3(S1).unwrap().get_a(); // $ target=get_a_my_trait3 target=unwrap target=MyTrait::get_a type=f:S1
19501950
}
19511951
}
19521952

rust/ql/test/library-tests/type-inference/type-inference.expected

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3345,22 +3345,27 @@ inferType
33453345
| main.rs:1926:59:1928:5 | { ... } | | main.rs:1879:5:1879:22 | S3 |
33463346
| main.rs:1926:59:1928:5 | { ... } | | main.rs:1926:43:1926:57 | ImplTraitTypeRepr |
33473347
| main.rs:1926:59:1928:5 | { ... } | T3 | main.rs:1926:24:1926:31 | T |
3348+
| main.rs:1926:59:1928:5 | { ... } | impl(T) | main.rs:1926:24:1926:31 | T |
33483349
| main.rs:1927:9:1927:13 | S3(...) | | main.rs:1879:5:1879:22 | S3 |
33493350
| main.rs:1927:9:1927:13 | S3(...) | | main.rs:1926:43:1926:57 | ImplTraitTypeRepr |
33503351
| main.rs:1927:9:1927:13 | S3(...) | T3 | main.rs:1926:24:1926:31 | T |
3352+
| main.rs:1927:9:1927:13 | S3(...) | impl(T) | main.rs:1926:24:1926:31 | T |
33513353
| main.rs:1927:12:1927:12 | x | | main.rs:1926:24:1926:31 | T |
33523354
| main.rs:1930:34:1930:34 | x | | main.rs:1930:24:1930:31 | T |
33533355
| main.rs:1930:67:1932:5 | { ... } | | {EXTERNAL LOCATION} | Option |
33543356
| main.rs:1930:67:1932:5 | { ... } | T | main.rs:1879:5:1879:22 | S3 |
33553357
| main.rs:1930:67:1932:5 | { ... } | T | main.rs:1930:50:1930:64 | ImplTraitTypeRepr |
33563358
| main.rs:1930:67:1932:5 | { ... } | T.T3 | main.rs:1930:24:1930:31 | T |
3359+
| main.rs:1930:67:1932:5 | { ... } | T.impl(T) | main.rs:1930:24:1930:31 | T |
33573360
| main.rs:1931:9:1931:19 | Some(...) | | {EXTERNAL LOCATION} | Option |
33583361
| main.rs:1931:9:1931:19 | Some(...) | T | main.rs:1879:5:1879:22 | S3 |
33593362
| main.rs:1931:9:1931:19 | Some(...) | T | main.rs:1930:50:1930:64 | ImplTraitTypeRepr |
33603363
| main.rs:1931:9:1931:19 | Some(...) | T.T3 | main.rs:1930:24:1930:31 | T |
3364+
| main.rs:1931:9:1931:19 | Some(...) | T.impl(T) | main.rs:1930:24:1930:31 | T |
33613365
| main.rs:1931:14:1931:18 | S3(...) | | main.rs:1879:5:1879:22 | S3 |
33623366
| main.rs:1931:14:1931:18 | S3(...) | | main.rs:1930:50:1930:64 | ImplTraitTypeRepr |
33633367
| main.rs:1931:14:1931:18 | S3(...) | T3 | main.rs:1930:24:1930:31 | T |
3368+
| main.rs:1931:14:1931:18 | S3(...) | impl(T) | main.rs:1930:24:1930:31 | T |
33643369
| main.rs:1931:17:1931:17 | x | | main.rs:1930:24:1930:31 | T |
33653370
| main.rs:1934:26:1934:26 | t | | main.rs:1934:29:1934:43 | ImplTraitTypeRepr |
33663371
| main.rs:1934:51:1936:5 | { ... } | | main.rs:1934:23:1934:23 | A |
@@ -3383,13 +3388,18 @@ inferType
33833388
| main.rs:1946:13:1946:13 | d | | main.rs:1878:5:1878:14 | S2 |
33843389
| main.rs:1946:17:1946:34 | uses_my_trait2(...) | | main.rs:1878:5:1878:14 | S2 |
33853390
| main.rs:1946:32:1946:33 | S1 | | main.rs:1876:5:1877:14 | S1 |
3386-
| main.rs:1947:13:1947:13 | e | | main.rs:1926:24:1926:31 | T |
3391+
| main.rs:1947:13:1947:13 | e | | main.rs:1876:5:1877:14 | S1 |
33873392
| main.rs:1947:17:1947:35 | get_a_my_trait2(...) | | main.rs:1926:43:1926:57 | ImplTraitTypeRepr |
3388-
| main.rs:1947:17:1947:43 | ... .get_a() | | main.rs:1926:24:1926:31 | T |
3393+
| main.rs:1947:17:1947:35 | get_a_my_trait2(...) | impl(T) | main.rs:1876:5:1877:14 | S1 |
3394+
| main.rs:1947:17:1947:43 | ... .get_a() | | main.rs:1876:5:1877:14 | S1 |
33893395
| main.rs:1947:33:1947:34 | S1 | | main.rs:1876:5:1877:14 | S1 |
3396+
| main.rs:1949:13:1949:13 | f | | main.rs:1876:5:1877:14 | S1 |
33903397
| main.rs:1949:17:1949:35 | get_a_my_trait3(...) | | {EXTERNAL LOCATION} | Option |
33913398
| main.rs:1949:17:1949:35 | get_a_my_trait3(...) | T | main.rs:1930:50:1930:64 | ImplTraitTypeRepr |
3399+
| main.rs:1949:17:1949:35 | get_a_my_trait3(...) | T.impl(T) | main.rs:1876:5:1877:14 | S1 |
33923400
| main.rs:1949:17:1949:44 | ... .unwrap() | | main.rs:1930:50:1930:64 | ImplTraitTypeRepr |
3401+
| main.rs:1949:17:1949:44 | ... .unwrap() | impl(T) | main.rs:1876:5:1877:14 | S1 |
3402+
| main.rs:1949:17:1949:52 | ... .get_a() | | main.rs:1876:5:1877:14 | S1 |
33933403
| main.rs:1949:33:1949:34 | S1 | | main.rs:1876:5:1877:14 | S1 |
33943404
| main.rs:1960:16:1960:20 | SelfParam | | file://:0:0:0:0 | & |
33953405
| main.rs:1960:16:1960:20 | SelfParam | &T | main.rs:1956:5:1957:13 | S |

0 commit comments

Comments
 (0)