Skip to content

Commit 466bf85

Browse files
committed
Rust: Fix type inference for trait objects for traits with associated types
1 parent 1b2f160 commit 466bf85

File tree

5 files changed

+69
-28
lines changed

5 files changed

+69
-28
lines changed

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

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ private import codeql.rust.internal.CachedStages
77
private import codeql.rust.elements.internal.generated.Raw
88
private import codeql.rust.elements.internal.generated.Synth
99

10+
/** Holds if a dyn trait type should have a type parameter associated with `n`. */
11+
predicate dynTraitTypeParameter(Trait trait, AstNode n) {
12+
trait = any(DynTraitTypeRepr dt).getTrait() and
13+
(
14+
n = trait.getGenericParamList().getATypeParam() or
15+
n = trait.(TraitItemNode).getAnAssocItem().(TypeAlias)
16+
)
17+
}
18+
1019
cached
1120
newtype TType =
1221
TTuple(int arity) {
@@ -30,9 +39,7 @@ newtype TType =
3039
TTypeParamTypeParameter(TypeParam t) or
3140
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
3241
TArrayTypeParameter() or
33-
TDynTraitTypeParameter(TypeParam tp) {
34-
tp = any(DynTraitTypeRepr dt).getTrait().getGenericParamList().getATypeParam()
35-
} or
42+
TDynTraitTypeParameter(AstNode n) { dynTraitTypeParameter(_, n) } or
3643
TRefTypeParameter() or
3744
TSelfTypeParameter(Trait t) or
3845
TSliceTypeParameter()
@@ -406,15 +413,35 @@ class ArrayTypeParameter extends TypeParameter, TArrayTypeParameter {
406413
}
407414

408415
class DynTraitTypeParameter extends TypeParameter, TDynTraitTypeParameter {
409-
private TypeParam typeParam;
416+
private AstNode n;
410417

411-
DynTraitTypeParameter() { this = TDynTraitTypeParameter(typeParam) }
418+
DynTraitTypeParameter() { this = TDynTraitTypeParameter(n) }
412419

413-
TypeParam getTypeParam() { result = typeParam }
420+
Trait getTrait() { dynTraitTypeParameter(result, n) }
414421

415-
override string toString() { result = "dyn(" + typeParam.toString() + ")" }
422+
/** Gets the dyn trait type that this type parameter belongs to. */
423+
DynTraitType getDynTraitType() { result.getTrait() = this.getTrait() }
416424

417-
override Location getLocation() { result = typeParam.getLocation() }
425+
/** Gets the `TypeParam` of this dyn trait type parameter, if any. */
426+
TypeParam getTypeParam() { result = n }
427+
428+
/** Gets the `TypeAlias` of this dyn trait type parameter, if any. */
429+
TypeAlias getTypeAlias() { result = n }
430+
431+
/** Gets the trait type parameter that this dyn trait type parameter corresponds to. */
432+
TypeParameter getTraitTypeParameter() {
433+
result.(TypeParamTypeParameter).getTypeParam() = n
434+
or
435+
result.(AssociatedTypeTypeParameter).getTypeAlias() = n
436+
}
437+
438+
private string toStringInner() {
439+
result = [this.getTypeParam().toString(), this.getTypeAlias().getName().toString()]
440+
}
441+
442+
override string toString() { result = "dyn(" + this.toStringInner() + ")" }
443+
444+
override Location getLocation() { result = n.getLocation() }
418445
}
419446

420447
/** An implicit reference type parameter. */
@@ -503,8 +530,7 @@ final class ImplTypeAbstraction extends TypeAbstraction, Impl {
503530

504531
final class DynTypeAbstraction extends TypeAbstraction, DynTraitTypeRepr {
505532
override TypeParameter getATypeParameter() {
506-
result.(TypeParamTypeParameter).getTypeParam() =
507-
this.getTrait().getGenericParamList().getATypeParam()
533+
result = any(DynTraitTypeParameter tp | tp.getTrait() = this.getTrait()).getTraitTypeParameter()
508534
}
509535
}
510536

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ private module Input1 implements InputSig1<Location> {
9797
id = 2
9898
or
9999
kind = 1 and
100-
id = idOfTypeParameterAstNode(tp0.(DynTraitTypeParameter).getTypeParam())
100+
id =
101+
idOfTypeParameterAstNode([
102+
tp0.(DynTraitTypeParameter).getTypeParam().(AstNode),
103+
tp0.(DynTraitTypeParameter).getTypeAlias()
104+
])
101105
or
102106
kind = 2 and
103107
exists(AstNode node | id = idOfTypeParameterAstNode(node) |

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@ class DynTraitTypeReprMention extends TypeMention instanceof DynTraitTypeRepr {
324324
result = dynType
325325
or
326326
exists(DynTraitTypeParameter tp, TypePath path0, TypePath suffix |
327-
tp = dynType.getTypeParameter(_) and
327+
dynType = tp.getDynTraitType() and
328328
path = TypePath::cons(tp, suffix) and
329329
result = super.getTypeBoundList().getBound(0).getTypeRepr().(TypeMention).resolveTypeAt(path0) and
330-
path0.isCons(TTypeParamTypeParameter(tp.getTypeParam()), suffix)
330+
path0.isCons(tp.getTraitTypeParameter(), suffix)
331331
)
332332
}
333333
}
@@ -363,10 +363,10 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
363363
path.isEmpty() and
364364
result.(DynTraitType).getTrait() = trait
365365
or
366-
exists(TypeParam param |
367-
param = trait.getGenericParamList().getATypeParam() and
368-
path = TypePath::singleton(TDynTraitTypeParameter(param)) and
369-
result = TTypeParamTypeParameter(param)
366+
exists(DynTraitTypeParameter tp |
367+
trait = tp.getTrait() and
368+
path = TypePath::singleton(tp) and
369+
result = tp.getTraitTypeParameter()
370370
)
371371
}
372372
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,15 @@ fn assoc_get<A, B, T: AssocTrait<A, AP = B> + ?Sized>(a: &T) -> (A, B) {
8686
fn test_assoc_type(obj: &dyn AssocTrait<i64, AP = bool>) {
8787
let (
8888
_gp, // $ type=_gp:i64
89-
_ap, // $ MISSING: type=_ap:bool
89+
_ap, // $ type=_ap:bool
9090
) = (*obj).get(); // $ target=deref target=AssocTrait::get
9191
let (
9292
_gp, // $ type=_gp:i64
93-
_ap, // $ MISSING: type=_ap:bool
93+
_ap, // $ type=_ap:bool
9494
) = assoc_dyn_get(obj); // $ target=assoc_dyn_get
9595
let (
9696
_gp, // $ type=_gp:i64
97-
_ap, // $ MISSING: type=_ap:bool
97+
_ap, // $ type=_ap:bool
9898
) = assoc_get(obj); // $ target=assoc_get
9999
}
100100

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,17 @@ inferType
271271
| dyn_type.rs:75:21:75:23 | obj | T.dyn(A) | {EXTERNAL LOCATION} | bool |
272272
| dyn_type.rs:78:24:78:24 | a | | file://:0:0:0:0 | & |
273273
| dyn_type.rs:78:24:78:24 | a | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
274+
| dyn_type.rs:78:24:78:24 | a | &T.dyn(AP) | dyn_type.rs:78:21:78:21 | B |
274275
| dyn_type.rs:78:24:78:24 | a | &T.dyn(GP) | dyn_type.rs:78:18:78:18 | A |
275276
| dyn_type.rs:78:65:80:1 | { ... } | | file://:0:0:0:0 | (T_2) |
276277
| dyn_type.rs:78:65:80:1 | { ... } | 0(2) | dyn_type.rs:78:18:78:18 | A |
277-
| dyn_type.rs:78:65:80:1 | { ... } | 1(2) | dyn_type.rs:16:5:16:12 | AP |
278278
| dyn_type.rs:78:65:80:1 | { ... } | 1(2) | dyn_type.rs:78:21:78:21 | B |
279279
| dyn_type.rs:79:5:79:5 | a | | file://:0:0:0:0 | & |
280280
| dyn_type.rs:79:5:79:5 | a | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
281+
| dyn_type.rs:79:5:79:5 | a | &T.dyn(AP) | dyn_type.rs:78:21:78:21 | B |
281282
| dyn_type.rs:79:5:79:5 | a | &T.dyn(GP) | dyn_type.rs:78:18:78:18 | A |
282283
| dyn_type.rs:79:5:79:11 | a.get() | | file://:0:0:0:0 | (T_2) |
283284
| dyn_type.rs:79:5:79:11 | a.get() | 0(2) | dyn_type.rs:78:18:78:18 | A |
284-
| dyn_type.rs:79:5:79:11 | a.get() | 1(2) | dyn_type.rs:16:5:16:12 | AP |
285285
| dyn_type.rs:79:5:79:11 | a.get() | 1(2) | dyn_type.rs:78:21:78:21 | B |
286286
| dyn_type.rs:82:55:82:55 | a | | file://:0:0:0:0 | & |
287287
| dyn_type.rs:82:55:82:55 | a | &T | dyn_type.rs:82:20:82:52 | T |
@@ -295,40 +295,49 @@ inferType
295295
| dyn_type.rs:83:5:83:11 | a.get() | 1(2) | dyn_type.rs:82:17:82:17 | B |
296296
| dyn_type.rs:86:20:86:22 | obj | | file://:0:0:0:0 | & |
297297
| dyn_type.rs:86:20:86:22 | obj | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
298+
| dyn_type.rs:86:20:86:22 | obj | &T.dyn(AP) | {EXTERNAL LOCATION} | bool |
298299
| dyn_type.rs:86:20:86:22 | obj | &T.dyn(GP) | {EXTERNAL LOCATION} | i64 |
299300
| dyn_type.rs:87:9:90:5 | TuplePat | | file://:0:0:0:0 | (T_2) |
300301
| dyn_type.rs:87:9:90:5 | TuplePat | 0(2) | {EXTERNAL LOCATION} | i64 |
301-
| dyn_type.rs:87:9:90:5 | TuplePat | 1(2) | dyn_type.rs:16:5:16:12 | AP |
302+
| dyn_type.rs:87:9:90:5 | TuplePat | 1(2) | {EXTERNAL LOCATION} | bool |
302303
| dyn_type.rs:88:9:88:11 | _gp | | {EXTERNAL LOCATION} | i64 |
303-
| dyn_type.rs:89:9:89:11 | _ap | | dyn_type.rs:16:5:16:12 | AP |
304+
| dyn_type.rs:89:9:89:11 | _ap | | {EXTERNAL LOCATION} | bool |
304305
| dyn_type.rs:90:9:90:14 | (...) | | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
306+
| dyn_type.rs:90:9:90:14 | (...) | dyn(AP) | {EXTERNAL LOCATION} | bool |
305307
| dyn_type.rs:90:9:90:14 | (...) | dyn(GP) | {EXTERNAL LOCATION} | i64 |
306308
| dyn_type.rs:90:9:90:20 | ... .get() | | file://:0:0:0:0 | (T_2) |
307309
| dyn_type.rs:90:9:90:20 | ... .get() | 0(2) | {EXTERNAL LOCATION} | i64 |
308-
| dyn_type.rs:90:9:90:20 | ... .get() | 1(2) | dyn_type.rs:16:5:16:12 | AP |
310+
| dyn_type.rs:90:9:90:20 | ... .get() | 1(2) | {EXTERNAL LOCATION} | bool |
309311
| dyn_type.rs:90:10:90:13 | * ... | | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
312+
| dyn_type.rs:90:10:90:13 | * ... | dyn(AP) | {EXTERNAL LOCATION} | bool |
310313
| dyn_type.rs:90:10:90:13 | * ... | dyn(GP) | {EXTERNAL LOCATION} | i64 |
311314
| dyn_type.rs:90:11:90:13 | obj | | file://:0:0:0:0 | & |
312315
| dyn_type.rs:90:11:90:13 | obj | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
316+
| dyn_type.rs:90:11:90:13 | obj | &T.dyn(AP) | {EXTERNAL LOCATION} | bool |
313317
| dyn_type.rs:90:11:90:13 | obj | &T.dyn(GP) | {EXTERNAL LOCATION} | i64 |
314318
| dyn_type.rs:91:9:94:5 | TuplePat | | file://:0:0:0:0 | (T_2) |
315319
| dyn_type.rs:91:9:94:5 | TuplePat | 0(2) | {EXTERNAL LOCATION} | i64 |
320+
| dyn_type.rs:91:9:94:5 | TuplePat | 1(2) | {EXTERNAL LOCATION} | bool |
316321
| dyn_type.rs:92:9:92:11 | _gp | | {EXTERNAL LOCATION} | i64 |
322+
| dyn_type.rs:93:9:93:11 | _ap | | {EXTERNAL LOCATION} | bool |
317323
| dyn_type.rs:94:9:94:26 | assoc_dyn_get(...) | | file://:0:0:0:0 | (T_2) |
318324
| dyn_type.rs:94:9:94:26 | assoc_dyn_get(...) | 0(2) | {EXTERNAL LOCATION} | i64 |
325+
| dyn_type.rs:94:9:94:26 | assoc_dyn_get(...) | 1(2) | {EXTERNAL LOCATION} | bool |
319326
| dyn_type.rs:94:23:94:25 | obj | | file://:0:0:0:0 | & |
320327
| dyn_type.rs:94:23:94:25 | obj | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
328+
| dyn_type.rs:94:23:94:25 | obj | &T.dyn(AP) | {EXTERNAL LOCATION} | bool |
321329
| dyn_type.rs:94:23:94:25 | obj | &T.dyn(GP) | {EXTERNAL LOCATION} | i64 |
322330
| dyn_type.rs:95:9:98:5 | TuplePat | | file://:0:0:0:0 | (T_2) |
323331
| dyn_type.rs:95:9:98:5 | TuplePat | 0(2) | {EXTERNAL LOCATION} | i64 |
324-
| dyn_type.rs:95:9:98:5 | TuplePat | 1(2) | dyn_type.rs:16:5:16:12 | AP |
332+
| dyn_type.rs:95:9:98:5 | TuplePat | 1(2) | {EXTERNAL LOCATION} | bool |
325333
| dyn_type.rs:96:9:96:11 | _gp | | {EXTERNAL LOCATION} | i64 |
326-
| dyn_type.rs:97:9:97:11 | _ap | | dyn_type.rs:16:5:16:12 | AP |
334+
| dyn_type.rs:97:9:97:11 | _ap | | {EXTERNAL LOCATION} | bool |
327335
| dyn_type.rs:98:9:98:22 | assoc_get(...) | | file://:0:0:0:0 | (T_2) |
328336
| dyn_type.rs:98:9:98:22 | assoc_get(...) | 0(2) | {EXTERNAL LOCATION} | i64 |
329-
| dyn_type.rs:98:9:98:22 | assoc_get(...) | 1(2) | dyn_type.rs:16:5:16:12 | AP |
337+
| dyn_type.rs:98:9:98:22 | assoc_get(...) | 1(2) | {EXTERNAL LOCATION} | bool |
330338
| dyn_type.rs:98:19:98:21 | obj | | file://:0:0:0:0 | & |
331339
| dyn_type.rs:98:19:98:21 | obj | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
340+
| dyn_type.rs:98:19:98:21 | obj | &T.dyn(AP) | {EXTERNAL LOCATION} | bool |
332341
| dyn_type.rs:98:19:98:21 | obj | &T.dyn(GP) | {EXTERNAL LOCATION} | i64 |
333342
| dyn_type.rs:102:26:102:48 | &... | | file://:0:0:0:0 | & |
334343
| dyn_type.rs:102:26:102:48 | &... | &T | dyn_type.rs:5:1:8:1 | dyn MyTrait1 |
@@ -349,10 +358,12 @@ inferType
349358
| dyn_type.rs:107:21:107:45 | &... | &T | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
350359
| dyn_type.rs:107:21:107:45 | &... | &T | dyn_type.rs:33:1:36:1 | GenStruct |
351360
| dyn_type.rs:107:21:107:45 | &... | &T.A | {EXTERNAL LOCATION} | i32 |
361+
| dyn_type.rs:107:21:107:45 | &... | &T.dyn(AP) | {EXTERNAL LOCATION} | bool |
352362
| dyn_type.rs:107:21:107:45 | &... | &T.dyn(GP) | {EXTERNAL LOCATION} | i64 |
353363
| dyn_type.rs:107:22:107:45 | GenStruct {...} | | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
354364
| dyn_type.rs:107:22:107:45 | GenStruct {...} | | dyn_type.rs:33:1:36:1 | GenStruct |
355365
| dyn_type.rs:107:22:107:45 | GenStruct {...} | A | {EXTERNAL LOCATION} | i32 |
366+
| dyn_type.rs:107:22:107:45 | GenStruct {...} | dyn(AP) | {EXTERNAL LOCATION} | bool |
356367
| dyn_type.rs:107:22:107:45 | GenStruct {...} | dyn(GP) | {EXTERNAL LOCATION} | i64 |
357368
| dyn_type.rs:107:41:107:43 | 100 | | {EXTERNAL LOCATION} | i32 |
358369
| loop/main.rs:7:12:7:15 | SelfParam | | loop/main.rs:6:1:8:1 | Self [trait T1] |

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy