-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow if
and match
in constants
#2342
Conversation
The semantics of |
@Centril I don't see match enum_value {
Variant0Pattern => {},
Variant1Pattern => {},
_ => {
// something else
},
} to some very unsafe code: if std::intrinsics::discriminant(enum_value) == 0 {
let Pattern: EnumVariant0 = transmute(enum_value);
} else if std::intrinsics::discriminant(enum_value) == 1 {
let Pattern: EnumVariant1 = transmute(enum_value);
} else {
// something else
} Which is almost how MIR handles matches. |
@oli-obk Still... I feel lang RFC texts should be as unambiguous as possible... This makes it easier to review changes proposed and define the spec / reference of the language =) |
Part of the issue with this is that |
The allowed recursion depth isn't very high. Also |
Then I would describe the semantics of |
The reason I did the opposite is that |
Fun fact: there are actually differences in |
@rfcbot fcp merge |
Team member @withoutboats has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
@petrochenkov |
This is required to implement |
@gnzlbg Can you elaborate how? I don't see why those functions (both for portable vector types and arch-specific ones) would have to branch or match, and indeed I can't see anything other than simple data movement when I look at the current implementations. |
@rkruppe wrong link, I've edited the post, but this explains it in a nutshell: Boolean vector constructors' take #[inline]
/* const */ fn bool_to_internal(x: bool) -> $elem_ty { // $elem_ty is, e.g., i32
if x {
!(0 as $elem_ty)
} else {
0 as $elem_ty
}
} The #[inline]
pub /*const*/ fn new($($elem_name: bool),*) -> Self {
$id($(Self::bool_to_internal($elem_name)),*)
} and currently cannot be |
Ah, so this is only about the boolean consts? And probably only the platform specific types? In any case note that this RFC just gives you lazy evaluation of the branches (and more natural syntax). In simple cases like selecting between |
This is only about the portable boolean vector types (they work portably across platforms).
Oh, I did not know about that! Thanks! That should work for |
Why not just cast the boolean to an integer (giving you either This is usually seen in branchless selects, where |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period is now complete. |
Huzzah! The RFC has been accepted. Tracking issue: rust-lang/rust#49146 |
y - x | ||
} | ||
} | ||
const AB: u32 = foo(x, y); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't that be foo(X, Y)
?
Enable
if
andmatch
during const evaluation and make them evaluate lazily.In short, this will allow
if x < y { y - x } else { x - y }
even though theelse branch would emit an overflow error for unsigned types if
x < y
.Rendered
Tracking issue