From e1663b69bf6e0f5b69c3490b7f66cb8a2113bb99 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 19 Oct 2026 16:54:00 +0200 Subject: [PATCH] Don't emit allow attributes in try/contract desugaring --- compiler/rustc_ast_lowering/src/contract.rs | 5 --- compiler/rustc_ast_lowering/src/expr.rs | 35 +++++------------ .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 + ...ible_struct_drop.build.ElaborateDrops.diff | 38 +++++-------------- ....test.ElaborateDrops.after.panic-abort.mir | 6 +-- ...test.ElaborateDrops.after.panic-unwind.mir | 6 +-- ...ng.identity.JumpThreading.panic-abort.diff | 26 ++++++------- ...g.identity.JumpThreading.panic-unwind.diff | 26 ++++++------- ...ts.runtime-optimized.after.panic-abort.mir | 6 +-- ...s.runtime-optimized.after.panic-unwind.mir | 6 +-- ..._question_mark.runtime-optimized.after.mir | 16 +++----- ...e_const_switch.identity.JumpThreading.diff | 24 +++++------- tests/ui/inference/issue-71309.stderr | 4 +- tests/ui/unpretty/exhaustive.hir.stdout | 20 ++-------- 14 files changed, 68 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index cbfeda33040e7..9ceec41533d8e 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -1,9 +1,7 @@ use std::sync::Arc; use rustc_attr_ir::lang_items::LangItem; -use rustc_attr_ir::target::Target; use rustc_span::sym; -use thin_vec::thin_vec; use crate::LoweringContext; @@ -351,9 +349,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ), )); - let attrs: rustc_ast::AttrVec = thin_vec![self.unreachable_code_attr(span)]; - self.lower_attrs(contract_check.hir_id, &attrs, span, Target::Expression); - let ret_block = self.block_all(span, arena_vec![self; ret_stmt], Some(contract_check)); self.arena.alloc(self.expr_block(self.arena.alloc(ret_block))) } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index f4bfec24e3b1b..c10ad4b2a398c 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -16,7 +16,7 @@ use rustc_session::diagnostics::report_lit_error; use rustc_span::{ ByteSymbol, DUMMY_SP, DesugaringKind, Ident, Span, Spanned, Symbol, respan, span_bug, sym, }; -use thin_vec::{ThinVec, thin_vec}; +use thin_vec::ThinVec; mod closure; use crate::diagnostics::{ @@ -1933,13 +1933,14 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `ExprKind::Try` from: `?` into: /// ```ignore (pseudo-rust) /// match Try::branch() { - /// ControlFlow::Continue(val) => #[allow(unreachable_code)] val,, + /// ControlFlow::Continue(val) => val, /// ControlFlow::Break(residual) => - /// #[allow(unreachable_code)] - /// // If there is an enclosing `try {...}`: - /// break 'catch_target Residual::into_try_type(residual), + /// // If there is an enclosing homogeneous `try {...}`: + /// break 'catch_target residual_into_try_type(residual), + /// // If there is an enclosing heterogeneous`try {...}`: + /// break 'catch_target FromResidual::from_residual(residual), /// // Otherwise: - /// return Try::from_residual(residual), + /// return FromResidual::from_residual(residual), /// } /// ``` fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir> { @@ -1967,21 +1968,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }; - let attrs: AttrVec = thin_vec![self.unreachable_code_attr(try_span)]; - - // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` + // `ControlFlow::Continue(val) => val,` let continue_arm = { let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident); let val_expr = self.expr_ident(span, val_ident, val_pat_nid); - self.lower_attrs(val_expr.hir_id, &attrs, span, Target::Expression); let continue_pat = self.pat_cf_continue(unstable_span, val_pat); self.arm(continue_pat, val_expr, try_span) }; - // `ControlFlow::Break(residual) => - // #[allow(unreachable_code)] - // return Try::from_residual(residual),` + // `ControlFlow::Break(residual) => (residual),` let break_arm = { let residual_ident = Ident::with_dummy_span(sym::residual); let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident); @@ -2016,7 +2012,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let ret_expr = self.checked_return(Some(from_residual_expr)); self.arena.alloc(self.expr(try_span, ret_expr)) }; - self.lower_attrs(ret_expr.hir_id, &attrs, span, Target::Expression); let break_pat = self.pat_cf_break(try_span, residual_local); self.arm(break_pat, ret_expr, try_span) @@ -2357,18 +2352,6 @@ impl<'hir> LoweringContext<'_, 'hir> { body: expr, } } - - /// `#[allow(unreachable_code)]` - pub(super) fn unreachable_code_attr(&mut self, span: Span) -> Attribute { - let attr = attr::mk_attr_nested_word( - &self.tcx.sess.psess.attr_id_generator, - AttrStyle::Outer, - sym::allow, - sym::unreachable_code, - span, - ); - attr - } } /// Used by [`LoweringContext::make_lowered_await`] to customize the desugaring based on what kind diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9e3e3d810345e..e3fffc04246f8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -84,6 +84,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `.await` operator. Some(DesugaringKind::Await) => return, + // Don't lint *within* contract attrs + Some(DesugaringKind::Contract) => return, _ => {} } diff --git a/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff b/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff index b6085e6c9b23b..94ff83194794f 100644 --- a/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff +++ b/tests/mir-opt/building/fallible_struct_drop.build.ElaborateDrops.diff @@ -61,53 +61,33 @@ + let mut _56: bool; scope 1 { debug residual => _9; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _12; - scope 4 { - } } - scope 5 { + scope 3 { debug residual => _19; - scope 6 { - } } - scope 7 { + scope 4 { debug val => _22; - scope 8 { - } } - scope 9 { + scope 5 { debug residual => _29; - scope 10 { - } } - scope 11 { + scope 6 { debug val => _32; - scope 12 { - } } - scope 13 { + scope 7 { debug residual => _39; - scope 14 { - } } - scope 15 { + scope 8 { debug val => _42; - scope 16 { - } } - scope 17 { + scope 9 { debug residual => _49; - scope 18 { - } } - scope 19 { + scope 10 { debug val => _52; - scope 20 { - } } bb0: { diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir index e8efb9b7c3483..e637c79b33ff7 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-abort.mir @@ -15,13 +15,9 @@ fn test() -> Option> { let _11: u32; scope 1 { debug residual => _8; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _11; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir index 4da1eed4484bb..d99f5f8fcafb6 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.after.panic-unwind.mir @@ -15,13 +15,9 @@ fn test() -> Option> { let _11: u32; scope 1 { debug residual => _8; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _11; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff index a822ca20a8e80..c3525ea8e368e 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff @@ -14,32 +14,28 @@ let _9: i32; scope 1 { debug residual => _6; - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let mut _14: isize; - let _15: i32; - let mut _16: i32; - let mut _17: bool; - scope 9 { - scope 10 (inlined >::from) { - } + scope 6 (inlined #[track_caller] as FromResidual>>::from_residual) { + let mut _14: isize; + let _15: i32; + let mut _16: i32; + let mut _17: bool; + scope 7 { + scope 8 (inlined >::from) { } } } } - scope 3 { + scope 2 { debug val => _9; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _10: isize; let _11: i32; let _12: i32; let mut _13: std::result::Result; - scope 6 { + scope 4 { } - scope 7 { + scope 5 { } } diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff index a822ca20a8e80..c3525ea8e368e 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff @@ -14,32 +14,28 @@ let _9: i32; scope 1 { debug residual => _6; - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let mut _14: isize; - let _15: i32; - let mut _16: i32; - let mut _17: bool; - scope 9 { - scope 10 (inlined >::from) { - } + scope 6 (inlined #[track_caller] as FromResidual>>::from_residual) { + let mut _14: isize; + let _15: i32; + let mut _16: i32; + let mut _17: bool; + scope 7 { + scope 8 (inlined >::from) { } } } } - scope 3 { + scope 2 { debug val => _9; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _10: isize; let _11: i32; let _12: i32; let mut _13: std::result::Result; - scope 6 { + scope 4 { } - scope 7 { + scope 5 { } } diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir index 5a9f8b2cc466b..36a0b991ef5dc 100644 --- a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-abort.mir @@ -9,13 +9,9 @@ fn option_traits(_1: Option) -> Option { let mut _5: u32; scope 1 { debug residual => const Option::::None; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _4; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir index 8d272ac3485f1..8f785ce59d58d 100644 --- a/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/option_bubble_debug.option_traits.runtime-optimized.after.panic-unwind.mir @@ -9,13 +9,9 @@ fn option_traits(_1: Option) -> Option { let mut _5: u32; scope 1 { debug residual => const Option::::None; - scope 2 { - } } - scope 3 { + scope 2 { debug val => _4; - scope 4 { - } } bb0: { diff --git a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir index 3c559614e9863..cde5538f54ad5 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.runtime-optimized.after.mir @@ -9,22 +9,18 @@ fn map_via_question_mark(_1: Option) -> Option { let mut _9: i32; scope 1 { debug residual => const Option::::None; - scope 2 { - scope 7 (inlined as FromResidual>>::from_residual) { - let mut _3: isize; - let mut _5: bool; - } + scope 5 (inlined as FromResidual>>::from_residual) { + let mut _3: isize; + let mut _5: bool; } } - scope 3 { + scope 2 { debug val => _8; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _2: isize; let _6: i32; - scope 6 { + scope 4 { } } diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff index be29296044837..a115cb21e7d7c 100644 --- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff +++ b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff @@ -10,31 +10,27 @@ let _5: i32; scope 1 { debug residual => _4; - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let mut _10: isize; - let _11: i32; - let mut _12: bool; - scope 9 { - scope 10 (inlined >::from) { - } + scope 6 (inlined #[track_caller] as FromResidual>>::from_residual) { + let mut _10: isize; + let _11: i32; + let mut _12: bool; + scope 7 { + scope 8 (inlined >::from) { } } } } - scope 3 { + scope 2 { debug val => _5; - scope 4 { - } } - scope 5 (inlined as Try>::branch) { + scope 3 (inlined as Try>::branch) { let mut _6: isize; let _7: i32; let _8: i32; let mut _9: std::result::Result; - scope 6 { + scope 4 { } - scope 7 { + scope 5 { } } diff --git a/tests/ui/inference/issue-71309.stderr b/tests/ui/inference/issue-71309.stderr index a96cbccf02708..673649c767e3d 100644 --- a/tests/ui/inference/issue-71309.stderr +++ b/tests/ui/inference/issue-71309.stderr @@ -7,8 +7,8 @@ LL | let y: u32 = x?; = note: `?` operator cannot convert from `i32` to `u32` help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit | -LL | let y: u32 = (x?).try_into().unwrap(); - | + +++++++++++++++++++++ +LL | let y: u32 = x?.try_into().unwrap(); + | ++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 34c5c7e589bc5..7fb3f85b7f5ce 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -236,14 +236,8 @@ mod expressions { type_ascribe!({ from_output(()) }, Option<_>); type_ascribe!({ from_output(match branch(None) { - Break { 0: residual } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - break from_residual(residual), - Continue { 0: val } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - val, + Break { 0: residual } => break from_residual(residual), + Continue { 0: val } => val, }) }, Option) } @@ -364,14 +358,8 @@ mod expressions { fn expr_try() { let expr; match branch(expr) { - Break { 0: residual } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - return from_residual(residual), - Continue { 0: val } => - #[attr = LintCheck([LintCheck {lint_name: "unreachable_code", - kind: Allow}])] - val, + Break { 0: residual } => return from_residual(residual), + Continue { 0: val } => val, }; } /// ExprKind::Yield