Skip to content

Commit edf6c7f

Browse files
committed
Rust: Handle (Enum::)Variant::<TypeArg> type mentions
1 parent a96d3d7 commit edf6c7f

File tree

4 files changed

+32
-25
lines changed

4 files changed

+32
-25
lines changed

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

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,7 @@ private module StructExprMatchingInput implements MatchingInputSig {
509509
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
510510
// `Foo<Bar>::Variant { ... }`.
511511
apos.isStructPos() and
512-
exists(Path p, TypeMention tm |
513-
p = this.getPath() and
514-
if resolvePath(p) instanceof Variant then tm = p.getQualifier() else tm = p
515-
|
516-
result = tm.resolveTypeAt(path)
517-
)
512+
result = this.getPath().(TypeMention).resolveTypeAt(path)
518513
}
519514

520515
Declaration getTarget() { result = resolvePath(this.getPath()) }
@@ -1242,12 +1237,7 @@ private module StructPatMatchingInput implements MatchingInputSig {
12421237
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
12431238
// `let Foo<Bar>::Variant { ... } = ...`.
12441239
apos.isStructPos() and
1245-
exists(Path p, TypeMention tm |
1246-
p = this.getPath() and
1247-
if resolvePath(p) instanceof Variant then tm = p.getQualifier() else tm = p
1248-
|
1249-
result = tm.resolveTypeAt(path)
1250-
)
1240+
result = this.getPath().(TypeMention).resolveTypeAt(path)
12511241
}
12521242

12531243
Declaration getTarget() { result = resolvePath(this.getPath()) }
@@ -1297,14 +1287,9 @@ private module TupleStructPatMatchingInput implements MatchingInputSig {
12971287
result = inferType(this.getNodeAt(apos), path)
12981288
or
12991289
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
1300-
// `let Option::<Foo>(x) = ...`.
1290+
// `let Option::<Foo>::Some(x) = ...`.
13011291
apos.isSelf() and
1302-
exists(Path p, TypeMention tm |
1303-
p = this.getPath() and
1304-
if resolvePath(p) instanceof Variant then tm = p.getQualifier() else tm = p
1305-
|
1306-
result = tm.resolveTypeAt(path)
1307-
)
1292+
result = this.getPath().(TypeMention).resolveTypeAt(path)
13081293
}
13091294

