mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #20906 from paldepind/rust/enum-fieldless
Rust: Add predicates for fieldless and unit-only enums
This commit is contained in:
@@ -31,5 +31,23 @@ module Impl {
|
||||
result = this.getVariantList().getAVariant() and
|
||||
result.getName().getText() = name
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a field-less enum, that is, an enum where no constructors contain fields.
|
||||
*
|
||||
* See: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.fieldless
|
||||
*/
|
||||
predicate isFieldless() {
|
||||
forall(Variant v | v = this.getVariantList().getAVariant() | v.getNumberOfFields() = 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a unit-only enum, that is, an enum where all constructors are unit variants.
|
||||
*
|
||||
* See: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.unit-only
|
||||
*/
|
||||
predicate isUnitOnly() {
|
||||
forall(Variant v | v = this.getVariantList().getAVariant() | v.isUnit())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,11 @@ module Impl {
|
||||
pragma[nomagic]
|
||||
predicate isTuple() { this.getFieldList() instanceof TupleFieldList }
|
||||
|
||||
/**
|
||||
* Holds if this struct uses record fields.
|
||||
*
|
||||
* Empty structs are considered to use record fields.
|
||||
*/
|
||||
/** Holds if this struct uses struct fields. */
|
||||
pragma[nomagic]
|
||||
predicate isStruct() { not this.isTuple() }
|
||||
predicate isStruct() { this.getFieldList() instanceof StructFieldList }
|
||||
|
||||
/** Holds if this struct does not have a field list. */
|
||||
predicate isUnit() { not this.hasFieldList() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,17 +36,27 @@ module Impl {
|
||||
pragma[nomagic]
|
||||
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }
|
||||
|
||||
/** Gets the number of fields of this variant. */
|
||||
int getNumberOfFields() {
|
||||
not this.hasFieldList() and
|
||||
result = 0
|
||||
or
|
||||
result = this.getFieldList().(StructFieldList).getNumberOfFields()
|
||||
or
|
||||
result = this.getFieldList().(TupleFieldList).getNumberOfFields()
|
||||
}
|
||||
|
||||
/** Holds if this variant uses tuple fields. */
|
||||
pragma[nomagic]
|
||||
predicate isTuple() { this.getFieldList() instanceof TupleFieldList }
|
||||
|
||||
/**
|
||||
* Holds if this variant uses struct fields.
|
||||
*
|
||||
* Empty variants are considered to use struct fields.
|
||||
*/
|
||||
/** Holds if this variant uses struct fields. */
|
||||
pragma[nomagic]
|
||||
predicate isStruct() { not this.isTuple() }
|
||||
predicate isStruct() { this.getFieldList() instanceof StructFieldList }
|
||||
|
||||
/** Holds if this variant does not have a field list. */
|
||||
pragma[nomagic]
|
||||
predicate isUnit() { not this.hasFieldList() }
|
||||
|
||||
/** Gets the enum that this variant belongs to. */
|
||||
Enum getEnum() { this = result.getVariantList().getAVariant() }
|
||||
|
||||
@@ -659,7 +659,7 @@ private class VariantItemNode extends ParameterizableItemNode instanceof Variant
|
||||
override string getName() { result = Variant.super.getName().getText() }
|
||||
|
||||
override Namespace getNamespace() {
|
||||
if super.getFieldList() instanceof StructFieldList then result.isType() else result.isValue()
|
||||
if super.isStruct() then result.isType() else result.isValue()
|
||||
}
|
||||
|
||||
override TypeParam getTypeParam(int i) {
|
||||
@@ -969,7 +969,7 @@ private class StructItemNode extends TypeItemNode, ParameterizableItemNode insta
|
||||
override Namespace getNamespace() {
|
||||
result.isType() // the struct itself
|
||||
or
|
||||
not super.getFieldList() instanceof StructFieldList and
|
||||
not super.isStruct() and
|
||||
result.isValue() // the constructor
|
||||
}
|
||||
|
||||
|
||||
@@ -787,7 +787,7 @@ private module StructExprMatchingInput implements MatchingInputSig {
|
||||
}
|
||||
|
||||
private class StructDecl extends Declaration, Struct {
|
||||
StructDecl() { this.isStruct() }
|
||||
StructDecl() { this.isStruct() or this.isUnit() }
|
||||
|
||||
override TypeParam getATypeParam() { result = this.getGenericParamList().getATypeParam() }
|
||||
|
||||
@@ -804,7 +804,7 @@ private module StructExprMatchingInput implements MatchingInputSig {
|
||||
}
|
||||
|
||||
private class StructVariantDecl extends Declaration, Variant {
|
||||
StructVariantDecl() { this.isStruct() }
|
||||
StructVariantDecl() { this.isStruct() or this.isUnit() }
|
||||
|
||||
Enum getEnum() { result.getVariantList().getAVariant() = this }
|
||||
|
||||
|
||||
7
rust/ql/test/library-tests/elements/enum/Cargo.lock
generated
Normal file
7
rust/ql/test/library-tests/elements/enum/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "test"
|
||||
version = "0.0.1"
|
||||
7
rust/ql/test/library-tests/elements/enum/Enum.expected
Normal file
7
rust/ql/test/library-tests/elements/enum/Enum.expected
Normal file
@@ -0,0 +1,7 @@
|
||||
fieldless
|
||||
| enums.rs:1:1:5:1 | enum Foo |
|
||||
| enums.rs:7:1:11:1 | enum Fieldless |
|
||||
| enums.rs:13:1:18:1 | enum Direction |
|
||||
unitOnly
|
||||
| enums.rs:1:1:5:1 | enum Foo |
|
||||
| enums.rs:13:1:18:1 | enum Direction |
|
||||
6
rust/ql/test/library-tests/elements/enum/Enum.ql
Normal file
6
rust/ql/test/library-tests/elements/enum/Enum.ql
Normal file
@@ -0,0 +1,6 @@
|
||||
import rust
|
||||
import TestUtils
|
||||
|
||||
query predicate fieldless(Enum e) { toBeTested(e) and e.isFieldless() }
|
||||
|
||||
query predicate unitOnly(Enum e) { toBeTested(e) and e.isUnitOnly() }
|
||||
24
rust/ql/test/library-tests/elements/enum/enums.rs
Normal file
24
rust/ql/test/library-tests/elements/enum/enums.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
enum Foo {
|
||||
Bar,
|
||||
Baz,
|
||||
Qux,
|
||||
}
|
||||
|
||||
enum Fieldless {
|
||||
Tuple(),
|
||||
Struct{},
|
||||
Unit,
|
||||
}
|
||||
|
||||
enum Direction {
|
||||
North = 0,
|
||||
East = 90,
|
||||
South = 180,
|
||||
West = 270,
|
||||
}
|
||||
|
||||
enum Color {
|
||||
Red(u8),
|
||||
Green(u8),
|
||||
Blue(u8),
|
||||
}
|
||||
Reference in New Issue
Block a user