Skip to content

Commit e4650fb

Browse files
committed
Rust: Rework type inference for impl Trait in return position
1 parent 22091d2 commit e4650fb

File tree

5 files changed

+75
-89
lines changed

5 files changed

+75
-89
lines changed

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

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ newtype TType =
1515
TTrait(Trait t) or
1616
TArrayType() or // todo: add size?
1717
TRefType() or // todo: add mut?
18-
TImplTraitType(ImplTraitTypeRepr impl) or
18+
TImplTraitArgumentType(Function function, ImplTraitTypeRepr impl) {
19+
impl = function.getAParam().getTypeRepr()
20+
} or
1921
TSliceType() or
2022
TTypeParamTypeParameter(TypeParam t) or
2123
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
@@ -196,53 +198,6 @@ class RefType extends Type, TRefType {
196198
override Location getLocation() { result instanceof EmptyLocation }
197199
}
198200

199-
/**
200-
* An [impl Trait][1] type.
201-
*
202-
* Each syntactic `impl Trait` type gives rise to its own type, even if
203-
* two `impl Trait` types have the same bounds.
204-
*
205-
* [1]: https://doc.rust-lang.org/reference/types/impl-trait.html
206-
*/
207-
class ImplTraitType extends Type, TImplTraitType {
208-
ImplTraitTypeRepr impl;
209-
210-
ImplTraitType() { this = TImplTraitType(impl) }
211-
212-
/** Gets the underlying AST node. */
213-
ImplTraitTypeRepr getImplTraitTypeRepr() { result = impl }
214-
215-
/** Gets the function that this `impl Trait` belongs to. */
216-
abstract Function getFunction();
217-
218-
override StructField getStructField(string name) { none() }
219-
220-
override TupleField getTupleField(int i) { none() }
221-
222-
override TypeParameter getTypeParameter(int i) { none() }
223-
224-
override string toString() { result = impl.toString() }
225-
226-
override Location getLocation() { result = impl.getLocation() }
227-
}
228-
229-
/**
230-
* An [impl Trait in return position][1] type, for example:
231-
*
232-
* ```rust
233-
* fn foo() -> impl Trait
234-
* ```
235-
*
236-
* [1]: https://doc.rust-lang.org/reference/types/impl-trait.html#r-type.impl-trait.return
237-
*/
238-
class ImplTraitReturnType extends ImplTraitType {
239-
private Function function;
240-
241-
ImplTraitReturnType() { impl = function.getRetType().getTypeRepr() }
242-
243-
override Function getFunction() { result = function }
244-
}
245-
246201
/**
247202
* A slice type.
248203
*
@@ -386,18 +341,27 @@ class SelfTypeParameter extends TypeParameter, TSelfTypeParameter {
386341
*
387342
* [1]: https://doc.rust-lang.org/reference/types/impl-trait.html#r-type.impl-trait.param
388343
*/
389-
class ImplTraitTypeTypeParameter extends ImplTraitType, TypeParameter {
344+
class ImplTraitArgumentType extends TypeParameter, TImplTraitArgumentType {
390345
private Function function;
346+
private ImplTraitTypeRepr impl;
391347

392-
ImplTraitTypeTypeParameter() { impl = function.getAParam().getTypeRepr() }
348+
ImplTraitArgumentType() { this = TImplTraitArgumentType(function, impl) }
393349

394-
override Function getFunction() { result = function }
350+
/** Gets the function that this `impl Trait` belongs to. */
351+
Function getFunction() { result = function }
352+
353+
/** Gets the underlying AST node. */
354+
ImplTraitTypeRepr getImplTraitTypeRepr() { result = impl }
395355

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

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

400360
override TypeParameter getTypeParameter(int i) { none() }
361+
362+
override string toString() { result = impl.toString() }
363+
364+
override Location getLocation() { result = impl.getLocation() }
401365
}
402366

403367
/**

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

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private module Input1 implements InputSig1<Location> {
101101
node = tp0.(TypeParamTypeParameter).getTypeParam() or
102102
node = tp0.(AssociatedTypeTypeParameter).getTypeAlias() or
103103
node = tp0.(SelfTypeParameter).getTrait() or
104-
node = tp0.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr()
104+
node = tp0.(ImplTraitArgumentType).getImplTraitTypeRepr()
105105
)
106106
|
107107
tp0 order by kind, id
@@ -132,11 +132,7 @@ private module Input2 implements InputSig2 {
132132
result = tp.(SelfTypeParameter).getTrait()
133133
or
134134
result =
135-
tp.(ImplTraitTypeTypeParameter)
136-
.getImplTraitTypeRepr()
137-
.getTypeBoundList()
138-
.getABound()
139-
.getTypeRepr()
135+
tp.(ImplTraitArgumentType).getImplTraitTypeRepr().getTypeBoundList().getABound().getTypeRepr()
140136
}
141137

142138
/**
@@ -670,7 +666,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
670666
)
671667
or
672668
ppos.isImplicit() and
673-
this = result.(ImplTraitTypeTypeParameter).getFunction()
669+
this = result.(ImplTraitArgumentType).getFunction()
674670
}
675671

676672
override Type getParameterType(DeclarationPosition dpos, TypePath path) {
@@ -1476,7 +1472,7 @@ private Function getTypeParameterMethod(TypeParameter tp, string name) {
14761472
or
14771473
result = getMethodSuccessor(tp.(SelfTypeParameter).getTrait(), name)
14781474
or
1479-
result = getMethodSuccessor(tp.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr(), name)
1475+
result = getMethodSuccessor(tp.(ImplTraitArgumentType).getImplTraitTypeRepr(), name)
14801476
}
14811477

14821478
pragma[nomagic]
@@ -1655,8 +1651,8 @@ private Function getMethodFromImpl(MethodCall mc) {
16551651

16561652
bindingset[trait, name]
16571653
pragma[inline_late]
1658-
private Function getTraitMethod(ImplTraitReturnType trait, string name) {
1659-
result = getMethodSuccessor(trait.getImplTraitTypeRepr(), name)
1654+
private Function getTraitMethod(TraitType trait, string name) {
1655+
result = getMethodSuccessor(trait.getTrait(), name)
16601656
}
16611657

16621658
pragma[nomagic]
@@ -1669,7 +1665,8 @@ private Function resolveMethodCallTarget(MethodCall mc) {
16691665
result = getTypeParameterMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName())
16701666
or
16711667
// The type of the receiver is an `impl Trait` type.
1672-
result = getTraitMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName())
1668+
result = getTraitMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName()) and
1669+
not exists(mc.getTrait())
16731670
}
16741671

16751672
pragma[nomagic]

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,13 @@ class PathTypeReprMention extends TypeMention, PathTypeRepr {
216216
class ImplTraitTypeReprMention extends TypeMention instanceof ImplTraitTypeRepr {
217217
override Type resolveTypeAt(TypePath typePath) {
218218
typePath.isEmpty() and
219-
result.(ImplTraitType).getImplTraitTypeRepr() = this
219+
result.(ImplTraitArgumentType).getImplTraitTypeRepr() = this
220+
or
221+
exists(Function f |
222+
this = f.getRetType().getTypeRepr() and
223+
result =
224+
super.getTypeBoundList().getABound().getTypeRepr().(TypeMention).resolveTypeAt(typePath)
225+
)
220226
}
221227
}
222228

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,7 @@ mod impl_trait {
19211921
let a = get_a_my_trait(); // $ method=get_a_my_trait
19221922
let c = uses_my_trait2(a); // $ type=c:S2 method=uses_my_trait2
19231923
let d = uses_my_trait2(S1); // $ type=d:S2 method=uses_my_trait2
1924-
let e = get_a_my_trait2(S1).get_a(); // $ method=get_a_my_trait2 method=MyTrait::get_a $ MISSING: type=e:S1
1924+
let e = get_a_my_trait2(S1).get_a(); // $ method=get_a_my_trait2 method=MyTrait::get_a $ type=e:S1
19251925
}
19261926
}
19271927

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

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,10 +3128,8 @@ inferType
31283128
| main.rs:1821:25:1823:5 | { ... } | | main.rs:1815:5:1815:14 | S1 |
31293129
| main.rs:1822:9:1822:10 | S1 | | main.rs:1815:5:1815:14 | S1 |
31303130
| main.rs:1825:41:1827:5 | { ... } | | {EXTERNAL LOCATION} | trait Future |
3131-
| main.rs:1825:41:1827:5 | { ... } | | main.rs:1825:16:1825:39 | ImplTraitTypeRepr |
31323131
| main.rs:1825:41:1827:5 | { ... } | Output | main.rs:1815:5:1815:14 | S1 |
31333132
| main.rs:1826:9:1826:20 | { ... } | | {EXTERNAL LOCATION} | trait Future |
3134-
| main.rs:1826:9:1826:20 | { ... } | | main.rs:1825:16:1825:39 | ImplTraitTypeRepr |
31353133
| main.rs:1826:9:1826:20 | { ... } | Output | main.rs:1815:5:1815:14 | S1 |
31363134
| main.rs:1826:17:1826:18 | S1 | | main.rs:1815:5:1815:14 | S1 |
31373135
| main.rs:1835:13:1835:42 | SelfParam | | {EXTERNAL LOCATION} | Pin |
@@ -3144,16 +3142,20 @@ inferType
31443142
| main.rs:1838:13:1838:38 | ...::Ready(...) | | {EXTERNAL LOCATION} | Poll |
31453143
| main.rs:1838:13:1838:38 | ...::Ready(...) | T | main.rs:1815:5:1815:14 | S1 |
31463144
| main.rs:1838:36:1838:37 | S1 | | main.rs:1815:5:1815:14 | S1 |
3145+
| main.rs:1842:41:1844:5 | { ... } | | {EXTERNAL LOCATION} | trait Future |
31473146
| main.rs:1842:41:1844:5 | { ... } | | main.rs:1829:5:1829:14 | S2 |
3148-
| main.rs:1842:41:1844:5 | { ... } | | main.rs:1842:16:1842:39 | ImplTraitTypeRepr |
3147+
| main.rs:1842:41:1844:5 | { ... } | Output | main.rs:1815:5:1815:14 | S1 |
3148+
| main.rs:1843:9:1843:10 | S2 | | {EXTERNAL LOCATION} | trait Future |
31493149
| main.rs:1843:9:1843:10 | S2 | | main.rs:1829:5:1829:14 | S2 |
3150-
| main.rs:1843:9:1843:10 | S2 | | main.rs:1842:16:1842:39 | ImplTraitTypeRepr |
3150+
| main.rs:1843:9:1843:10 | S2 | Output | main.rs:1815:5:1815:14 | S1 |
31513151
| main.rs:1847:9:1847:12 | f1(...) | | {EXTERNAL LOCATION} | trait Future |
31523152
| main.rs:1847:9:1847:12 | f1(...) | Output | main.rs:1815:5:1815:14 | S1 |
31533153
| main.rs:1847:9:1847:18 | await ... | | main.rs:1815:5:1815:14 | S1 |
3154-
| main.rs:1848:9:1848:12 | f2(...) | | main.rs:1825:16:1825:39 | ImplTraitTypeRepr |
3154+
| main.rs:1848:9:1848:12 | f2(...) | | {EXTERNAL LOCATION} | trait Future |
3155+
| main.rs:1848:9:1848:12 | f2(...) | Output | main.rs:1815:5:1815:14 | S1 |
31553156
| main.rs:1848:9:1848:18 | await ... | | main.rs:1815:5:1815:14 | S1 |
3156-
| main.rs:1849:9:1849:12 | f3(...) | | main.rs:1842:16:1842:39 | ImplTraitTypeRepr |
3157+
| main.rs:1849:9:1849:12 | f3(...) | | {EXTERNAL LOCATION} | trait Future |
3158+
| main.rs:1849:9:1849:12 | f3(...) | Output | main.rs:1815:5:1815:14 | S1 |
31573159
| main.rs:1849:9:1849:18 | await ... | | main.rs:1815:5:1815:14 | S1 |
31583160
| main.rs:1850:9:1850:10 | S2 | | main.rs:1829:5:1829:14 | S2 |
31593161
| main.rs:1850:9:1850:16 | await S2 | | main.rs:1815:5:1815:14 | S1 |
@@ -3174,9 +3176,11 @@ inferType
31743176
| main.rs:1875:15:1875:19 | SelfParam | | file://:0:0:0:0 | & |
31753177
| main.rs:1875:15:1875:19 | SelfParam | &T | main.rs:1857:5:1858:14 | S1 |
31763178
| main.rs:1878:37:1880:5 | { ... } | | main.rs:1857:5:1858:14 | S1 |
3177-
| main.rs:1878:37:1880:5 | { ... } | | main.rs:1878:16:1878:35 | ImplTraitTypeRepr |
3179+
| main.rs:1878:37:1880:5 | { ... } | | main.rs:1862:5:1864:5 | trait Trait1 |
3180+
| main.rs:1878:37:1880:5 | { ... } | | main.rs:1866:5:1868:5 | trait Trait2 |
31783181
| main.rs:1879:9:1879:10 | S1 | | main.rs:1857:5:1858:14 | S1 |
3179-
| main.rs:1879:9:1879:10 | S1 | | main.rs:1878:16:1878:35 | ImplTraitTypeRepr |
3182+
| main.rs:1879:9:1879:10 | S1 | | main.rs:1862:5:1864:5 | trait Trait1 |
3183+
| main.rs:1879:9:1879:10 | S1 | | main.rs:1866:5:1868:5 | trait Trait2 |
31803184
| main.rs:1883:18:1883:22 | SelfParam | | file://:0:0:0:0 | & |
31813185
| main.rs:1883:18:1883:22 | SelfParam | &T | main.rs:1882:5:1884:5 | Self [trait MyTrait] |
31823186
| main.rs:1887:18:1887:22 | SelfParam | | file://:0:0:0:0 | & |
@@ -3198,15 +3202,19 @@ inferType
31983202
| main.rs:1894:25:1894:28 | self | &T.T3 | main.rs:1892:10:1892:17 | T |
31993203
| main.rs:1895:13:1895:21 | t.clone() | | main.rs:1892:10:1892:17 | T |
32003204
| main.rs:1899:45:1901:5 | { ... } | | main.rs:1857:5:1858:14 | S1 |
3201-
| main.rs:1899:45:1901:5 | { ... } | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3205+
| main.rs:1899:45:1901:5 | { ... } | | main.rs:1882:5:1884:5 | trait MyTrait |
3206+
| main.rs:1899:45:1901:5 | { ... } | A | main.rs:1859:5:1859:14 | S2 |
32023207
| main.rs:1900:9:1900:10 | S1 | | main.rs:1857:5:1858:14 | S1 |
3203-
| main.rs:1900:9:1900:10 | S1 | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3208+
| main.rs:1900:9:1900:10 | S1 | | main.rs:1882:5:1884:5 | trait MyTrait |
3209+
| main.rs:1900:9:1900:10 | S1 | A | main.rs:1859:5:1859:14 | S2 |
32043210
| main.rs:1903:34:1903:34 | x | | main.rs:1903:24:1903:31 | T |
32053211
| main.rs:1903:59:1905:5 | { ... } | | main.rs:1860:5:1860:22 | S3 |
3206-
| main.rs:1903:59:1905:5 | { ... } | | main.rs:1903:43:1903:57 | ImplTraitTypeRepr |
3212+
| main.rs:1903:59:1905:5 | { ... } | | main.rs:1882:5:1884:5 | trait MyTrait |
3213+
| main.rs:1903:59:1905:5 | { ... } | A | main.rs:1903:24:1903:31 | T |
32073214
| main.rs:1903:59:1905:5 | { ... } | T3 | main.rs:1903:24:1903:31 | T |
32083215
| main.rs:1904:9:1904:13 | S3(...) | | main.rs:1860:5:1860:22 | S3 |
3209-
| main.rs:1904:9:1904:13 | S3(...) | | main.rs:1903:43:1903:57 | ImplTraitTypeRepr |
3216+
| main.rs:1904:9:1904:13 | S3(...) | | main.rs:1882:5:1884:5 | trait MyTrait |
3217+
| main.rs:1904:9:1904:13 | S3(...) | A | main.rs:1903:24:1903:31 | T |
32103218
| main.rs:1904:9:1904:13 | S3(...) | T3 | main.rs:1903:24:1903:31 | T |
32113219
| main.rs:1904:12:1904:12 | x | | main.rs:1903:24:1903:31 | T |
32123220
| main.rs:1907:41:1907:41 | t | | main.rs:1907:26:1907:38 | B |
@@ -3217,26 +3225,37 @@ inferType
32173225
| main.rs:1911:51:1913:5 | { ... } | | main.rs:1911:23:1911:23 | A |
32183226
| main.rs:1912:9:1912:9 | t | | main.rs:1911:29:1911:43 | ImplTraitTypeRepr |
32193227
| main.rs:1912:9:1912:17 | t.get_a() | | main.rs:1911:23:1911:23 | A |
3220-
| main.rs:1916:13:1916:13 | x | | main.rs:1878:16:1878:35 | ImplTraitTypeRepr |
3221-
| main.rs:1916:17:1916:20 | f1(...) | | main.rs:1878:16:1878:35 | ImplTraitTypeRepr |
3222-
| main.rs:1917:9:1917:9 | x | | main.rs:1878:16:1878:35 | ImplTraitTypeRepr |
3223-
| main.rs:1918:9:1918:9 | x | | main.rs:1878:16:1878:35 | ImplTraitTypeRepr |
3224-
| main.rs:1919:13:1919:13 | a | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3225-
| main.rs:1919:17:1919:32 | get_a_my_trait(...) | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3228+
| main.rs:1916:13:1916:13 | x | | main.rs:1862:5:1864:5 | trait Trait1 |
3229+
| main.rs:1916:13:1916:13 | x | | main.rs:1866:5:1868:5 | trait Trait2 |
3230+
| main.rs:1916:17:1916:20 | f1(...) | | main.rs:1862:5:1864:5 | trait Trait1 |
3231+
| main.rs:1916:17:1916:20 | f1(...) | | main.rs:1866:5:1868:5 | trait Trait2 |
3232+
| main.rs:1917:9:1917:9 | x | | main.rs:1862:5:1864:5 | trait Trait1 |
3233+
| main.rs:1917:9:1917:9 | x | | main.rs:1866:5:1868:5 | trait Trait2 |
3234+
| main.rs:1918:9:1918:9 | x | | main.rs:1862:5:1864:5 | trait Trait1 |
3235+
| main.rs:1918:9:1918:9 | x | | main.rs:1866:5:1868:5 | trait Trait2 |
3236+
| main.rs:1919:13:1919:13 | a | | main.rs:1882:5:1884:5 | trait MyTrait |
3237+
| main.rs:1919:13:1919:13 | a | A | main.rs:1859:5:1859:14 | S2 |
3238+
| main.rs:1919:17:1919:32 | get_a_my_trait(...) | | main.rs:1882:5:1884:5 | trait MyTrait |
3239+
| main.rs:1919:17:1919:32 | get_a_my_trait(...) | A | main.rs:1859:5:1859:14 | S2 |
32263240
| main.rs:1920:13:1920:13 | b | | main.rs:1859:5:1859:14 | S2 |
32273241
| main.rs:1920:17:1920:33 | uses_my_trait1(...) | | main.rs:1859:5:1859:14 | S2 |
3228-
| main.rs:1920:32:1920:32 | a | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3229-
| main.rs:1921:13:1921:13 | a | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3230-
| main.rs:1921:17:1921:32 | get_a_my_trait(...) | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3242+
| main.rs:1920:32:1920:32 | a | | main.rs:1882:5:1884:5 | trait MyTrait |
3243+
| main.rs:1920:32:1920:32 | a | A | main.rs:1859:5:1859:14 | S2 |
3244+
| main.rs:1921:13:1921:13 | a | | main.rs:1882:5:1884:5 | trait MyTrait |
3245+
| main.rs:1921:13:1921:13 | a | A | main.rs:1859:5:1859:14 | S2 |
3246+
| main.rs:1921:17:1921:32 | get_a_my_trait(...) | | main.rs:1882:5:1884:5 | trait MyTrait |
3247+
| main.rs:1921:17:1921:32 | get_a_my_trait(...) | A | main.rs:1859:5:1859:14 | S2 |
32313248
| main.rs:1922:13:1922:13 | c | | main.rs:1859:5:1859:14 | S2 |
32323249
| main.rs:1922:17:1922:33 | uses_my_trait2(...) | | main.rs:1859:5:1859:14 | S2 |
3233-
| main.rs:1922:32:1922:32 | a | | main.rs:1899:28:1899:43 | ImplTraitTypeRepr |
3250+
| main.rs:1922:32:1922:32 | a | | main.rs:1882:5:1884:5 | trait MyTrait |
3251+
| main.rs:1922:32:1922:32 | a | A | main.rs:1859:5:1859:14 | S2 |
32343252
| main.rs:1923:13:1923:13 | d | | main.rs:1859:5:1859:14 | S2 |
32353253
| main.rs:1923:17:1923:34 | uses_my_trait2(...) | | main.rs:1859:5:1859:14 | S2 |
32363254
| main.rs:1923:32:1923:33 | S1 | | main.rs:1857:5:1858:14 | S1 |
3237-
| main.rs:1924:13:1924:13 | e | | main.rs:1903:24:1903:31 | T |
3238-
| main.rs:1924:17:1924:35 | get_a_my_trait2(...) | | main.rs:1903:43:1903:57 | ImplTraitTypeRepr |
3239-
| main.rs:1924:17:1924:43 | ... .get_a() | | main.rs:1903:24:1903:31 | T |
3255+
| main.rs:1924:13:1924:13 | e | | main.rs:1857:5:1858:14 | S1 |
3256+
| main.rs:1924:17:1924:35 | get_a_my_trait2(...) | | main.rs:1882:5:1884:5 | trait MyTrait |
3257+
| main.rs:1924:17:1924:35 | get_a_my_trait2(...) | A | main.rs:1857:5:1858:14 | S1 |
3258+
| main.rs:1924:17:1924:43 | ... .get_a() | | main.rs:1857:5:1858:14 | S1 |
32403259
| main.rs:1924:33:1924:34 | S1 | | main.rs:1857:5:1858:14 | S1 |
32413260
| main.rs:1935:16:1935:20 | SelfParam | | file://:0:0:0:0 | & |
32423261
| main.rs:1935:16:1935:20 | SelfParam | &T | main.rs:1931:5:1932:13 | S |

0 commit comments

Comments
 (0)