13101295
Declaration getTarget() { result = resolvePath(this.getPath()) }

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@ class SliceTypeReprMention extends TypeMention instanceof SliceTypeRepr {
5353
class PathTypeMention extends TypeMention, Path {
5454
TypeItemNode resolved;
5555

56-
PathTypeMention() { resolved = resolvePath(this) }
56+
PathTypeMention() {
57+
resolved = resolvePath(this)
58+
or
59+
resolved = resolvePath(this).(Variant).getEnum()
60+
}
5761

58-
ItemNode getResolved() { result = resolved }
62+
TypeItemNode getResolved() { result = resolved }
5963

6064
pragma[nomagic]
6165
private TypeAlias getResolvedTraitAlias(string name) {
@@ -99,6 +103,10 @@ class PathTypeMention extends TypeMention, Path {
99103
this = node.getASelfPath() and
100104
result = node.(ImplItemNode).getSelfPath().getSegment().getGenericArgList().getTypeArg(i)
101105
)
106+
or
107+
// `Option::<i32>::Some` is valid in addition to `Option::Some::<i32>`
108+
resolvePath(this) instanceof Variant and
109+
result = this.getQualifier().getSegment().getGenericArgList().getTypeArg(i)
102110
}
103111

104112
private TypeMention getPositionalTypeArgument(int i) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,18 +2462,18 @@ pub mod pattern_matching {
24622462
_ => (),
24632463
}
24642464

2465-
let opt1 = Some(Default::default()); // $ MISSING: type=opt1:T.i32 method=default
2465+
let opt1 = Some(Default::default()); // $ type=opt1:T.i32 method=default
24662466
#[rustfmt::skip]
24672467
let _ = if let Some::<i32>(x) = opt1
24682468
{
2469-
x; // $ MISSING: type=x:i32
2469+
x; // $ type=x:i32
24702470
};
24712471

2472-
let opt2 = Some(Default::default()); // $ MISSING: type=opt2:T.i32 method=default
2472+
let opt2 = Some(Default::default()); // $ type=opt2:T.i32 method=default
24732473
#[rustfmt::skip]
24742474
let _ = if let Option::Some::<i32>(x) = opt2
24752475
{
2476-
x; // $ MISSING: type=x:i32
2476+
x; // $ type=x:i32
24772477
};
24782478

24792479
let opt3 = Some(Default::default()); // $ type=opt3:T.i32 method=default

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4303,13 +4303,27 @@ inferType
43034303
| main.rs:2462:13:2462:13 | _ | T1.T2.&T | {EXTERNAL LOCATION} | str |
43044304
| main.rs:2462:13:2462:13 | _ | T2 | {EXTERNAL LOCATION} | bool |
43054305
| main.rs:2465:13:2465:16 | opt1 | | {EXTERNAL LOCATION} | Option |
4306+
| main.rs:2465:13:2465:16 | opt1 | T | {EXTERNAL LOCATION} | i32 |
43064307
| main.rs:2465:20:2465:43 | Some(...) | | {EXTERNAL LOCATION} | Option |
4308+
| main.rs:2465:20:2465:43 | Some(...) | T | {EXTERNAL LOCATION} | i32 |
4309+
| main.rs:2465:25:2465:42 | ...::default(...) | | {EXTERNAL LOCATION} | i32 |
43074310
| main.rs:2467:24:2467:37 | Some::<...>(...) | | {EXTERNAL LOCATION} | Option |
4311+
| main.rs:2467:24:2467:37 | Some::<...>(...) | T | {EXTERNAL LOCATION} | i32 |
4312+
| main.rs:2467:36:2467:36 | x | | {EXTERNAL LOCATION} | i32 |
43084313
| main.rs:2467:41:2467:44 | opt1 | | {EXTERNAL LOCATION} | Option |
4314+
| main.rs:2467:41:2467:44 | opt1 | T | {EXTERNAL LOCATION} | i32 |
4315+
| main.rs:2469:13:2469:13 | x | | {EXTERNAL LOCATION} | i32 |
43094316
| main.rs:2472:13:2472:16 | opt2 | | {EXTERNAL LOCATION} | Option |
4317+
| main.rs:2472:13:2472:16 | opt2 | T | {EXTERNAL LOCATION} | i32 |
43104318
| main.rs:2472:20:2472:43 | Some(...) | | {EXTERNAL LOCATION} | Option |
4319+
| main.rs:2472:20:2472:43 | Some(...) | T | {EXTERNAL LOCATION} | i32 |
4320+
| main.rs:2472:25:2472:42 | ...::default(...) | | {EXTERNAL LOCATION} | i32 |
43114321
| main.rs:2474:24:2474:45 | ...::Some::<...>(...) | | {EXTERNAL LOCATION} | Option |
4322+
| main.rs:2474:24:2474:45 | ...::Some::<...>(...) | T | {EXTERNAL LOCATION} | i32 |
4323+
| main.rs:2474:44:2474:44 | x | | {EXTERNAL LOCATION} | i32 |
43124324
| main.rs:2474:49:2474:52 | opt2 | | {EXTERNAL LOCATION} | Option |
4325+
| main.rs:2474:49:2474:52 | opt2 | T | {EXTERNAL LOCATION} | i32 |
4326+
| main.rs:2476:13:2476:13 | x | | {EXTERNAL LOCATION} | i32 |
43134327
| main.rs:2479:13:2479:16 | opt3 | | {EXTERNAL LOCATION} | Option |
43144328
| main.rs:2479:13:2479:16 | opt3 | T | {EXTERNAL LOCATION} | i32 |
43154329
| main.rs:2479:20:2479:43 | Some(...) | | {EXTERNAL LOCATION} | Option |

0 commit comments

Comments
 (0)