Skip to content

Commit b9f9ba1

Browse files
authored
Add const methods for oparg enums (#7617)
* Add const methods for oparg enums * Shorten doc link
1 parent 3d91197 commit b9f9ba1

1 file changed

Lines changed: 51 additions & 31 deletions

File tree

  • crates/compiler-core/src/bytecode

‎crates/compiler-core/src/bytecode/oparg.rs‎

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,6 @@ impl OpArgState {
136136
/// - impl [`Into<u32>`]
137137
/// - impl [`OpArgType`]
138138
///
139-
/// # Note
140-
/// If an enum variant has "alternative" values (i.e. `Foo = 0 | 1`), the first value will be the
141-
/// result of converting to a number.
142-
///
143139
/// # Examples
144140
///
145141
/// ```ignore
@@ -150,8 +146,8 @@ impl OpArgState {
150146
/// /// Some doc.
151147
/// Foo = 4,
152148
/// Bar = 8,
153-
/// Baz = 15 | 16,
154-
/// Qux = 23 | 42
149+
/// Baz = 15,
150+
/// Qux = 16
155151
/// }
156152
/// );
157153
/// ```
@@ -161,7 +157,7 @@ macro_rules! oparg_enum {
161157
$vis:vis enum $name:ident {
162158
$(
163159
$(#[$variant_meta:meta])*
164-
$variant:ident = $value:literal $(| $alternatives:expr)*
160+
$variant:ident = $value:literal
165161
),* $(,)?
166162
}
167163
) => {
@@ -174,9 +170,9 @@ macro_rules! oparg_enum {
174170
}
175171

176172
impl_oparg_enum!(
177-
enum $name {
173+
$vis enum $name {
178174
$(
179-
$variant = $value $(| $alternatives)*,
175+
$variant = $value,
180176
)*
181177
}
182178
);
@@ -185,48 +181,73 @@ macro_rules! oparg_enum {
185181

186182
macro_rules! impl_oparg_enum {
187183
(
188-
enum $name:ident {
184+
$vis:vis enum $name:ident {
189185
$(
190-
$variant:ident = $value:literal $(| $alternatives:expr)*
186+
$variant:ident = $value:literal
191187
),* $(,)?
192188
}
193189
) => {
194-
impl TryFrom<u8> for $name {
195-
type Error = $crate::marshal::MarshalError;
190+
impl $name {
191+
/// Returns the oparg as a [`u8`] value.
192+
#[must_use]
193+
$vis const fn as_u8(self) -> u8 {
194+
match self {
195+
$(
196+
Self::$variant => $value,
197+
)*
198+
}
199+
}
196200

197-
fn try_from(value: u8) -> Result<Self, Self::Error> {
201+
/// Returns the oparg as a [`u32`] value.
202+
#[must_use]
203+
$vis const fn as_u32(self) -> u32 {
204+
self.as_u8() as u32
205+
}
206+
207+
$vis const fn try_from_u8(value: u8) -> Result<Self, $crate::marshal::MarshalError> {
198208
Ok(match value {
199209
$(
200-
$value $(| $alternatives)* => Self::$variant,
210+
$value => Self::$variant,
201211
)*
202-
_ => return Err(Self::Error::InvalidBytecode),
212+
_ => return Err($crate::marshal::MarshalError::InvalidBytecode),
203213
})
204214
}
215+
216+
$vis const fn try_from_u32(value: u32) -> Result<Self, $crate::marshal::MarshalError> {
217+
if value > (u8::MAX as u32) {
218+
return Err($crate::marshal::MarshalError::InvalidBytecode);
219+
}
220+
221+
// We already validated this is a lossles cast.
222+
Self::try_from_u8(value as u8)
223+
}
224+
}
225+
226+
impl TryFrom<u8> for $name {
227+
type Error = $crate::marshal::MarshalError;
228+
229+
fn try_from(value: u8) -> Result<Self, Self::Error> {
230+
Self::try_from_u8(value)
231+
}
205232
}
206233

207234
impl TryFrom<u32> for $name {
208235
type Error = $crate::marshal::MarshalError;
209236

210237
fn try_from(value: u32) -> Result<Self, Self::Error> {
211-
u8::try_from(value)
212-
.map_err(|_| Self::Error::InvalidBytecode)
213-
.map(TryInto::try_into)?
238+
Self::try_from_u32(value)
214239
}
215240
}
216241

217242
impl From<$name> for u8 {
218243
fn from(value: $name) -> Self {
219-
match value {
220-
$(
221-
$name::$variant => $value,
222-
)*
223-
}
244+
value.as_u8()
224245
}
225246
}
226247

227248
impl From<$name> for u32 {
228249
fn from(value: $name) -> Self {
229-
Self::from(u8::from(value))
250+
value.as_u32()
230251
}
231252
}
232253

@@ -239,7 +260,7 @@ oparg_enum!(
239260
///
240261
/// ## See also
241262
///
242-
/// - [CPython FVC_* flags](https://github.com/python/cpython/blob/8183fa5e3f78ca6ab862de7fb8b14f3d929421e0/Include/ceval.h#L129-L132)
263+
/// - [CPython FVC_* flags](https://github.com/python/cpython/blob/v3.14.4/Include/ceval.h#L129-L132)
243264
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
244265
pub enum ConvertValueOparg {
245266
/// No conversion.
@@ -248,8 +269,7 @@ oparg_enum!(
248269
/// f"{x}"
249270
/// f"{x:4}"
250271
/// ```
251-
// Ruff `ConversionFlag::None` is `-1i8`, when its converted to `u8` its value is `u8::MAX`.
252-
None = 0 | 255,
272+
None = 0,
253273
/// Converts by calling `str(<value>)`.
254274
///
255275
/// ```python
@@ -747,19 +767,19 @@ macro_rules! newtype_oparg {
747767
$vis struct $name(u32);
748768

749769
impl $name {
750-
/// Creates a new [`$name`] instance.
770+
#[doc = concat!("Creates a new [`", stringify!($name), "`] instance.")]
751771
#[must_use]
752772
pub const fn from_u32(value: u32) -> Self {
753773
Self(value)
754774
}
755775

756-
/// Returns the oparg as a `u32` value.
776+
/// Returns the oparg as a [`u32`] value.
757777
#[must_use]
758778
pub const fn as_u32(self) -> u32 {
759779
self.0
760780
}
761781

762-
/// Returns the oparg as a `usize` value.
782+
/// Returns the oparg as a [`usize`] value.
763783
#[must_use]
764784
pub const fn as_usize(self) -> usize {
765785
self.0 as usize

0 commit comments

Comments
 (0)