Skip to content

Commit e3fa2da

Browse files
bjorn3folkertdev
andcommitted
Add #[loop_match] for improved DFA codegen
Co-authored-by: Folkert de Vries <[email protected]>
1 parent 19cab6b commit e3fa2da

33 files changed

+1457
-24
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,16 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
583583
EncodeCrossCrate::Yes, min_generic_const_args, experimental!(type_const),
584584
),
585585

586+
// #[loop_match] and #[const_continue]
587+
gated!(
588+
const_continue, Normal, template!(Word), ErrorFollowing,
589+
EncodeCrossCrate::No, loop_match, experimental!(const_continue)
590+
),
591+
gated!(
592+
loop_match, Normal, template!(Word), ErrorFollowing,
593+
EncodeCrossCrate::No, loop_match, experimental!(loop_match)
594+
),
595+
586596
// ==========================================================================
587597
// Internal attributes: Stability, deprecation, and unsafe:
588598
// ==========================================================================

compiler/rustc_feature/src/unstable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ declare_features! (
546546
/// Allows using `#[link(kind = "link-arg", name = "...")]`
547547
/// to pass custom arguments to the linker.
548548
(unstable, link_arg_attribute, "1.76.0", Some(99427)),
549+
(unstable, loop_match, "CURRENT_RUSTC_VERSION", Some(138777)),
549550
/// Give access to additional metadata about declarative macro meta-variables.
550551
(unstable, macro_metavar_expr, "1.61.0", Some(83527)),
551552
/// Provides a way to concatenate identifiers using metavariable expressions.

compiler/rustc_middle/src/thir.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@ pub enum ExprKind<'tcx> {
375375
Loop {
376376
body: ExprId,
377377
},
378+
/// A `#[loop_match] loop { state = 'blk: { match state { ... } } }` expression.
379+
LoopMatch {
380+
state: ExprId,
381+
382+
region_scope: region::Scope,
383+
arms: Box<[ArmId]>,
384+
},
378385
/// Special expression representing the `let` part of an `if let` or similar construct
379386
/// (including `if let` guards in match arms, and let-chains formed by `&&`).
380387
///
@@ -451,6 +458,11 @@ pub enum ExprKind<'tcx> {
451458
Continue {
452459
label: region::Scope,
453460
},
461+
/// A `#[const_continue] break` expression.
462+
ConstContinue {
463+
label: region::Scope,
464+
value: ExprId,
465+
},
454466
/// A `return` expression.
455467
Return {
456468
value: Option<ExprId>,

compiler/rustc_middle/src/thir/visit.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
7979
visitor.visit_pat(pat);
8080
}
8181
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
82+
LoopMatch { state, ref arms, .. } => {
83+
visitor.visit_expr(&visitor.thir()[state]);
84+
for &arm in &**arms {
85+
visitor.visit_arm(&visitor.thir()[arm]);
86+
}
87+
}
8288
Match { scrutinee, ref arms, .. } => {
8389
visitor.visit_expr(&visitor.thir()[scrutinee]);
8490
for &arm in &**arms {
@@ -104,6 +110,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
104110
}
105111
}
106112
Continue { label: _ } => {}
113+
ConstContinue { value, label: _ } => visitor.visit_expr(&visitor.thir()[value]),
107114
Return { value } => {
108115
if let Some(value) = value {
109116
visitor.visit_expr(&visitor.thir()[value])

compiler/rustc_mir_build/messages.ftl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
8484
8585
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
8686
87+
mir_build_const_continue_missing_value = a `const_continue` must break to a label with a value
88+
8789
mir_build_const_defined_here = constant defined here
8890
8991
mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns
@@ -212,6 +214,22 @@ mir_build_literal_in_range_out_of_bounds =
212214
literal out of range for `{$ty}`
213215
.label = this value does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
214216
217+
mir_build_loop_match_bad_rhs =
218+
this expression must be a single `match` wrapped in a labelled block
219+
220+
mir_build_loop_match_bad_statements =
221+
statements are not allowed in this position within a `loop_match`
222+
223+
mir_build_loop_match_invalid_match =
224+
invalid match on `loop_match` state
225+
.note = only matches on local variables are valid
226+
mir_build_loop_match_invalid_update =
227+
invalid update of the `loop_match` state
228+
.label = the assignment must update this variable
229+
230+
mir_build_loop_match_missing_assignment =
231+
expected a single assignment expression
232+
215233
mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper =
216234
lower range bound must be less than or equal to upper
217235
.label = lower bound larger than upper bound

compiler/rustc_mir_build/src/builder/expr/as_place.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,12 +562,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
562562
| ExprKind::Match { .. }
563563
| ExprKind::If { .. }
564564
| ExprKind::Loop { .. }
565+
| ExprKind::LoopMatch { .. }
565566
| ExprKind::Block { .. }
566567
| ExprKind::Let { .. }
567568
| ExprKind::Assign { .. }
568569
| ExprKind::AssignOp { .. }
569570
| ExprKind::Break { .. }
570571
| ExprKind::Continue { .. }
572+
| ExprKind::ConstContinue { .. }
571573
| ExprKind::Return { .. }
572574
| ExprKind::Become { .. }
573575
| ExprKind::Literal { .. }

compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
538538
| ExprKind::RawBorrow { .. }
539539
| ExprKind::Adt { .. }
540540
| ExprKind::Loop { .. }
541+
| ExprKind::LoopMatch { .. }
541542
| ExprKind::LogicalOp { .. }
542543
| ExprKind::Call { .. }
543544
| ExprKind::Field { .. }
@@ -548,6 +549,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
548549
| ExprKind::UpvarRef { .. }
549550
| ExprKind::Break { .. }
550551
| ExprKind::Continue { .. }
552+
| ExprKind::ConstContinue { .. }
551553
| ExprKind::Return { .. }
552554
| ExprKind::Become { .. }
553555
| ExprKind::InlineAsm { .. }

compiler/rustc_mir_build/src/builder/expr/category.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,11 @@ impl Category {
8383
| ExprKind::NamedConst { .. } => Some(Category::Constant),
8484

8585
ExprKind::Loop { .. }
86+
| ExprKind::LoopMatch { .. }
8687
| ExprKind::Block { .. }
8788
| ExprKind::Break { .. }
8889
| ExprKind::Continue { .. }
90+
| ExprKind::ConstContinue { .. }
8991
| ExprKind::Return { .. }
9092
| ExprKind::Become { .. } =>
9193
// FIXME(#27840) these probably want their own

0 commit comments

Comments
 (0)