From b73bf3c0b52d3fa61f0110f3fc867ca69f9f43ae Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 30 May 2025 16:17:48 +0000 Subject: [PATCH 1/3] Add regression test for break inside const items --- .../break-inside-inline-const-issue-128604.rs | 6 ++++++ .../break-inside-inline-const-issue-128604.stderr | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs index a9795d1569c86..cc0d757885dec 100644 --- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs @@ -23,3 +23,9 @@ fn main() { } } } + +const FOO: () = break; +//~^ ERROR: `break` outside of a loop or labeled block + +static BAR: () = break; +//~^ ERROR: `break` outside of a loop or labeled block diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr index 300cd45ad6912..dcd571a028b9f 100644 --- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr @@ -10,6 +10,18 @@ error[E0268]: `break` outside of a loop or labeled block LL | break; | ^^^^^ cannot `break` outside of a loop or labeled block +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-inside-inline-const-issue-128604.rs:27:17 + | +LL | const FOO: () = break; + | ^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-inside-inline-const-issue-128604.rs:30:18 + | +LL | static BAR: () = break; + | ^^^^^ cannot `break` outside of a loop or labeled block + error[E0268]: `break` outside of a loop or labeled block --> $DIR/break-inside-inline-const-issue-128604.rs:2:21 | @@ -34,6 +46,6 @@ LL | LL ~ break 'block; | -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0268`. From 1b9d38dd08d2e09b2ea6b18a0201252203f63e27 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 30 May 2025 16:01:00 +0000 Subject: [PATCH 2/3] Remove check_mod_loops query and run the checks per-body instead --- compiler/rustc_hir_typeck/messages.ftl | 44 ++++++ compiler/rustc_hir_typeck/src/errors.rs | 128 ++++++++++++++++++ compiler/rustc_hir_typeck/src/lib.rs | 9 ++ .../src/loops.rs | 30 +--- compiler/rustc_interface/src/passes.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 5 - compiler/rustc_passes/messages.ftl | 40 ------ compiler/rustc_passes/src/errors.rs | 128 +----------------- compiler/rustc_passes/src/lib.rs | 2 - ...block-control-flow-static-semantics.stderr | 32 ++--- ...ak-inside-inline-const-issue-128604.stderr | 24 ++-- .../cross-const-control-flow-125846.stderr | 20 +-- tests/ui/loops/issue-43162.stderr | 12 +- tests/ui/track-diagnostics/track.stderr | 2 +- 14 files changed, 230 insertions(+), 247 deletions(-) rename compiler/{rustc_passes => rustc_hir_typeck}/src/loops.rs (93%) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 6c33dfb4ec050..3bdd1b48666e0 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -17,6 +17,24 @@ hir_typeck_base_expression_double_dot_enable_default_field_values = add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields hir_typeck_base_expression_double_dot_remove = remove the `..` as all the fields are already present +hir_typeck_break_inside_closure = + `{$name}` inside of a closure + .label = cannot `{$name}` inside of a closure + .closure_label = enclosing closure + +hir_typeck_break_inside_coroutine = + `{$name}` inside `{$kind}` {$source} + .label = cannot `{$name}` inside `{$kind}` {$source} + .coroutine_label = enclosing `{$kind}` {$source} + +hir_typeck_break_non_loop = + `break` with value from a `{$kind}` loop + .label = can only break with a value inside `loop` or breakable block + .label2 = you can't `break` with a value in a `{$kind}` loop + .suggestion = use `break` on its own without a value inside this `{$kind}` loop + .break_expr_suggestion = alternatively, you might have meant to use the available loop label + + hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> [NONE] {""} [implement] , perhaps you need to implement it @@ -64,6 +82,12 @@ hir_typeck_const_select_must_be_fn = this argument must be a function item .note = expected a function item, found {$ty} .help = consult the documentation on `const_eval_select` for more information +hir_typeck_continue_labeled_block = + `continue` pointing to a labeled block + .label = labeled blocks cannot be `continue`'d + .block_label = labeled block the `continue` points to + + hir_typeck_convert_to_str = try converting the passed type into a `&str` hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `{$expected}` @@ -182,6 +206,19 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` +hir_typeck_outside_loop = + `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + .label = cannot `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + +hir_typeck_outside_loop_suggestion = consider labeling this block to be able to break within it + + hir_typeck_params_not_allowed = referencing function parameters is not allowed in naked functions .help = follow the calling convention in asm block to use parameters @@ -254,6 +291,13 @@ hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field +hir_typeck_unlabeled_cf_in_while_condition = + `break` or `continue` with no label in the condition of a `while` loop + .label = unlabeled `{$cf_type}` in the condition of a `while` loop + +hir_typeck_unlabeled_in_labeled_block = + unlabeled `{$cf_type}` inside of a labeled block + .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label hir_typeck_use_is_empty = consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 97a90548fc54a..774815015d542 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -2,11 +2,14 @@ use std::borrow::Cow; +use rustc_ast::Label; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, }; +use rustc_hir as hir; +use rustc_hir::ExprKind; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; @@ -721,6 +724,131 @@ pub(crate) struct TrivialCast<'tcx> { pub cast_ty: Ty<'tcx>, } +pub(crate) struct BreakNonLoop<'a> { + pub span: Span, + pub head: Option, + pub kind: &'a str, + pub suggestion: String, + pub loop_label: Option