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)