diff options
| author | Jubilee <workingjubilee@gmail.com> | 2025-06-24 19:45:30 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-24 19:45:30 -0700 |
| commit | f542909d1ceae371fe0e236e00276109522fa86d (patch) | |
| tree | 9dc32e189696a4705b9b3f8f6b26fcb6a8a8a4c3 /compiler/rustc_mir_build/src/errors.rs | |
| parent | 4f477427b81bba86e8b761a5fb5b52635b82d54e (diff) | |
| parent | ba5556d239c11232dc8d95123ea70a2783019476 (diff) | |
| download | rust-f542909d1ceae371fe0e236e00276109522fa86d.tar.gz rust-f542909d1ceae371fe0e236e00276109522fa86d.zip | |
Rollup merge of #138780 - trifectatechfoundation:loop_match_attr, r=oli-obk,traviscross
Add `#[loop_match]` for improved DFA codegen
tracking issue: https://github.com/rust-lang/rust/issues/132306
project goal: https://github.com/rust-lang/rust-project-goals/issues/258
This PR adds the `#[loop_match]` attribute, which aims to improve code generation for state machines. For some (very exciting) benchmarks, see https://github.com/rust-lang/rust-project-goals/issues/258#issuecomment-2732965199
Currently, a very restricted syntax pattern is accepted. We'd like to get feedback and merge this now before we go too far in a direction that others have concerns with.
## current state
We accept code that looks like this
```rust
#[loop_match]
loop {
state = 'blk: {
match state {
State::A => {
#[const_continue]
break 'blk State::B
}
State::B => { /* ... */ }
/* ... */
}
}
}
```
- a loop should have the same semantics with and without `#[loop_match]`: normal `continue` and `break` continue to work
- `#[const_continue]` is only allowed in loops annotated with `#[loop_match]`
- the loop body needs to have this particular shape (a single assignment to the match scrutinee, with the body a labelled block containing just a match)
## future work
- perform const evaluation on the `break` value
- support more state/scrutinee types
## maybe future work
- allow `continue 'label value` syntax, which `#[const_continue]` could then use.
- allow the match to be on an arbitrary expression (e.g. `State::Initial`)
- attempt to also optimize `break`/`continue` expressions that are not marked with `#[const_continue]`
r? ``@traviscross``
Diffstat (limited to 'compiler/rustc_mir_build/src/errors.rs')
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index ae09db50235..32df191cbca 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1149,3 +1149,80 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg { } } } + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_invalid_update)] +pub(crate) struct LoopMatchInvalidUpdate { + #[primary_span] + pub lhs: Span, + #[label] + pub scrutinee: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_invalid_match)] +#[note] +pub(crate) struct LoopMatchInvalidMatch { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_unsupported_type)] +#[note] +pub(crate) struct LoopMatchUnsupportedType<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, +} + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_bad_statements)] +pub(crate) struct LoopMatchBadStatements { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_bad_rhs)] +pub(crate) struct LoopMatchBadRhs { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_missing_assignment)] +pub(crate) struct LoopMatchMissingAssignment { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_loop_match_arm_with_guard)] +pub(crate) struct LoopMatchArmWithGuard { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_const_continue_bad_const)] +pub(crate) struct ConstContinueBadConst { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_const_continue_missing_value)] +pub(crate) struct ConstContinueMissingValue { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(mir_build_const_continue_unknown_jump_target)] +#[note] +pub(crate) struct ConstContinueUnknownJumpTarget { + #[primary_span] + pub span: Span, +} |
