diff options
| -rw-r--r-- | Cargo.toml | 32 | ||||
| -rw-r--r-- | src/armv7.rs | 2 | ||||
| -rw-r--r-- | src/armv8/a64.rs | 3 | 
3 files changed, 34 insertions, 3 deletions
| @@ -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. | 
