diff --git a/Cargo.lock b/Cargo.lock index 886b8294e17..58e16defe00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3110,7 +3110,6 @@ dependencies = [ "lz4_flex", "malachite-bigint", "num-complex", - "num_enum", "ruff_source_file", "rustpython-wtf8", ] diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index f76ccd152e7..6101441dadf 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -1165,7 +1165,7 @@ impl Compiler { arg: OpArgMarker::marker(), } .into(), - arg: OpArg(bytecode::ResumeType::AtFuncStart as u32), + arg: OpArg(u32::from(bytecode::ResumeType::AtFuncStart)), target: BlockIdx::NULL, location, end_location, @@ -1267,8 +1267,6 @@ impl Compiler { /// Emit format parameter validation for annotation scope /// if format > VALUE_WITH_FAKE_GLOBALS (2): raise NotImplementedError fn emit_format_validation(&mut self) -> CompileResult<()> { - use bytecode::ComparisonOperator::Greater; - // Load format parameter (first local variable, index 0) emit!(self, Instruction::LoadFast(0)); @@ -1276,7 +1274,12 @@ impl Compiler { self.emit_load_const(ConstantData::Integer { value: 2.into() }); // Compare: format > 2 - emit!(self, Instruction::CompareOp { op: Greater }); + emit!( + self, + Instruction::CompareOp { + op: ComparisonOperator::Greater + } + ); // Jump to body if format <= 2 (comparison is false) let body_block = self.new_block(); @@ -6545,9 +6548,9 @@ impl Compiler { self, Instruction::Resume { arg: if is_await { - bytecode::ResumeType::AfterAwait as u32 + u32::from(bytecode::ResumeType::AfterAwait) } else { - bytecode::ResumeType::AfterYieldFrom as u32 + u32::from(bytecode::ResumeType::AfterYieldFrom) } } ); @@ -6702,7 +6705,7 @@ impl Compiler { emit!( self, Instruction::Resume { - arg: bytecode::ResumeType::AfterYield as u32 + arg: u32::from(bytecode::ResumeType::AfterYield) } ); } @@ -6924,7 +6927,7 @@ impl Compiler { emit!( compiler, Instruction::Resume { - arg: bytecode::ResumeType::AfterYield as u32 + arg: u32::from(bytecode::ResumeType::AfterYield) } ); emit!(compiler, Instruction::PopTop); @@ -8412,7 +8415,7 @@ impl Compiler { // Emit BUILD_INTERPOLATION // oparg encoding: (conversion << 2) | has_format_spec - let oparg = (conversion << 2) | (has_format_spec as u32); + let oparg = (conversion << 2) | u32::from(has_format_spec); emit!(self, Instruction::BuildInterpolation { oparg }); *interp_count += 1; diff --git a/crates/compiler-core/Cargo.toml b/crates/compiler-core/Cargo.toml index 6a03f02c24f..f4e619b95a4 100644 --- a/crates/compiler-core/Cargo.toml +++ b/crates/compiler-core/Cargo.toml @@ -17,7 +17,6 @@ bitflags = { workspace = true } itertools = { workspace = true } malachite-bigint = { workspace = true } num-complex = { workspace = true } -num_enum = { workspace = true } lz4_flex = "0.12" diff --git a/crates/compiler-core/src/bytecode.rs b/crates/compiler-core/src/bytecode.rs index 3080b4e623e..a59b8f269e9 100644 --- a/crates/compiler-core/src/bytecode.rs +++ b/crates/compiler-core/src/bytecode.rs @@ -304,8 +304,8 @@ bitflags! { } } -#[derive(Copy, Clone)] #[repr(C)] +#[derive(Copy, Clone, Debug)] pub struct CodeUnit { pub op: Instruction, pub arg: OpArgByte, @@ -330,7 +330,7 @@ impl TryFrom<&[u8]> for CodeUnit { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct CodeUnits(Box<[CodeUnit]>); impl TryFrom<&[u8]> for CodeUnits { diff --git a/crates/compiler-core/src/bytecode/oparg.rs b/crates/compiler-core/src/bytecode/oparg.rs index 7d2fca03988..a4eeb7ea1d9 100644 --- a/crates/compiler-core/src/bytecode/oparg.rs +++ b/crates/compiler-core/src/bytecode/oparg.rs @@ -1,5 +1,4 @@ use bitflags::bitflags; -use num_enum::{IntoPrimitive, TryFromPrimitive}; use core::fmt; @@ -104,11 +103,82 @@ impl OpArgState { } } -macro_rules! impl_oparg_enum_traits { - ($name:ty) => { - impl From<$name> for u32 { - fn from(value: $name) -> Self { - Self::from(u8::from(value)) +/// Helper macro for defining oparg enums in an optimal way. +/// +/// Will generate the following: +/// +/// - Enum which variant's aren't assigned any value (for optimizations). +/// - impl [`TryFrom`] +/// - impl [`TryFrom`] +/// - impl [`Into`] +/// - impl [`Into`] +/// - impl [`OpArgType`] +/// +/// # Note +/// If an enum variant has "alternative" values (i.e. `Foo = 0 | 1`), the first value will be the +/// result of converting to a number. +/// +/// # Examples +/// +/// ```ignore +/// oparg_enum!( +/// /// Oparg for the `X` opcode. +/// #[derive(Clone, Copy)] +/// pub enum MyOpArg { +/// /// Some doc. +/// Foo = 4, +/// Bar = 8, +/// Baz = 15 | 16, +/// Qux = 23 | 42 +/// } +/// ); +/// ``` +macro_rules! oparg_enum { + ( + $(#[$enum_meta:meta])* + $vis:vis enum $name:ident { + $( + $(#[$variant_meta:meta])* + $variant:ident = $value:literal $(| $alternatives:expr)* + ),* $(,)? + } + ) => { + $(#[$enum_meta])* + $vis enum $name { + $( + $(#[$variant_meta])* + $variant, // Do assign value to variant. + )* + } + + impl_oparg_enum!( + enum $name { + $( + $variant = $value $(| $alternatives)*, + )* + } + ); + }; +} + +macro_rules! impl_oparg_enum { + ( + enum $name:ident { + $( + $variant:ident = $value:literal $(| $alternatives:expr)* + ),* $(,)? + } + ) => { + impl TryFrom for $name { + type Error = $crate::marshal::MarshalError; + + fn try_from(value: u8) -> Result { + Ok(match value { + $( + $value $(| $alternatives)* => Self::$variant, + )* + _ => return Err(Self::Error::InvalidBytecode), + }) } } @@ -121,51 +191,66 @@ macro_rules! impl_oparg_enum_traits { .map(TryInto::try_into)? } } + + impl From<$name> for u8 { + fn from(value: $name) -> Self { + match value { + $( + $name::$variant => $value, + )* + } + } + } + + impl From<$name> for u32 { + fn from(value: $name) -> Self { + Self::from(u8::from(value)) + } + } + + impl OpArgType for $name {} }; } -/// Oparg values for [`Instruction::ConvertValue`]. -/// -/// ## See also -/// -/// - [CPython FVC_* flags](https://github.com/python/cpython/blob/8183fa5e3f78ca6ab862de7fb8b14f3d929421e0/Include/ceval.h#L129-L132) -#[repr(u8)] -#[derive(Clone, Copy, Debug, Eq, Hash, IntoPrimitive, PartialEq, TryFromPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum ConvertValueOparg { - /// No conversion. +oparg_enum!( + /// Oparg values for [`Instruction::ConvertValue`]. /// - /// ```python - /// f"{x}" - /// f"{x:4}" - /// ``` - // Ruff `ConversionFlag::None` is `-1i8`, when its converted to `u8` its value is `u8::MAX`. - #[num_enum(alternatives = [255])] - None = 0, - /// Converts by calling `str()`. + /// ## See also /// - /// ```python - /// f"{x!s}" - /// f"{x!s:2}" - /// ``` - Str = 1, - /// Converts by calling `repr()`. - /// - /// ```python - /// f"{x!r}" - /// f"{x!r:2}" - /// ``` - Repr = 2, - /// Converts by calling `ascii()`. - /// - /// ```python - /// f"{x!a}" - /// f"{x!a:2}" - /// ``` - Ascii = 3, -} - -impl_oparg_enum_traits!(ConvertValueOparg); + /// - [CPython FVC_* flags](https://github.com/python/cpython/blob/8183fa5e3f78ca6ab862de7fb8b14f3d929421e0/Include/ceval.h#L129-L132) + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub enum ConvertValueOparg { + /// No conversion. + /// + /// ```python + /// f"{x}" + /// f"{x:4}" + /// ``` + // Ruff `ConversionFlag::None` is `-1i8`, when its converted to `u8` its value is `u8::MAX`. + None = 0 | 255, + /// Converts by calling `str()`. + /// + /// ```python + /// f"{x!s}" + /// f"{x!s:2}" + /// ``` + Str = 1, + /// Converts by calling `repr()`. + /// + /// ```python + /// f"{x!r}" + /// f"{x!r:2}" + /// ``` + Repr = 2, + /// Converts by calling `ascii()`. + /// + /// ```python + /// f"{x!a}" + /// f"{x!a:2}" + /// ``` + Ascii = 3, + } +); impl fmt::Display for ConvertValueOparg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -181,23 +266,20 @@ impl fmt::Display for ConvertValueOparg { } } -impl OpArgType for ConvertValueOparg {} - -/// Resume type for the RESUME instruction -#[repr(u8)] -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum ResumeType { - AtFuncStart = 0, - AfterYield = 1, - AfterYieldFrom = 2, - AfterAwait = 3, -} +oparg_enum!( + /// Resume type for the RESUME instruction + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] + pub enum ResumeType { + AtFuncStart = 0, + AfterYield = 1, + AfterYieldFrom = 2, + AfterAwait = 3, + } +); pub type NameIdx = u32; impl OpArgType for u32 {} -//impl OpArgType for bool {} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] #[repr(transparent)] @@ -229,73 +311,64 @@ impl fmt::Display for Label { } } -/// The kind of Raise that occurred. -#[repr(u8)] -#[derive(Copy, Clone, Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Eq)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum RaiseKind { - /// Bare `raise` statement with no arguments. - /// Gets the current exception from VM state (topmost_exception). - /// Maps to RAISE_VARARGS with oparg=0. - BareRaise = 0, - /// `raise exc` - exception is on the stack. - /// Maps to RAISE_VARARGS with oparg=1. - Raise = 1, - /// `raise exc from cause` - exception and cause are on the stack. - /// Maps to RAISE_VARARGS with oparg=2. - RaiseCause = 2, - /// Reraise exception from the stack top. - /// Used in exception handler cleanup blocks (finally, except). - /// Gets exception from stack, not from VM state. - /// Maps to the RERAISE opcode. - ReraiseFromStack = 3, -} - -impl_oparg_enum_traits!(RaiseKind); -impl OpArgType for RaiseKind {} - -/// Intrinsic function for CALL_INTRINSIC_1 -#[repr(u8)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum IntrinsicFunction1 { - // Invalid = 0, - Print = 1, - /// Import * operation - ImportStar = 2, - /// Convert StopIteration to RuntimeError in async context - StopIterationError = 3, - AsyncGenWrap = 4, - UnaryPositive = 5, - /// Convert list to tuple - ListToTuple = 6, - /// Type parameter related - TypeVar = 7, - ParamSpec = 8, - TypeVarTuple = 9, - /// Generic subscript for PEP 695 - SubscriptGeneric = 10, - TypeAlias = 11, -} - -impl_oparg_enum_traits!(IntrinsicFunction1); -impl OpArgType for IntrinsicFunction1 {} - -/// Intrinsic function for CALL_INTRINSIC_2 -#[repr(u8)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum IntrinsicFunction2 { - PrepReraiseStar = 1, - TypeVarWithBound = 2, - TypeVarWithConstraint = 3, - SetFunctionTypeParams = 4, - /// Set default value for type parameter (PEP 695) - SetTypeparamDefault = 5, -} - -impl_oparg_enum_traits!(IntrinsicFunction2); -impl OpArgType for IntrinsicFunction2 {} +oparg_enum!( + /// The kind of Raise that occurred. + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub enum RaiseKind { + /// Bare `raise` statement with no arguments. + /// Gets the current exception from VM state (topmost_exception). + /// Maps to RAISE_VARARGS with oparg=0. + BareRaise = 0, + /// `raise exc` - exception is on the stack. + /// Maps to RAISE_VARARGS with oparg=1. + Raise = 1, + /// `raise exc from cause` - exception and cause are on the stack. + /// Maps to RAISE_VARARGS with oparg=2. + RaiseCause = 2, + /// Reraise exception from the stack top. + /// Used in exception handler cleanup blocks (finally, except). + /// Gets exception from stack, not from VM state. + /// Maps to the RERAISE opcode. + ReraiseFromStack = 3, + } +); + +oparg_enum!( + /// Intrinsic function for CALL_INTRINSIC_1 + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub enum IntrinsicFunction1 { + // Invalid = 0, + Print = 1, + /// Import * operation + ImportStar = 2, + /// Convert StopIteration to RuntimeError in async context + StopIterationError = 3, + AsyncGenWrap = 4, + UnaryPositive = 5, + /// Convert list to tuple + ListToTuple = 6, + /// Type parameter related + TypeVar = 7, + ParamSpec = 8, + TypeVarTuple = 9, + /// Generic subscript for PEP 695 + SubscriptGeneric = 10, + TypeAlias = 11, + } +); + +oparg_enum!( + /// Intrinsic function for CALL_INTRINSIC_2 + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub enum IntrinsicFunction2 { + PrepReraiseStar = 1, + TypeVarWithBound = 2, + TypeVarWithConstraint = 3, + SetFunctionTypeParams = 4, + /// Set default value for type parameter (PEP 695) + SetTypeparamDefault = 5, + } +); bitflags! { #[derive(Copy, Clone, Debug, PartialEq)] @@ -326,95 +399,92 @@ impl From for u32 { impl OpArgType for MakeFunctionFlags {} -/// The possible comparison operators. -#[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum ComparisonOperator { - // be intentional with bits so that we can do eval_ord with just a bitwise and - // bits: | Equal | Greater | Less | - Less = 0b001, - Greater = 0b010, - NotEqual = 0b011, - Equal = 0b100, - LessOrEqual = 0b101, - GreaterOrEqual = 0b110, -} - -impl_oparg_enum_traits!(ComparisonOperator); -impl OpArgType for ComparisonOperator {} - -/// The possible Binary operators -/// -/// # Examples -/// -/// ```rust -/// use rustpython_compiler_core::bytecode::{Arg, BinaryOperator, Instruction}; -/// let (op, _) = Arg::new(BinaryOperator::Add); -/// let instruction = Instruction::BinaryOp { op }; -/// ``` -/// -/// See also: -/// - [_PyEval_BinaryOps](https://github.com/python/cpython/blob/8183fa5e3f78ca6ab862de7fb8b14f3d929421e0/Python/ceval.c#L316-L343) -#[repr(u8)] -#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum BinaryOperator { - /// `+` - Add = 0, - /// `&` - And = 1, - /// `//` - FloorDivide = 2, - /// `<<` - Lshift = 3, - /// `@` - MatrixMultiply = 4, - /// `*` - Multiply = 5, - /// `%` - Remainder = 6, - /// `|` - Or = 7, - /// `**` - Power = 8, - /// `>>` - Rshift = 9, - /// `-` - Subtract = 10, - /// `/` - TrueDivide = 11, - /// `^` - Xor = 12, - /// `+=` - InplaceAdd = 13, - /// `&=` - InplaceAnd = 14, - /// `//=` - InplaceFloorDivide = 15, - /// `<<=` - InplaceLshift = 16, - /// `@=` - InplaceMatrixMultiply = 17, - /// `*=` - InplaceMultiply = 18, - /// `%=` - InplaceRemainder = 19, - /// `|=` - InplaceOr = 20, - /// `**=` - InplacePower = 21, - /// `>>=` - InplaceRshift = 22, - /// `-=` - InplaceSubtract = 23, - /// `/=` - InplaceTrueDivide = 24, - /// `^=` - InplaceXor = 25, - /// `[]` subscript - Subscr = 26, -} +oparg_enum!( + /// The possible comparison operators. + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum ComparisonOperator { + // be intentional with bits so that we can do eval_ord with just a bitwise and + // bits: | Equal | Greater | Less | + Less = 0b001, + Greater = 0b010, + NotEqual = 0b011, + Equal = 0b100, + LessOrEqual = 0b101, + GreaterOrEqual = 0b110, + } +); + +oparg_enum!( + /// The possible Binary operators + /// + /// # Examples + /// + /// ```rust + /// use rustpython_compiler_core::bytecode::{Arg, BinaryOperator, Instruction}; + /// let (op, _) = Arg::new(BinaryOperator::Add); + /// let instruction = Instruction::BinaryOp { op }; + /// ``` + /// + /// See also: + /// - [_PyEval_BinaryOps](https://github.com/python/cpython/blob/8183fa5e3f78ca6ab862de7fb8b14f3d929421e0/Python/ceval.c#L316-L343) + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub enum BinaryOperator { + /// `+` + Add = 0, + /// `&` + And = 1, + /// `//` + FloorDivide = 2, + /// `<<` + Lshift = 3, + /// `@` + MatrixMultiply = 4, + /// `*` + Multiply = 5, + /// `%` + Remainder = 6, + /// `|` + Or = 7, + /// `**` + Power = 8, + /// `>>` + Rshift = 9, + /// `-` + Subtract = 10, + /// `/` + TrueDivide = 11, + /// `^` + Xor = 12, + /// `+=` + InplaceAdd = 13, + /// `&=` + InplaceAnd = 14, + /// `//=` + InplaceFloorDivide = 15, + /// `<<=` + InplaceLshift = 16, + /// `@=` + InplaceMatrixMultiply = 17, + /// `*=` + InplaceMultiply = 18, + /// `%=` + InplaceRemainder = 19, + /// `|=` + InplaceOr = 20, + /// `**=` + InplacePower = 21, + /// `>>=` + InplaceRshift = 22, + /// `-=` + InplaceSubtract = 23, + /// `/=` + InplaceTrueDivide = 24, + /// `^=` + InplaceXor = 25, + /// `[]` subscript + Subscr = 26, + } +); impl BinaryOperator { /// Get the "inplace" version of the operator. @@ -449,9 +519,6 @@ impl BinaryOperator { } } -impl_oparg_enum_traits!(BinaryOperator); -impl OpArgType for BinaryOperator {} - impl fmt::Display for BinaryOperator { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let op = match self { @@ -487,43 +554,37 @@ impl fmt::Display for BinaryOperator { } } -/// Whether or not to invert the operation. -#[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum Invert { - /// ```py - /// foo is bar - /// x in lst - /// ``` - No = 0, - /// ```py - /// foo is not bar - /// x not in lst - /// ``` - Yes = 1, -} - -impl_oparg_enum_traits!(Invert); -impl OpArgType for Invert {} - -/// Special method for LOAD_SPECIAL opcode (context managers). -#[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum SpecialMethod { - /// `__enter__` for sync context manager - Enter = 0, - /// `__exit__` for sync context manager - Exit = 1, - /// `__aenter__` for async context manager - AEnter = 2, - /// `__aexit__` for async context manager - AExit = 3, -} - -impl_oparg_enum_traits!(SpecialMethod); -impl OpArgType for SpecialMethod {} +oparg_enum!( + /// Whether or not to invert the operation. + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum Invert { + /// ```py + /// foo is bar + /// x in lst + /// ``` + No = 0, + /// ```py + /// foo is not bar + /// x not in lst + /// ``` + Yes = 1, + } +); + +oparg_enum!( + /// Special method for LOAD_SPECIAL opcode (context managers). + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum SpecialMethod { + /// `__enter__` for sync context manager + Enter = 0, + /// `__exit__` for sync context manager + Exit = 1, + /// `__aenter__` for async context manager + AEnter = 2, + /// `__aexit__` for async context manager + AExit = 3, + } +); impl fmt::Display for SpecialMethod { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -537,26 +598,23 @@ impl fmt::Display for SpecialMethod { } } -/// Common constants for LOAD_COMMON_CONSTANT opcode. -/// pycore_opcode_utils.h CONSTANT_* -#[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -pub enum CommonConstant { - /// `AssertionError` exception type - AssertionError = 0, - /// `NotImplementedError` exception type - NotImplementedError = 1, - /// Built-in `tuple` type - BuiltinTuple = 2, - /// Built-in `all` function - BuiltinAll = 3, - /// Built-in `any` function - BuiltinAny = 4, -} - -impl_oparg_enum_traits!(CommonConstant); -impl OpArgType for CommonConstant {} +oparg_enum!( + /// Common constants for LOAD_COMMON_CONSTANT opcode. + /// pycore_opcode_utils.h CONSTANT_* + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum CommonConstant { + /// `AssertionError` exception type + AssertionError = 0, + /// `NotImplementedError` exception type + NotImplementedError = 1, + /// Built-in `tuple` type + BuiltinTuple = 2, + /// Built-in `all` function + BuiltinAll = 3, + /// Built-in `any` function + BuiltinAny = 4, + } +); impl fmt::Display for CommonConstant { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -571,51 +629,20 @@ impl fmt::Display for CommonConstant { } } -/// Specifies if a slice is built with either 2 or 3 arguments. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum BuildSliceArgCount { - /// ```py - /// x[5:10] - /// ``` - Two, - /// ```py - /// x[5:10:2] - /// ``` - Three, -} - -impl TryFrom for BuildSliceArgCount { - type Error = MarshalError; - - fn try_from(value: u8) -> Result { - Ok(match value { - 2 => Self::Two, - 3 => Self::Three, - _ => return Err(Self::Error::InvalidBytecode), - }) - } -} - -impl TryFrom for BuildSliceArgCount { - type Error = MarshalError; - - fn try_from(value: u32) -> Result { - u8::try_from(value) - .map_err(|_| Self::Error::InvalidBytecode) - .map(TryInto::try_into)? +oparg_enum!( + /// Specifies if a slice is built with either 2 or 3 arguments. + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub enum BuildSliceArgCount { + /// ```py + /// x[5:10] + /// ``` + Two = 2, + /// ```py + /// x[5:10:2] + /// ``` + Three = 3, } -} - -impl From for u32 { - fn from(value: BuildSliceArgCount) -> Self { - match value { - BuildSliceArgCount::Two => 2, - BuildSliceArgCount::Three => 3, - } - } -} - -impl OpArgType for BuildSliceArgCount {} +); #[derive(Copy, Clone)] pub struct UnpackExArgs { @@ -727,23 +754,3 @@ impl From for LoadSuperAttr { builder.build() } } - -/// Helper function for `num_enum` derive macro. -/// -/// # Examples -/// -/// ```ignore -/// use num_enum::TryFromPrimitive; -/// -/// use rustpython_compiler_core::marshal::MarshalError; -/// -/// #[repr(u8)] -/// #[derive(TryFromPrimitive)] -/// #[num_enum(error_type(name = MarshalError, constructor = new_invalid_bytecode))] -/// enum Foo { -/// A = 1, -/// B = 2 -/// } -fn new_invalid_bytecode(_: T) -> MarshalError { - MarshalError::InvalidBytecode -} diff --git a/crates/vm/src/types/slot.rs b/crates/vm/src/types/slot.rs index 2f45d9dcff1..53750610cae 100644 --- a/crates/vm/src/types/slot.rs +++ b/crates/vm/src/types/slot.rs @@ -1819,13 +1819,13 @@ impl PyComparisonOp { } } - pub const fn eval_ord(self, ord: Ordering) -> bool { + pub fn eval_ord(self, ord: Ordering) -> bool { let bit = match ord { Ordering::Less => Self::Lt, Ordering::Equal => Self::Eq, Ordering::Greater => Self::Gt, }; - self.0 as u8 & bit.0 as u8 != 0 + u8::from(self.0) & u8::from(bit.0) != 0 } pub const fn swapped(self) -> Self {