Auto merge of #141883 - oli-obk:remove-check-mod-loops, r=nnethercote
Remove check_mod_loops query and run the checks per-body instead This analysis is older than my first rustc contribution I believe. It was never querified. Ideally we'd merge it into the analysis happening within typeck anyway (typeck just uses span_delayed_bug instead of erroring), but I didn't want to do that within this PR that also moves things around and subtly changes diagnostic ordering.
This commit is contained in:
commit
1c047506f9
17 changed files with 274 additions and 273 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Span>,
|
||||
pub kind: &'a str,
|
||||
pub suggestion: String,
|
||||
pub loop_label: Option<Label>,
|
||||
pub break_label: Option<Label>,
|
||||
pub break_expr_kind: &'a ExprKind<'a>,
|
||||
pub break_expr_span: Span,
|
||||
}
|
||||
|
||||
impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> {
|
||||
#[track_caller]
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
|
||||
let mut diag = Diag::new(dcx, level, fluent::hir_typeck_break_non_loop);
|
||||
diag.span(self.span);
|
||||
diag.code(E0571);
|
||||
diag.arg("kind", self.kind);
|
||||
diag.span_label(self.span, fluent::hir_typeck_label);
|
||||
if let Some(head) = self.head {
|
||||
diag.span_label(head, fluent::hir_typeck_label2);
|
||||
}
|
||||
diag.span_suggestion(
|
||||
self.span,
|
||||
fluent::hir_typeck_suggestion,
|
||||
self.suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
if let (Some(label), None) = (self.loop_label, self.break_label) {
|
||||
match self.break_expr_kind {
|
||||
ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { segments: [segment], res: hir::def::Res::Err, .. },
|
||||
)) if label.ident.to_string() == format!("'{}", segment.ident) => {
|
||||
// This error is redundant, we will have already emitted a
|
||||
// suggestion to use the label when `segment` wasn't found
|
||||
// (hence the `Res::Err` check).
|
||||
diag.downgrade_to_delayed_bug();
|
||||
}
|
||||
_ => {
|
||||
diag.span_suggestion(
|
||||
self.break_expr_span,
|
||||
fluent::hir_typeck_break_expr_suggestion,
|
||||
label.ident,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_continue_labeled_block, code = E0696)]
|
||||
pub(crate) struct ContinueLabeledBlock {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(hir_typeck_block_label)]
|
||||
pub block_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_break_inside_closure, code = E0267)]
|
||||
pub(crate) struct BreakInsideClosure<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(hir_typeck_closure_label)]
|
||||
pub closure_span: Span,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_break_inside_coroutine, code = E0267)]
|
||||
pub(crate) struct BreakInsideCoroutine<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(hir_typeck_coroutine_label)]
|
||||
pub coroutine_span: Span,
|
||||
pub name: &'a str,
|
||||
pub kind: &'a str,
|
||||
pub source: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_outside_loop, code = E0268)]
|
||||
pub(crate) struct OutsideLoop<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub spans: Vec<Span>,
|
||||
pub name: &'a str,
|
||||
pub is_break: bool,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: Option<OutsideLoopSuggestion>,
|
||||
}
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(hir_typeck_outside_loop_suggestion, applicability = "maybe-incorrect")]
|
||||
pub(crate) struct OutsideLoopSuggestion {
|
||||
#[suggestion_part(code = "'block: ")]
|
||||
pub block_span: Span,
|
||||
#[suggestion_part(code = " 'block")]
|
||||
pub break_spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_unlabeled_in_labeled_block, code = E0695)]
|
||||
pub(crate) struct UnlabeledInLabeledBlock<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub cf_type: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_unlabeled_cf_in_while_condition, code = E0590)]
|
||||
pub(crate) struct UnlabeledCfInWhileCondition<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub cf_type: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_no_associated_item, code = E0599)]
|
||||
pub(crate) struct NoAssociatedItem {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ mod fallback;
|
|||
mod fn_ctxt;
|
||||
mod gather_locals;
|
||||
mod intrinsicck;
|
||||
mod loops;
|
||||
mod method;
|
||||
mod naked_functions;
|
||||
mod op;
|
||||
|
|
@ -149,6 +150,7 @@ fn typeck_with_inspect<'tcx>(
|
|||
};
|
||||
|
||||
check_abi(tcx, id, span, fn_sig.abi());
|
||||
loops::check(tcx, def_id, body);
|
||||
|
||||
// Compute the function signature from point of view of inside the fn.
|
||||
let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
|
||||
|
|
@ -189,6 +191,8 @@ fn typeck_with_inspect<'tcx>(
|
|||
tcx.type_of(def_id).instantiate_identity()
|
||||
};
|
||||
|
||||
loops::check(tcx, def_id, body);
|
||||
|
||||
let expected_type = fcx.normalize(body.value.span, expected_type);
|
||||
|
||||
let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ use std::fmt;
|
|||
|
||||
use Context::*;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{Destination, Node};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
|
|
@ -73,17 +73,17 @@ struct CheckLoopVisitor<'tcx> {
|
|||
block_breaks: BTreeMap<Span, BlockInfo>,
|
||||
}
|
||||
|
||||
fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
|
||||
pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
|
||||
let mut check =
|
||||
CheckLoopVisitor { tcx, cx_stack: vec![Normal], block_breaks: Default::default() };
|
||||
tcx.hir_visit_item_likes_in_module(module_def_id, &mut check);
|
||||
let cx = match tcx.def_kind(def_id) {
|
||||
DefKind::AnonConst => AnonConst,
|
||||
_ => Fn,
|
||||
};
|
||||
check.with_context(cx, |v| v.visit_body(body));
|
||||
check.report_outside_loop_error();
|
||||
}
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { check_mod_loops, ..*providers };
|
||||
}
|
||||
|
||||
impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
|
||||
type NestedFilter = nested_filter::OnlyBodies;
|
||||
|
||||
|
|
@ -91,33 +91,14 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
|
||||
self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
|
||||
fn visit_anon_const(&mut self, _: &'hir hir::AnonConst) {
|
||||
// Typecked on its own.
|
||||
}
|
||||
|
||||
fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
|
||||
self.with_context(ConstBlock, |v| intravisit::walk_inline_const(v, c));
|
||||
}
|
||||
|
||||
fn visit_fn(
|
||||
&mut self,
|
||||
fk: hir::intravisit::FnKind<'hir>,
|
||||
fd: &'hir hir::FnDecl<'hir>,
|
||||
b: hir::BodyId,
|
||||
_: Span,
|
||||
id: LocalDefId,
|
||||
) {
|
||||
self.with_context(Fn, |v| intravisit::walk_fn(v, fk, fd, b, id));
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &'hir hir::TraitItem<'hir>) {
|
||||
self.with_context(Fn, |v| intravisit::walk_trait_item(v, trait_item));
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'hir hir::ImplItem<'hir>) {
|
||||
self.with_context(Fn, |v| intravisit::walk_impl_item(v, impl_item));
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
||||
match e.kind {
|
||||
hir::ExprKind::If(cond, then, else_opt) => {
|
||||
|
|
@ -954,7 +954,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
|
|||
tcx.ensure_ok().exportable_items(LOCAL_CRATE);
|
||||
tcx.ensure_ok().stable_order_of_exportable_impls(LOCAL_CRATE);
|
||||
tcx.par_hir_for_each_module(|module| {
|
||||
tcx.ensure_ok().check_mod_loops(module);
|
||||
tcx.ensure_ok().check_mod_attrs(module);
|
||||
tcx.ensure_ok().check_mod_unstable_api_usage(module);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1115,11 +1115,6 @@ rustc_queries! {
|
|||
desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
|
||||
}
|
||||
|
||||
/// Checks the loops in the module.
|
||||
query check_mod_loops(key: LocalModDefId) {
|
||||
desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
|
||||
}
|
||||
|
||||
query check_mod_privacy(key: LocalModDefId) {
|
||||
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,23 +56,6 @@ passes_autodiff_attr =
|
|||
passes_both_ffi_const_and_pure =
|
||||
`#[ffi_const]` function cannot be `#[ffi_pure]`
|
||||
|
||||
passes_break_inside_closure =
|
||||
`{$name}` inside of a closure
|
||||
.label = cannot `{$name}` inside of a closure
|
||||
.closure_label = enclosing closure
|
||||
|
||||
passes_break_inside_coroutine =
|
||||
`{$name}` inside `{$kind}` {$source}
|
||||
.label = cannot `{$name}` inside `{$kind}` {$source}
|
||||
.coroutine_label = enclosing `{$kind}` {$source}
|
||||
|
||||
passes_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
|
||||
|
||||
passes_cannot_stabilize_deprecated =
|
||||
an API can't be stabilized after it is deprecated
|
||||
.label = invalid version
|
||||
|
|
@ -103,10 +86,6 @@ passes_const_stable_not_stable =
|
|||
attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]`
|
||||
.label = attribute specified here
|
||||
|
||||
passes_continue_labeled_block =
|
||||
`continue` pointing to a labeled block
|
||||
.label = labeled blocks cannot be `continue`'d
|
||||
.block_label = labeled block the `continue` points to
|
||||
|
||||
passes_coroutine_on_non_closure =
|
||||
attribute should be applied to closures
|
||||
|
|
@ -574,17 +553,6 @@ passes_optimize_invalid_target =
|
|||
passes_outer_crate_level_attr =
|
||||
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
|
||||
|
||||
passes_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] {""}
|
||||
}
|
||||
|
||||
passes_outside_loop_suggestion = consider labeling this block to be able to break within it
|
||||
|
||||
passes_panic_unwind_without_std =
|
||||
unwinding panics are not supported without std
|
||||
|
|
@ -752,14 +720,6 @@ passes_unknown_lang_item =
|
|||
definition of an unknown lang item: `{$name}`
|
||||
.label = definition of unknown lang item `{$name}`
|
||||
|
||||
passes_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
|
||||
|
||||
passes_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
|
||||
|
||||
passes_unnecessary_partial_stable_feature = the feature `{$feature}` has been partially stabilized since {$since} and is succeeded by the feature `{$implies}`
|
||||
.suggestion = if you are using features which are still unstable, change to using `{$implies}`
|
||||
.suggestion_remove = if you are using features which are now stable, remove this line
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
use std::io::Error;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use rustc_ast::Label;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
|
||||
MultiSpan, Subdiagnostic,
|
||||
};
|
||||
use rustc_hir::{self as hir, ExprKind, Target};
|
||||
use rustc_hir::Target;
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::{MainDefinition, Ty};
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
|
|
@ -1071,131 +1070,6 @@ pub(crate) struct FeaturePreviouslyDeclared<'a> {
|
|||
pub prev_declared: &'a str,
|
||||
}
|
||||
|
||||
pub(crate) struct BreakNonLoop<'a> {
|
||||
pub span: Span,
|
||||
pub head: Option<Span>,
|
||||
pub kind: &'a str,
|
||||
pub suggestion: String,
|
||||
pub loop_label: Option<Label>,
|
||||
pub break_label: Option<Label>,
|
||||
pub break_expr_kind: &'a ExprKind<'a>,
|
||||
pub break_expr_span: Span,
|
||||
}
|
||||
|
||||
impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> {
|
||||
#[track_caller]
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
|
||||
let mut diag = Diag::new(dcx, level, fluent::passes_break_non_loop);
|
||||
diag.span(self.span);
|
||||
diag.code(E0571);
|
||||
diag.arg("kind", self.kind);
|
||||
diag.span_label(self.span, fluent::passes_label);
|
||||
if let Some(head) = self.head {
|
||||
diag.span_label(head, fluent::passes_label2);
|
||||
}
|
||||
diag.span_suggestion(
|
||||
self.span,
|
||||
fluent::passes_suggestion,
|
||||
self.suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
if let (Some(label), None) = (self.loop_label, self.break_label) {
|
||||
match self.break_expr_kind {
|
||||
ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { segments: [segment], res: hir::def::Res::Err, .. },
|
||||
)) if label.ident.to_string() == format!("'{}", segment.ident) => {
|
||||
// This error is redundant, we will have already emitted a
|
||||
// suggestion to use the label when `segment` wasn't found
|
||||
// (hence the `Res::Err` check).
|
||||
diag.downgrade_to_delayed_bug();
|
||||
}
|
||||
_ => {
|
||||
diag.span_suggestion(
|
||||
self.break_expr_span,
|
||||
fluent::passes_break_expr_suggestion,
|
||||
label.ident,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_continue_labeled_block, code = E0696)]
|
||||
pub(crate) struct ContinueLabeledBlock {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(passes_block_label)]
|
||||
pub block_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_break_inside_closure, code = E0267)]
|
||||
pub(crate) struct BreakInsideClosure<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(passes_closure_label)]
|
||||
pub closure_span: Span,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_break_inside_coroutine, code = E0267)]
|
||||
pub(crate) struct BreakInsideCoroutine<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(passes_coroutine_label)]
|
||||
pub coroutine_span: Span,
|
||||
pub name: &'a str,
|
||||
pub kind: &'a str,
|
||||
pub source: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_outside_loop, code = E0268)]
|
||||
pub(crate) struct OutsideLoop<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub spans: Vec<Span>,
|
||||
pub name: &'a str,
|
||||
pub is_break: bool,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: Option<OutsideLoopSuggestion>,
|
||||
}
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(passes_outside_loop_suggestion, applicability = "maybe-incorrect")]
|
||||
pub(crate) struct OutsideLoopSuggestion {
|
||||
#[suggestion_part(code = "'block: ")]
|
||||
pub block_span: Span,
|
||||
#[suggestion_part(code = " 'block")]
|
||||
pub break_spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_unlabeled_in_labeled_block, code = E0695)]
|
||||
pub(crate) struct UnlabeledInLabeledBlock<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub cf_type: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_unlabeled_cf_in_while_condition, code = E0590)]
|
||||
pub(crate) struct UnlabeledCfInWhileCondition<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub cf_type: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
|
||||
pub(crate) struct NakedFunctionIncompatibleAttribute {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ mod lang_items;
|
|||
pub mod layout_test;
|
||||
mod lib_features;
|
||||
mod liveness;
|
||||
pub mod loops;
|
||||
mod reachable;
|
||||
pub mod stability;
|
||||
mod upvars;
|
||||
|
|
@ -45,7 +44,6 @@ pub fn provide(providers: &mut Providers) {
|
|||
entry::provide(providers);
|
||||
lang_items::provide(providers);
|
||||
lib_features::provide(providers);
|
||||
loops::provide(providers);
|
||||
liveness::provide(providers);
|
||||
reachable::provide(providers);
|
||||
stability::provide(providers);
|
||||
|
|
|
|||
|
|
@ -1,19 +1,3 @@
|
|||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:32:9
|
||||
|
|
||||
LL | async {
|
||||
| ----- enclosing `async` block
|
||||
LL | break 0u8;
|
||||
| ^^^^^^^^^ cannot `break` inside `async` block
|
||||
|
||||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:39:13
|
||||
|
|
||||
LL | async {
|
||||
| ----- enclosing `async` block
|
||||
LL | break 0u8;
|
||||
| ^^^^^^^^^ cannot `break` inside `async` block
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:21:58
|
||||
|
|
||||
|
|
@ -50,6 +34,22 @@ LL | let _: &dyn Future<Output = ()> = █
|
|||
|
|
||||
= note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 14:22}` to `&dyn Future<Output = ()>`
|
||||
|
||||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:32:9
|
||||
|
|
||||
LL | async {
|
||||
| ----- enclosing `async` block
|
||||
LL | break 0u8;
|
||||
| ^^^^^^^^^ cannot `break` inside `async` block
|
||||
|
||||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:39:13
|
||||
|
|
||||
LL | async {
|
||||
| ----- enclosing `async` block
|
||||
LL | break 0u8;
|
||||
| ^^^^^^^^^ cannot `break` inside `async` block
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -10,17 +10,6 @@ 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:2:21
|
||||
|
|
||||
LL | let _ = ['a'; { break 2; 1 }];
|
||||
| ^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
|
||||
help: consider labeling this block to be able to break within it
|
||||
|
|
||||
LL | let _ = ['a'; 'block: { break 'block 2; 1 }];
|
||||
| +++++++ ++++++
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-inline-const-issue-128604.rs:9:13
|
||||
|
|
||||
|
|
@ -34,6 +23,29 @@ LL |
|
|||
LL ~ break 'block;
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-inline-const-issue-128604.rs:2:21
|
||||
|
|
||||
LL | let _ = ['a'; { break 2; 1 }];
|
||||
| ^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
|
||||
help: consider labeling this block to be able to break within it
|
||||
|
|
||||
LL | let _ = ['a'; 'block: { break 'block 2; 1 }];
|
||||
| +++++++ ++++++
|
||||
|
||||
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: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,16 @@ LL | const { async {}.await }
|
|||
| | only allowed inside `async` functions and blocks
|
||||
| this is not `async`
|
||||
|
||||
error[E0572]: return statement outside of function body
|
||||
--> $DIR/cross-const-control-flow-125846.rs:4:13
|
||||
|
|
||||
LL | / fn foo() {
|
||||
LL | | const { return }
|
||||
| | --^^^^^^-- the return is part of this body...
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_- ...not the enclosing function body
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/cross-const-control-flow-125846.rs:9:19
|
||||
|
|
||||
|
|
@ -63,16 +73,6 @@ error[E0268]: `continue` outside of a loop
|
|||
LL | const { continue }
|
||||
| ^^^^^^^^ cannot `continue` outside of a loop
|
||||
|
||||
error[E0572]: return statement outside of function body
|
||||
--> $DIR/cross-const-control-flow-125846.rs:4:13
|
||||
|
|
||||
LL | / fn foo() {
|
||||
LL | | const { return }
|
||||
| | --^^^^^^-- the return is part of this body...
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_- ...not the enclosing function body
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0268, E0435, E0572, E0728, E0767.
|
||||
|
|
|
|||
|
|
@ -4,12 +4,6 @@ error[E0268]: `break` outside of a loop or labeled block
|
|||
LL | break true;
|
||||
| ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/issue-43162.rs:7:5
|
||||
|
|
||||
LL | break {};
|
||||
| ^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-43162.rs:1:13
|
||||
|
|
||||
|
|
@ -18,6 +12,12 @@ LL | fn foo() -> bool {
|
|||
| |
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/issue-43162.rs:7:5
|
||||
|
|
||||
LL | break {};
|
||||
| ^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0268, E0308.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0268]: `break` outside of a loop or labeled block
|
|||
|
|
||||
LL | break rust
|
||||
| ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
|
||||
-Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC
|
||||
|
||||
error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
|
||||
--> $DIR/track.rs:LL:CC
|
||||
|
|
|
|||
|
|
@ -1,3 +1,21 @@
|
|||
error[E0571]: `break` with value from a `while` loop
|
||||
--> $DIR/issue-114529-illegal-break-with-value.rs:22:9
|
||||
|
|
||||
LL | while true {
|
||||
| ---------- you can't `break` with a value in a `while` loop
|
||||
LL | / break (|| {
|
||||
LL | | let local = 9;
|
||||
LL | | });
|
||||
| |__________^ can only break with a value inside `loop` or breakable block
|
||||
|
|
||||
help: use `break` on its own without a value inside this `while` loop
|
||||
|
|
||||
LL - break (|| {
|
||||
LL - let local = 9;
|
||||
LL - });
|
||||
LL + break;
|
||||
|
|
||||
|
||||
error[E0571]: `break` with value from a `while` loop
|
||||
--> $DIR/issue-114529-illegal-break-with-value.rs:9:13
|
||||
|
|
||||
|
|
@ -26,24 +44,6 @@ LL - break v;
|
|||
LL + break;
|
||||
|
|
||||
|
||||
error[E0571]: `break` with value from a `while` loop
|
||||
--> $DIR/issue-114529-illegal-break-with-value.rs:22:9
|
||||
|
|
||||
LL | while true {
|
||||
| ---------- you can't `break` with a value in a `while` loop
|
||||
LL | / break (|| {
|
||||
LL | | let local = 9;
|
||||
LL | | });
|
||||
| |__________^ can only break with a value inside `loop` or breakable block
|
||||
|
|
||||
help: use `break` on its own without a value inside this `while` loop
|
||||
|
|
||||
LL - break (|| {
|
||||
LL - let local = 9;
|
||||
LL - });
|
||||
LL + break;
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0571`.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
|
||||
|
|
||||
LL | let a = ["_"; unsafe { break; 1 + 2 }];
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:14:9
|
||||
|
|
||||
|
|
@ -37,6 +31,12 @@ LL | unsafe {
|
|||
LL ~ break 'block;
|
||||
|
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
|
||||
|
|
||||
LL | let a = ["_"; unsafe { break; 1 + 2 }];
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue