diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a6ea4aa8923cf..6027027428eee 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -100,10 +100,13 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::If(ref cond, ref then, ref else_opt) => { self.lower_expr_if(cond, then, else_opt.as_deref()) } - ExprKind::While(ref cond, ref body, opt_label) => self - .with_loop_scope(e.id, |this| { - this.lower_expr_while_in_loop_scope(e.span, cond, body, opt_label) - }), + ExprKind::While(ref cond, ref body, opt_label) => { + self.with_loop_scope(e.id, |this| { + let span = + this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); + this.lower_expr_while_in_loop_scope(span, cond, body, opt_label) + }) + } ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| { hir::ExprKind::Loop( this.lower_block(body, false), diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 60cb78d902ee6..37fec0ac38cc5 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -389,9 +389,9 @@ pub fn struct_lint_level<'s, 'd>( pub fn in_external_macro(sess: &Session, span: Span) -> bool { let expn_data = span.ctxt().outer_expn_data(); match expn_data.kind { - ExpnKind::Inlined | ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop(_)) => { - false - } + ExpnKind::Inlined + | ExpnKind::Root + | ExpnKind::Desugaring(DesugaringKind::ForLoop(_) | DesugaringKind::WhileLoop) => false, ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { // Dummy span for the `def_site` means it's an external macro. diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 29af6b38bf47b..aa15febe8853d 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1101,6 +1101,7 @@ pub enum DesugaringKind { Await, ForLoop(ForLoopLoc), LetElse, + WhileLoop, } /// A location in the desugaring of a `for` loop @@ -1122,6 +1123,7 @@ impl DesugaringKind { DesugaringKind::OpaqueTy => "`impl Trait`", DesugaringKind::ForLoop(_) => "`for` loop", DesugaringKind::LetElse => "`let...else`", + DesugaringKind::WhileLoop => "`while` loop", } } } diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 79763942d05d9..e34b8d998b1c9 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -54,7 +54,7 @@ use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, ToPredicate, Ty, TypeAndMut}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; -use rustc_span::{self, BytePos, Span}; +use rustc_span::{self, BytePos, DesugaringKind, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; @@ -1536,8 +1536,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // If the block is from an external macro or try (`?`) desugaring, then // do not suggest adding a semicolon, because there's nowhere to put it. // See issues #81943 and #87051. - if cond_expr.span.desugaring_kind().is_none() - && !in_external_macro(fcx.tcx.sess, cond_expr.span) + if matches!( + cond_expr.span.desugaring_kind(), + None | Some(DesugaringKind::WhileLoop) + ) && !in_external_macro(fcx.tcx.sess, cond_expr.span) && !matches!( cond_expr.kind, hir::ExprKind::Match(.., hir::MatchSource::TryDesugar) diff --git a/src/tools/clippy/tests/ui/crashes/issues_loop_mut_cond.rs b/src/tools/clippy/tests/ui/crashes/issues_loop_mut_cond.rs index 553c840f9b081..bb238c81ebc05 100644 --- a/src/tools/clippy/tests/ui/crashes/issues_loop_mut_cond.rs +++ b/src/tools/clippy/tests/ui/crashes/issues_loop_mut_cond.rs @@ -1,4 +1,3 @@ -#![allow(clippy::blocks_in_if_conditions)] #![allow(dead_code)] /// Issue: https://github.com/rust-lang/rust-clippy/issues/2596 diff --git a/src/tools/clippy/tests/ui/infinite_loop.rs b/src/tools/clippy/tests/ui/infinite_loop.rs index e86bd7bcf4faf..38e64b9ac0ada 100644 --- a/src/tools/clippy/tests/ui/infinite_loop.rs +++ b/src/tools/clippy/tests/ui/infinite_loop.rs @@ -1,5 +1,3 @@ -#![allow(clippy::blocks_in_if_conditions)] - fn fn_val(i: i32) -> i32 { unimplemented!() } diff --git a/src/tools/clippy/tests/ui/infinite_loop.stderr b/src/tools/clippy/tests/ui/infinite_loop.stderr index 69309b0da877c..4ec7d900ade3d 100644 --- a/src/tools/clippy/tests/ui/infinite_loop.stderr +++ b/src/tools/clippy/tests/ui/infinite_loop.stderr @@ -1,5 +1,5 @@ error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:22:11 + --> $DIR/infinite_loop.rs:20:11 | LL | while y < 10 { | ^^^^^^ @@ -8,7 +8,7 @@ LL | while y < 10 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:27:11 + --> $DIR/infinite_loop.rs:25:11 | LL | while y < 10 && x < 3 { | ^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | while y < 10 && x < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:34:11 + --> $DIR/infinite_loop.rs:32:11 | LL | while !cond { | ^^^^^ @@ -24,7 +24,7 @@ LL | while !cond { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:78:11 + --> $DIR/infinite_loop.rs:76:11 | LL | while i < 3 { | ^^^^^ @@ -32,7 +32,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:83:11 + --> $DIR/infinite_loop.rs:81:11 | LL | while i < 3 && j > 0 { | ^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | while i < 3 && j > 0 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:87:11 + --> $DIR/infinite_loop.rs:85:11 | LL | while i < 3 { | ^^^^^ @@ -48,7 +48,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:102:11 + --> $DIR/infinite_loop.rs:100:11 | LL | while i < 3 { | ^^^^^ @@ -56,7 +56,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:107:11 + --> $DIR/infinite_loop.rs:105:11 | LL | while i < 3 { | ^^^^^ @@ -64,7 +64,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:173:15 + --> $DIR/infinite_loop.rs:171:15 | LL | while self.count < n { | ^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | while self.count < n { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:181:11 + --> $DIR/infinite_loop.rs:179:11 | LL | while y < 10 { | ^^^^^^ @@ -82,7 +82,7 @@ LL | while y < 10 { = help: rewrite it as `if cond { loop { } }` error: variables in the condition are not mutated in the loop body - --> $DIR/infinite_loop.rs:188:11 + --> $DIR/infinite_loop.rs:186:11 | LL | while y < 10 { | ^^^^^^