aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml32
-rw-r--r--src/armv7.rs2
-rw-r--r--src/armv8/a64.rs3
3 files changed, 34 insertions, 3 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f9c6c91..bb7f6fb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,12 +21,40 @@ bitvec = { version = "1.0.1", default-features = false, features = [] }
"serde_derive" = { version = "1.0", optional = true }
[features]
-default = ["std", "alloc", "fmt", "use-serde"]
+default = ["std", "alloc", "fmt", "use-serde", "non-exhaustive-enums"]
+
+# IF YOU DISABLE DEFAULT FEATURES, EXPLICITLY ENABLE `non-exhaustive-enums`.
+# unless you read the rest of this section and manage or tolerate additional
+# Operand variants appearing across minor releases.
+#
+# `Opcode` and `Operand` enums are marked non-exhaustive to tolerate future
+# growth of the ISA or additions to the disassembler (NEON, etc). typically
+# disassemblers either care about a specific subset of instructions (`b<cc>`,
+# `bl` come to mind), or many (all?) instructions (program analysis, semantic
+# lifting, ..).
+#
+# this feature allows users to control the presence of the `#[non_exhaustive]`
+# attribute on Opcode and Operand to get feedback on missing variants in large
+# match blocks.
+#
+# additions to `Opcode` and `Operand` will happen across minor version bumps,
+# but not patch versions. code removing `#[non_exhaustive]` should probably
+# lock to a minor versions.
+#
+# this is an enabled-by-default feature to handle cases where a library removes
+# this feature, but something else in the dependency tree enables it. this way,
+# libraries can test with this feature disabled, lock to corresponding
+# major.minor versions of the disassembler and opcode set, and then harmlessly
+# tolerate `#[non_exhaustive]` if it's added inadvertently elsewhere in the
+# dependency tree.
+non-exhaustive-enums = []
# fmt-related features that depend on the alloc crate
alloc = []
-# formatting code (Display, Debug impls, etc) are optional on `fmt`.
+# formatting code (Display, Debug impls, etc) are (inconsistently) optional on
+# `fmt`. future crate releases will move `fmt` impls consistently behind this
+# feature.
#
# some `fmt` code also has `alloc` features (`InstructionDisplayBuffer`)
fmt = []
diff --git a/src/armv7.rs b/src/armv7.rs
index b1ae2ba..3e289b6 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -39,6 +39,7 @@ pub struct NoContext;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[allow(non_camel_case_types)]
#[allow(missing_docs)]
+#[cfg_attr(feature = "non-exhaustive-enums", non_exhaustive)]
pub enum Opcode {
Invalid,
/*
@@ -606,6 +607,7 @@ impl StatusRegMask {
/// an operand in an `arm` instruction.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "non-exhaustive-enums", non_exhaustive)]
pub enum Operand {
/// a general-purpose register.
Reg(Reg),
diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs
index 140e616..075efc2 100644
--- a/src/armv8/a64.rs
+++ b/src/armv8/a64.rs
@@ -1147,7 +1147,7 @@ impl SysOps {
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u16)]
#[allow(missing_docs)]
-#[non_exhaustive]
+#[cfg_attr(feature = "non-exhaustive-enums", non_exhaustive)]
pub enum Opcode {
Invalid,
UDF,
@@ -2795,6 +2795,7 @@ impl Display for ShiftStyle {
/// in practice; no `aarch64` instruction has multiple `Operand::PCOffset` entries, for example.
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(C)]
+#[cfg_attr(feature = "non-exhaustive-enums", non_exhaustive)]
pub enum Operand {
/// "no operand". since an instruction's `operands` array is always four entries, this is used
/// to fill space, if any, after recording an instruction's extant operands.