Skip to content

Commit b09a778

Browse files
committed
Rust: Rework type inference for impl Trait in return position
1 parent 04bf2f5 commit b09a778

File tree

5 files changed

+79
-93
lines changed

5 files changed

+79
-93
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: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private module Input1 implements InputSig1<Location> {
100100
node = tp0.(TypeParamTypeParameter).getTypeParam() or
101101
node = tp0.(AssociatedTypeTypeParameter).getTypeAlias() or
102102
node = tp0.(SelfTypeParameter).getTrait() or
103-
node = tp0.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr()
103+
node = tp0.(ImplTraitArgumentType).getImplTraitTypeRepr()
104104
)
105105
|
106106
tp0 order by kind, id
@@ -131,11 +131,7 @@ private module Input2 implements InputSig2 {
131131
result = tp.(SelfTypeParameter).getTrait()
132132
or
133133
result =
134-
tp.(ImplTraitTypeTypeParameter)
135-
.getImplTraitTypeRepr()
136-
.getTypeBoundList()
137-
.getABound()
138-
.getTypeRepr()
134+
tp.(ImplTraitArgumentType).getImplTraitTypeRepr().getTypeBoundList().getABound().getTypeRepr()
139135
}
140136

141137
/**
@@ -612,7 +608,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
612608
)
613609
or
614610
ppos.isImplicit() and
615-
this = result.(ImplTraitTypeTypeParameter).getFunction()
611+
this = result.(ImplTraitArgumentType).getFunction()
616612
}
617613

618614
override Type getParameterType(DeclarationPosition dpos, TypePath path) {
@@ -1257,7 +1253,7 @@ private Function getTypeParameterMethod(TypeParameter tp, string name) {
12571253
or
12581254
result = getMethodSuccessor(tp.(SelfTypeParameter).getTrait(), name)
12591255
or
1260-
result = getMethodSuccessor(tp.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr(), name)
1256+
result = getMethodSuccessor(tp.(ImplTraitArgumentType).getImplTraitTypeRepr(), name)
12611257
}
12621258

12631259
pragma[nomagic]
@@ -1427,12 +1423,6 @@ private Function getMethodFromImpl(MethodCall mc) {
14271423
)
14281424
}
14291425

1430-
bindingset[trait, name]
1431-
pragma[inline_late]
1432-
private Function getTraitMethod(ImplTraitReturnType trait, string name) {
1433-
result = getMethodSuccessor(trait.getImplTraitTypeRepr(), name)
1434-
}
1435-
14361426
cached
14371427
private module Cached {
14381428
private import codeql.rust.internal.CachedStages
@@ -1461,6 +1451,12 @@ private module Cached {
14611451
)
14621452
}
14631453

1454+
bindingset[trait, name]
1455+
pragma[inline_late]
1456+
private Function getTraitMethod(TraitType trait, string name) {
1457+
result = getMethodSuccessor(trait.getTrait(), name)
1458+
}
1459+
14641460
/** Gets a method that the method call `mc` resolves to, if any. */
14651461
cached
14661462
Function resolveMethodCallTarget(MethodCall mc) {
@@ -1472,7 +1468,8 @@ private module Cached {
14721468
result = getTypeParameterMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName())
14731469
or
14741470
// The type of the receiver is an `impl Trait` type.
1475-
result = getTraitMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName())
1471+
result = getTraitMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName()) and
1472+
not exists(mc.getTrait())
14761473
}
14771474

