Rust: Model union, never, and pointer types

This commit is contained in:
Tom Hvitved
2025-09-23 09:30:05 +02:00
parent 92cced201e
commit 2a814dd37c
8 changed files with 105 additions and 3 deletions

View File

@@ -21,6 +21,13 @@ module Impl {
* ```
*/
class Union extends Generated::Union {
/** Gets the record field named `name`, if any. */
pragma[nomagic]
StructField getStructField(string name) {
result = this.getStructFieldList().getAField() and
result.getName().getText() = name
}
override string toStringImpl() { result = "union " + this.getName().getText() }
}
}

View File

@@ -42,11 +42,14 @@ newtype TType =
TStruct(Struct s) or
TEnum(Enum e) or
TTrait(Trait t) or
TUnion(Union u) or
TArrayType() or // todo: add size?
TRefType() or // todo: add mut?
TImplTraitType(ImplTraitTypeRepr impl) or
TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or
TSliceType() or
TNeverType() or
TPtrType() or
TTupleTypeParameter(int arity, int i) { exists(TTuple(arity)) and i in [0 .. arity - 1] } or
TTypeParamTypeParameter(TypeParam t) or
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
@@ -57,7 +60,8 @@ newtype TType =
} or
TRefTypeParameter() or
TSelfTypeParameter(Trait t) or
TSliceTypeParameter()
TSliceTypeParameter() or
TPtrTypeParameter()
private predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) {
implTrait.isInReturnPos() and
@@ -224,6 +228,31 @@ class TraitType extends Type, TTrait {
override Location getLocation() { result = trait.getLocation() }
}
/** A union type. */
class UnionType extends StructOrEnumType, TUnion {
private Union union;
UnionType() { this = TUnion(union) }
override ItemNode asItemNode() { result = union }
override StructField getStructField(string name) { result = union.getStructField(name) }
override TupleField getTupleField(int i) { none() }
override TypeParameter getPositionalTypeParameter(int i) {
result = TTypeParamTypeParameter(union.getGenericParamList().getTypeParam(i))
}
override TypeMention getTypeParameterDefault(int i) {
result = union.getGenericParamList().getTypeParam(i).getDefaultType()
}
override string toString() { result = union.getName().getText() }
override Location getLocation() { result = union.getLocation() }
}
/**
* An array type.
*
@@ -374,6 +403,33 @@ class SliceType extends Type, TSliceType {
override Location getLocation() { result instanceof EmptyLocation }
}
class NeverType extends Type, TNeverType {
override StructField getStructField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getPositionalTypeParameter(int i) { none() }
override string toString() { result = "!" }
override Location getLocation() { result instanceof EmptyLocation }
}
class PtrType extends Type, TPtrType {
override StructField getStructField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getPositionalTypeParameter(int i) {
i = 0 and
result = TPtrTypeParameter()
}
override string toString() { result = "*" }
override Location getLocation() { result instanceof EmptyLocation }
}
/** A type parameter. */
abstract class TypeParameter extends Type {
override StructField getStructField(string name) { none() }
@@ -529,6 +585,12 @@ class SliceTypeParameter extends TypeParameter, TSliceTypeParameter {
override Location getLocation() { result instanceof EmptyLocation }
}
class PtrTypeParameter extends TypeParameter, TPtrTypeParameter {
override string toString() { result = "*T" }
override Location getLocation() { result instanceof EmptyLocation }
}
/**
* The implicit `Self` type parameter of a trait, that refers to the
* implementing type of the trait.

View File

@@ -99,6 +99,11 @@ private module Input1 implements InputSig1<Location> {
id1 = 0 and
id2 = 2
or
tp0 instanceof PtrTypeParameter and
kind = 0 and
id1 = 0 and
id2 = 3
or
kind = 1 and
id1 = 0 and
id2 =

View File

@@ -241,6 +241,8 @@ class NonAliasPathTypeMention extends PathTypeMention {
else result = TTrait(trait)
)
or
result = TUnion(resolved)
or
result = TTypeParamTypeParameter(resolved)
or
result = TAssociatedTypeTypeParameter(resolved)
@@ -387,3 +389,19 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList {
)
}
}
class NeverTypeReprMention extends TypeMention, NeverTypeRepr {
override Type resolveTypeAt(TypePath path) { result = TNeverType() and path.isEmpty() }
}
class PtrTypeReprMention extends TypeMention instanceof PtrTypeRepr {
override Type resolveTypeAt(TypePath path) {
path.isEmpty() and
result = TPtrType()
or
exists(TypePath suffix |
result = super.getTypeRepr().(TypeMention).resolveTypeAt(suffix) and
path = TypePath::cons(TPtrTypeParameter(), suffix)
)
}
}

View File

@@ -1,2 +0,0 @@
illFormedTypeMention
| macro_expansion.rs:99:7:99:19 | MyDeriveUnion |

View File

@@ -2250,6 +2250,7 @@ inferType
| main.rs:1127:43:1127:82 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
| main.rs:1127:50:1127:81 | "PairNone has no second elemen... | | file://:0:0:0:0 | & |
| main.rs:1127:50:1127:81 | "PairNone has no second elemen... | &T | {EXTERNAL LOCATION} | str |
| main.rs:1127:50:1127:81 | ...::panic_fmt(...) | | file://:0:0:0:0 | ! |
| main.rs:1127:50:1127:81 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
| main.rs:1127:50:1127:81 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
| main.rs:1127:50:1127:81 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
@@ -2261,6 +2262,7 @@ inferType
| main.rs:1128:43:1128:81 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |
| main.rs:1128:50:1128:80 | "PairFst has no second element... | | file://:0:0:0:0 | & |
| main.rs:1128:50:1128:80 | "PairFst has no second element... | &T | {EXTERNAL LOCATION} | str |
| main.rs:1128:50:1128:80 | ...::panic_fmt(...) | | file://:0:0:0:0 | ! |
| main.rs:1128:50:1128:80 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
| main.rs:1128:50:1128:80 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
| main.rs:1128:50:1128:80 | MacroExpr | | main.rs:1124:15:1124:17 | Snd |

View File

@@ -0,0 +1,3 @@
multipleCallTargets
| test.rs:117:9:117:20 | ptr.is_null() |
| test.rs:117:9:117:21 | ptr.is_null() |

View File

@@ -0,0 +1,7 @@
multipleCallTargets
| main.rs:242:44:242:78 | ... .cast() |
| main.rs:245:44:245:78 | ... .cast() |
| main.rs:248:44:248:78 | ... .cast() |
| main.rs:251:14:251:48 | ... .cast() |
| main.rs:254:14:254:48 | ... .cast() |
| main.rs:257:14:257:48 | ... .cast() |