Skip to content

Commit c52709a

Browse files
authored
Merge pull request #20516 from hvitved/rust/type-inference-union-pointer-never
Rust: Model union, never, and pointer types
2 parents 6678e79 + 7a74efc commit c52709a

File tree

8 files changed

+105
-3
lines changed

8 files changed

+105
-3
lines changed

rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ module Impl {
2121
* ```
2222
*/
2323
class Union extends Generated::Union {
24+
/** Gets the struct field named `name`, if any. */
25+
pragma[nomagic]
26+
StructField getStructField(string name) {
27+
result = this.getStructFieldList().getAField() and
28+
result.getName().getText() = name
29+
}
30+
2431
override string toStringImpl() { result = "union " + this.getName().getText() }
2532
}
2633
}

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

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ newtype TType =
4242
TStruct(Struct s) or
4343
TEnum(Enum e) or
4444
TTrait(Trait t) or
45+
TUnion(Union u) or
4546
TArrayType() or // todo: add size?
4647
TRefType() or // todo: add mut?
4748
TImplTraitType(ImplTraitTypeRepr impl) or
4849
TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or
4950
TSliceType() or
51+
TNeverType() or
52+
TPtrType() or
5053
TTupleTypeParameter(int arity, int i) { exists(TTuple(arity)) and i in [0 .. arity - 1] } or
5154
TTypeParamTypeParameter(TypeParam t) or
5255
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
@@ -57,7 +60,8 @@ newtype TType =
5760
} or
5861
TRefTypeParameter() or
5962
TSelfTypeParameter(Trait t) or
60-
TSliceTypeParameter()
63+
TSliceTypeParameter() or
64+
TPtrTypeParameter()
6165

6266
private predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) {
6367
implTrait.isInReturnPos() and
@@ -224,6 +228,31 @@ class TraitType extends Type, TTrait {
224228
override Location getLocation() { result = trait.getLocation() }
225229
}
226230

231+
/** A union type. */
232+
class UnionType extends StructOrEnumType, TUnion {
233+
private Union union;
234+
235+
UnionType() { this = TUnion(union) }
236+
237+
override ItemNode asItemNode() { result = union }
238+
239+
override StructField getStructField(string name) { result = union.getStructField(name) }
240+
241+
override TupleField getTupleField(int i) { none() }
242+
243+
override TypeParameter getPositionalTypeParameter(int i) {
244+
result = TTypeParamTypeParameter(union.getGenericParamList().getTypeParam(i))
245+
}
246+
247+
override TypeMention getTypeParameterDefault(int i) {
248+
result = union.getGenericParamList().getTypeParam(i).getDefaultType()
249+
}
250+
251+
override string toString() { result = union.getName().getText() }
252+
253+
override Location getLocation() { result = union.getLocation() }
254+
}
255+
227256
/**
228257
* An array type.
229258
*
@@ -374,6 +403,33 @@ class SliceType extends Type, TSliceType {
374403
override Location getLocation() { result instanceof EmptyLocation }
375404
}
376405

406+
class NeverType extends Type, TNeverType {
407+
override StructField getStructField(string name) { none() }
408+
409+
override TupleField getTupleField(int i) { none() }
410+
411+
override TypeParameter getPositionalTypeParameter(int i) { none() }
412+
413+
override string toString() { result = "!" }
414+
415+
override Location getLocation() { result instanceof EmptyLocation }
416+
}
417+
418+
class PtrType extends Type, TPtrType {
419+
override StructField getStructField(string name) { none() }
420+
421+
override TupleField getTupleField(int i) { none() }
422+
423+
override TypeParameter getPositionalTypeParameter(int i) {
424+
i = 0 and
425+
result = TPtrTypeParameter()
426+
}
427+
428+
override string toString() { result = "*" }
429+
430+
override Location getLocation() { result instanceof EmptyLocation }
431+
}
432+
377433
/** A type parameter. */
378434
abstract class TypeParameter extends Type {
379435
override StructField getStructField(string name) { none() }
@@ -529,6 +585,12 @@ class SliceTypeParameter extends TypeParameter, TSliceTypeParameter {
529585
override Location getLocation() { result instanceof EmptyLocation }
530586
}
531587

588+
class PtrTypeParameter extends TypeParameter, TPtrTypeParameter {
589+
override string toString() { result = "*T" }
590+
591+
override Location getLocation() { result instanceof EmptyLocation }
592+
}
593+
532594
/**
533595
* The implicit `Self` type parameter of a trait, that refers to the
534596
* implementing type of the trait.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ private module Input1 implements InputSig1<Location> {
9999
id1 = 0 and
100100
id2 = 2
101101
or
102+
tp0 instanceof PtrTypeParameter and
103+
kind = 0 and
104+
id1 = 0 and
105+
id2 = 3
106+
or
102107
kind = 1 and
103108
id1 = 0 and
104109
id2 =

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ class NonAliasPathTypeMention extends PathTypeMention {
241241
else result = TTrait(trait)
242242
)
243243
or
244+
result = TUnion(resolved)
245+
or
244246
result = TTypeParamTypeParameter(resolved)
245247
or
246248
result = TAssociatedTypeTypeParameter(resolved)
@@ -387,3 +389,19 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
387389
)
388390
}
389391
}
392+
393+
class NeverTypeReprMention extends TypeMention, NeverTypeRepr {
394+
override Type resolveTypeAt(TypePath path) { result = TNeverType() and path.isEmpty() }
395+
}
396+
397+
class PtrTypeReprMention extends TypeMention instanceof PtrTypeRepr {
398+
override Type resolveTypeAt(TypePath path) {
399+
path.isEmpty() and
400+
result = TPtrType()
401+
or
402+
exists(TypePath suffix |
403+
result = super.getTypeRepr().(TypeMention).resolveTypeAt(suffix) and
404+
path = TypePath::cons(TPtrTypeParameter(), suffix)
405+
)
406+
}
407+
}

rust/ql/test/extractor-tests/macro-expansion/CONSISTENCY/TypeInferenceConsistency.expected

Lines changed: 0 additions & 2 deletions
This file was deleted.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,7 @@ inferType
22502250
| main.rs:1127:43:1127:82 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
22512251
| main.rs:1127:50:1127:81 | "PairNone has no second elemen... | | file://:0:0:0:0 | & |
22522252
| main.rs:1127:50:1127:81 | "PairNone has no second elemen... | &T | {EXTERNAL LOCATION} | str |
2253+
| main.rs:1127:50:1127:81 | ...::panic_fmt(...) | | file://:0:0:0:0 | ! |
22532254
| main.rs:1127:50:1127:81 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
22542255
| main.rs:1127:50:1127:81 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
22552256
| main.rs:1127:50:1127:81 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
@@ -2261,6 +2262,7 @@ inferType
22612262
| main.rs:1128:43:1128:81 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
22622263
| main.rs:1128:50:1128:80 | "PairFst has no second element... | | file://:0:0:0:0 | & |
22632264
| main.rs:1128:50:1128:80 | "PairFst has no second element... | &T | {EXTERNAL LOCATION} | str |
2265+
| main.rs:1128:50:1128:80 | ...::panic_fmt(...) | | file://:0:0:0:0 | ! |
22642266
| main.rs:1128:50:1128:80 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
22652267
| main.rs:1128:50:1128:80 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
22662268
| main.rs:1128:50:1128:80 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
multipleCallTargets
2+
| test.rs:117:9:117:20 | ptr.is_null() |
3+
| test.rs:117:9:117:21 | ptr.is_null() |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
multipleCallTargets
2+
| main.rs:242:44:242:78 | ... .cast() |
3+
| main.rs:245:44:245:78 | ... .cast() |
4+
| main.rs:248:44:248:78 | ... .cast() |
5+
| main.rs:251:14:251:48 | ... .cast() |
6+
| main.rs:254:14:254:48 | ... .cast() |
7+
| main.rs:257:14:257:48 | ... .cast() |

0 commit comments

Comments
 (0)