14781475
pragma[inline]

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,13 @@ class PathTypeReprMention extends TypeMention, PathTypeRepr {
208208
class ImplTraitTypeReprMention extends TypeMention instanceof ImplTraitTypeRepr {
209209
override Type resolveTypeAt(TypePath typePath) {
210210
typePath.isEmpty() and
211-
result.(ImplTraitType).getImplTraitTypeRepr() = this
211+
result.(ImplTraitArgumentType).getImplTraitTypeRepr() = this
212+
or
213+
exists(Function f |
214+
this = f.getRetType().getTypeRepr() and
215+
result =
216+
super.getTypeBoundList().getABound().getTypeRepr().(TypeMention).resolveTypeAt(typePath)
217+
)
212218
}
213219
}
214220

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1911,7 +1911,7 @@ mod impl_trait {
19111911
let a = get_a_my_trait();
19121912
let c = uses_my_trait2(a); // $ type=c:S2
19131913
let d = uses_my_trait2(S1); // $ type=d:S2
1914-
let e = get_a_my_trait2(S1).get_a(); // $ method=MyTrait::get_a $ MISSING: type=e:S1
1914+
let e = get_a_my_trait2(S1).get_a(); // $ method=MyTrait::get_a $ type=e:S1
19151915
}
19161916
}
19171917

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

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,10 +2777,8 @@ inferType
27772777
| main.rs:1811:25:1813:5 | { ... } | | main.rs:1805:5:1805:14 | S1 |
27782778
| main.rs:1812:9:1812:10 | S1 | | main.rs:1805:5:1805:14 | S1 |
27792779
| main.rs:1815:41:1817:5 | { ... } | | {EXTERNAL LOCATION} | trait Future |
2780-
| main.rs:1815:41:1817:5 | { ... } | | main.rs:1815:16:1815:39 | ImplTraitTypeRepr |
27812780
| main.rs:1815:41:1817:5 | { ... } | Output | main.rs:1805:5:1805:14 | S1 |
27822781
| main.rs:1816:9:1816:20 | { ... } | | {EXTERNAL LOCATION} | trait Future |
2783-
| main.rs:1816:9:1816:20 | { ... } | | main.rs:1815:16:1815:39 | ImplTraitTypeRepr |
27842782
| main.rs:1816:9:1816:20 | { ... } | Output | main.rs:1805:5:1805:14 | S1 |
27852783
| main.rs:1816:17:1816:18 | S1 | | main.rs:1805:5:1805:14 | S1 |
27862784
| main.rs:1825:13:1825:42 | SelfParam | | {EXTERNAL LOCATION} | Pin |
@@ -2793,16 +2791,20 @@ inferType
27932791
| main.rs:1828:13:1828:38 | ...::Ready(...) | | {EXTERNAL LOCATION} | Poll |
27942792
| main.rs:1828:13:1828:38 | ...::Ready(...) | T | main.rs:1805:5:1805:14 | S1 |
27952793
| main.rs:1828:36:1828:37 | S1 | | main.rs:1805:5:1805:14 | S1 |
2794+
| main.rs:1832:41:1834:5 | { ... } | | {EXTERNAL LOCATION} | trait Future |
27962795
| main.rs:1832:41:1834:5 | { ... } | | main.rs:1819:5:1819:14 | S2 |
2797-
| main.rs:1832:41:1834:5 | { ... } | | main.rs:1832:16:1832:39 | ImplTraitTypeRepr |
2796+
| main.rs:1832:41:1834:5 | { ... } | Output | main.rs:1805:5:1805:14 | S1 |
2797+
| main.rs:1833:9:1833:10 | S2 | | {EXTERNAL LOCATION} | trait Future |
27982798
| main.rs:1833:9:1833:10 | S2 | | main.rs:1819:5:1819:14 | S2 |
2799-
| main.rs:1833:9:1833:10 | S2 | | main.rs:1832:16:1832:39 | ImplTraitTypeRepr |
2799+
| main.rs:1833:9:1833:10 | S2 | Output | main.rs:1805:5:1805:14 | S1 |
28002800
| main.rs:1837:9:1837:12 | f1(...) | | {EXTERNAL LOCATION} | trait Future |
28012801
| main.rs:1837:9:1837:12 | f1(...) | Output | main.rs:1805:5:1805:14 | S1 |
28022802
| main.rs:1837:9:1837:18 | await ... | | main.rs:1805:5:1805:14 | S1 |
2803-
| main.rs:1838:9:1838:12 | f2(...) | | main.rs:1815:16:1815:39 | ImplTraitTypeRepr |
2803+
| main.rs:1838:9:1838:12 | f2(...) | | {EXTERNAL LOCATION} | trait Future |
2804+
| main.rs:1838:9:1838:12 | f2(...) | Output | main.rs:1805:5:1805:14 | S1 |
28042805
| main.rs:1838:9:1838:18 | await ... | | main.rs:1805:5:1805:14 | S1 |
2805-
| main.rs:1839:9:1839:12 | f3(...) | | main.rs:1832:16:1832:39 | ImplTraitTypeRepr |
2806+
| main.rs:1839:9:1839:12 | f3(...) | | {EXTERNAL LOCATION} | trait Future |
2807+
| main.rs:1839:9:1839:12 | f3(...) | Output | main.rs:1805:5:1805:14 | S1 |
28062808
| main.rs:1839:9:1839:18 | await ... | | main.rs:1805:5:1805:14 | S1 |
28072809
| main.rs:1840:9:1840:10 | S2 | | main.rs:1819:5:1819:14 | S2 |
28082810
| main.rs:1840:9:1840:16 | await S2 | | main.rs:1805:5:1805:14 | S1 |
@@ -2823,9 +2825,11 @@ inferType
28232825
| main.rs:1865:15:1865:19 | SelfParam | | file://:0:0:0:0 | & |
28242826
| main.rs:1865:15:1865:19 | SelfParam | &T | main.rs:1847:5:1848:14 | S1 |
28252827
| main.rs:1868:37:1870:5 | { ... } | | main.rs:1847:5:1848:14 | S1 |
2826-
| main.rs:1868:37:1870:5 | { ... } | | main.rs:1868:16:1868:35 | ImplTraitTypeRepr |
2828+
| main.rs:1868:37:1870:5 | { ... } | | main.rs:1852:5:1854:5 | trait Trait1 |
2829+
| main.rs:1868:37:1870:5 | { ... } | | main.rs:1856:5:1858:5 | trait Trait2 |
28272830
| main.rs:1869:9:1869:10 | S1 | | main.rs:1847:5:1848:14 | S1 |
2828-
| main.rs:1869:9:1869:10 | S1 | | main.rs:1868:16:1868:35 | ImplTraitTypeRepr |
2831+
| main.rs:1869:9:1869:10 | S1 | | main.rs:1852:5:1854:5 | trait Trait1 |
2832+
| main.rs:1869:9:1869:10 | S1 | | main.rs:1856:5:1858:5 | trait Trait2 |
28292833
| main.rs:1873:18:1873:22 | SelfParam | | file://:0:0:0:0 | & |
28302834
| main.rs:1873:18:1873:22 | SelfParam | &T | main.rs:1872:5:1874:5 | Self [trait MyTrait] |
28312835
| main.rs:1877:18:1877:22 | SelfParam | | file://:0:0:0:0 | & |
@@ -2844,15 +2848,19 @@ inferType
28442848
| main.rs:1884:25:1884:28 | self | &T.T3 | main.rs:1882:10:1882:17 | T |
28452849
| main.rs:1885:13:1885:21 | t.clone() | | main.rs:1882:10:1882:17 | T |
28462850
| main.rs:1889:45:1891:5 | { ... } | | main.rs:1847:5:1848:14 | S1 |
2847-
| main.rs:1889:45:1891:5 | { ... } | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2851+
| main.rs:1889:45:1891:5 | { ... } | | main.rs:1872:5:1874:5 | trait MyTrait |
2852+
| main.rs:1889:45:1891:5 | { ... } | A | main.rs:1849:5:1849:14 | S2 |
28482853
| main.rs:1890:9:1890:10 | S1 | | main.rs:1847:5:1848:14 | S1 |
2849-
| main.rs:1890:9:1890:10 | S1 | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2854+
| main.rs:1890:9:1890:10 | S1 | | main.rs:1872:5:1874:5 | trait MyTrait |
2855+
| main.rs:1890:9:1890:10 | S1 | A | main.rs:1849:5:1849:14 | S2 |
28502856
| main.rs:1893:34:1893:34 | x | | main.rs:1893:24:1893:31 | T |
28512857
| main.rs:1893:59:1895:5 | { ... } | | main.rs:1850:5:1850:22 | S3 |
2852-
| main.rs:1893:59:1895:5 | { ... } | | main.rs:1893:43:1893:57 | ImplTraitTypeRepr |
2858+
| main.rs:1893:59:1895:5 | { ... } | | main.rs:1872:5:1874:5 | trait MyTrait |
2859+
| main.rs:1893:59:1895:5 | { ... } | A | main.rs:1893:24:1893:31 | T |
28532860
| main.rs:1893:59:1895:5 | { ... } | T3 | main.rs:1893:24:1893:31 | T |
28542861
| main.rs:1894:9:1894:13 | S3(...) | | main.rs:1850:5:1850:22 | S3 |
2855-
| main.rs:1894:9:1894:13 | S3(...) | | main.rs:1893:43:1893:57 | ImplTraitTypeRepr |
2862+
| main.rs:1894:9:1894:13 | S3(...) | | main.rs:1872:5:1874:5 | trait MyTrait |
2863+
| main.rs:1894:9:1894:13 | S3(...) | A | main.rs:1893:24:1893:31 | T |
28562864
| main.rs:1894:9:1894:13 | S3(...) | T3 | main.rs:1893:24:1893:31 | T |
28572865
| main.rs:1894:12:1894:12 | x | | main.rs:1893:24:1893:31 | T |
28582866
| main.rs:1897:41:1897:41 | t | | main.rs:1897:26:1897:38 | B |
@@ -2863,26 +2871,37 @@ inferType
28632871
| main.rs:1901:51:1903:5 | { ... } | | main.rs:1901:23:1901:23 | A |
28642872
| main.rs:1902:9:1902:9 | t | | main.rs:1901:29:1901:43 | ImplTraitTypeRepr |
28652873
| main.rs:1902:9:1902:17 | t.get_a() | | main.rs:1901:23:1901:23 | A |
2866-
| main.rs:1906:13:1906:13 | x | | main.rs:1868:16:1868:35 | ImplTraitTypeRepr |
2867-
| main.rs:1906:17:1906:20 | f1(...) | | main.rs:1868:16:1868:35 | ImplTraitTypeRepr |
2868-
| main.rs:1907:9:1907:9 | x | | main.rs:1868:16:1868:35 | ImplTraitTypeRepr |
2869-
| main.rs:1908:9:1908:9 | x | | main.rs:1868:16:1868:35 | ImplTraitTypeRepr |
2870-
| main.rs:1909:13:1909:13 | a | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2871-
| main.rs:1909:17:1909:32 | get_a_my_trait(...) | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2874+
| main.rs:1906:13:1906:13 | x | | main.rs:1852:5:1854:5 | trait Trait1 |
2875+
| main.rs:1906:13:1906:13 | x | | main.rs:1856:5:1858:5 | trait Trait2 |
2876+
| main.rs:1906:17:1906:20 | f1(...) | | main.rs:1852:5:1854:5 | trait Trait1 |
2877+
| main.rs:1906:17:1906:20 | f1(...) | | main.rs:1856:5:1858:5 | trait Trait2 |
2878+
| main.rs:1907:9:1907:9 | x | | main.rs:1852:5:1854:5 | trait Trait1 |
2879+
| main.rs:1907:9:1907:9 | x | | main.rs:1856:5:1858:5 | trait Trait2 |
2880+
| main.rs:1908:9:1908:9 | x | | main.rs:1852:5:1854:5 | trait Trait1 |
2881+
| main.rs:1908:9:1908:9 | x | | main.rs:1856:5:1858:5 | trait Trait2 |
2882+
| main.rs:1909:13:1909:13 | a | | main.rs:1872:5:1874:5 | trait MyTrait |
2883+
| main.rs:1909:13:1909:13 | a | A | main.rs:1849:5:1849:14 | S2 |
2884+
| main.rs:1909:17:1909:32 | get_a_my_trait(...) | | main.rs:1872:5:1874:5 | trait MyTrait |
2885+
| main.rs:1909:17:1909:32 | get_a_my_trait(...) | A | main.rs:1849:5:1849:14 | S2 |
28722886
| main.rs:1910:13:1910:13 | b | | main.rs:1849:5:1849:14 | S2 |
28732887
| main.rs:1910:17:1910:33 | uses_my_trait1(...) | | main.rs:1849:5:1849:14 | S2 |
2874-
| main.rs:1910:32:1910:32 | a | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2875-
| main.rs:1911:13:1911:13 | a | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2876-
| main.rs:1911:17:1911:32 | get_a_my_trait(...) | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2888+
| main.rs:1910:32:1910:32 | a | | main.rs:1872:5:1874:5 | trait MyTrait |
2889+
| main.rs:1910:32:1910:32 | a | A | main.rs:1849:5:1849:14 | S2 |
2890+
| main.rs:1911:13:1911:13 | a | | main.rs:1872:5:1874:5 | trait MyTrait |
2891+
| main.rs:1911:13:1911:13 | a | A | main.rs:1849:5:1849:14 | S2 |
2892+
| main.rs:1911:17:1911:32 | get_a_my_trait(...) | | main.rs:1872:5:1874:5 | trait MyTrait |
2893+
| main.rs:1911:17:1911:32 | get_a_my_trait(...) | A | main.rs:1849:5:1849:14 | S2 |
28772894
| main.rs:1912:13:1912:13 | c | | main.rs:1849:5:1849:14 | S2 |
28782895
| main.rs:1912:17:1912:33 | uses_my_trait2(...) | | main.rs:1849:5:1849:14 | S2 |
2879-
| main.rs:1912:32:1912:32 | a | | main.rs:1889:28:1889:43 | ImplTraitTypeRepr |
2896+
| main.rs:1912:32:1912:32 | a | | main.rs:1872:5:1874:5 | trait MyTrait |
2897+
| main.rs:1912:32:1912:32 | a | A | main.rs:1849:5:1849:14 | S2 |
28802898
| main.rs:1913:13:1913:13 | d | | main.rs:1849:5:1849:14 | S2 |
28812899
| main.rs:1913:17:1913:34 | uses_my_trait2(...) | | main.rs:1849:5:1849:14 | S2 |
28822900
| main.rs:1913:32:1913:33 | S1 | | main.rs:1847:5:1848:14 | S1 |
2883-
| main.rs:1914:13:1914:13 | e | | main.rs:1893:24:1893:31 | T |
2884-
| main.rs:1914:17:1914:35 | get_a_my_trait2(...) | | main.rs:1893:43:1893:57 | ImplTraitTypeRepr |
2885-
| main.rs:1914:17:1914:43 | ... .get_a() | | main.rs:1893:24:1893:31 | T |
2901+
| main.rs:1914:13:1914:13 | e | | main.rs:1847:5:1848:14 | S1 |
2902+
| main.rs:1914:17:1914:35 | get_a_my_trait2(...) | | main.rs:1872:5:1874:5 | trait MyTrait |
2903+
| main.rs:1914:17:1914:35 | get_a_my_trait2(...) | A | main.rs:1847:5:1848:14 | S1 |
2904+
| main.rs:1914:17:1914:43 | ... .get_a() | | main.rs:1847:5:1848:14 | S1 |
28862905
| main.rs:1914:33:1914:34 | S1 | | main.rs:1847:5:1848:14 | S1 |
28872906
| main.rs:1925:16:1925:20 | SelfParam | | file://:0:0:0:0 | & |
28882907
| main.rs:1925:16:1925:20 | SelfParam | &T | main.rs:1921:5:1922:13 | S |

0 commit comments

Comments
 (0)