diff options
Diffstat (limited to 'compiler')
72 files changed, 554 insertions, 401 deletions
diff --git a/compiler/rustc_abi/src/canon_abi.rs b/compiler/rustc_abi/src/canon_abi.rs index 7c020be6761..13f9a04b286 100644 --- a/compiler/rustc_abi/src/canon_abi.rs +++ b/compiler/rustc_abi/src/canon_abi.rs @@ -63,8 +63,8 @@ impl fmt::Display for CanonAbi { CanonAbi::Custom => ExternAbi::Custom, CanonAbi::Arm(arm_call) => match arm_call { ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false }, - ArmCall::CCmseNonSecureCall => ExternAbi::CCmseNonSecureCall, - ArmCall::CCmseNonSecureEntry => ExternAbi::CCmseNonSecureEntry, + ArmCall::CCmseNonSecureCall => ExternAbi::CmseNonSecureCall, + ArmCall::CCmseNonSecureEntry => ExternAbi::CmseNonSecureEntry, }, CanonAbi::GpuKernel => ExternAbi::GpuKernel, CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 1b8c2de1588..29a3678abf3 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -59,9 +59,9 @@ pub enum ExternAbi { unwind: bool, }, /// extremely constrained barely-C ABI for TrustZone - CCmseNonSecureCall, + CmseNonSecureCall, /// extremely constrained barely-C ABI for TrustZone - CCmseNonSecureEntry, + CmseNonSecureEntry, /* gpu */ /// An entry-point function called by the GPU's host @@ -140,8 +140,6 @@ macro_rules! abi_impls { abi_impls! { ExternAbi = { C { unwind: false } =><= "C", - CCmseNonSecureCall =><= "C-cmse-nonsecure-call", - CCmseNonSecureEntry =><= "C-cmse-nonsecure-entry", C { unwind: true } =><= "C-unwind", Rust =><= "Rust", Aapcs { unwind: false } =><= "aapcs", @@ -150,6 +148,8 @@ abi_impls! { AvrNonBlockingInterrupt =><= "avr-non-blocking-interrupt", Cdecl { unwind: false } =><= "cdecl", Cdecl { unwind: true } =><= "cdecl-unwind", + CmseNonSecureCall =><= "cmse-nonsecure-call", + CmseNonSecureEntry =><= "cmse-nonsecure-entry", Custom =><= "custom", EfiApi =><= "efiapi", Fastcall { unwind: false } =><= "fastcall", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ab8dac16026..d9272986a7e 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4064,9 +4064,9 @@ mod size_asserts { static_assert_size!(MetaItemLit, 40); static_assert_size!(Param, 40); static_assert_size!(Pat, 72); + static_assert_size!(PatKind, 48); static_assert_size!(Path, 24); static_assert_size!(PathSegment, 24); - static_assert_size!(PatKind, 48); static_assert_size!(Stmt, 32); static_assert_size!(StmtKind, 16); static_assert_size!(Ty, 64); diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs index 9b60807e650..6752218fa0d 100644 --- a/compiler/rustc_ast_lowering/src/stability.rs +++ b/compiler/rustc_ast_lowering/src/stability.rs @@ -127,12 +127,12 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> { feature: sym::abi_riscv_interrupt, explain: GateReason::Experimental, }), - ExternAbi::CCmseNonSecureCall => Err(UnstableAbi { + ExternAbi::CmseNonSecureCall => Err(UnstableAbi { abi, - feature: sym::abi_c_cmse_nonsecure_call, + feature: sym::abi_cmse_nonsecure_call, explain: GateReason::Experimental, }), - ExternAbi::CCmseNonSecureEntry => Err(UnstableAbi { + ExternAbi::CmseNonSecureEntry => Err(UnstableAbi { abi, feature: sym::cmse_nonsecure_entry, explain: GateReason::Experimental, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs new file mode 100644 index 00000000000..e41dd8bde8f --- /dev/null +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -0,0 +1,42 @@ +use crate::AttributeKind; + +#[derive(PartialEq)] +pub enum EncodeCrossCrate { + Yes, + No, +} + +impl AttributeKind { + pub fn encode_cross_crate(&self) -> EncodeCrossCrate { + use AttributeKind::*; + use EncodeCrossCrate::*; + + match self { + Align { .. } => No, + AllowConstFnUnstable(..) => No, + AllowInternalUnstable(..) => Yes, + AsPtr(..) => Yes, + BodyStability { .. } => No, + Confusables { .. } => Yes, + ConstStability { .. } => Yes, + ConstStabilityIndirect => No, + Deprecation { .. } => Yes, + DocComment { .. } => Yes, + Inline(..) => No, + MacroTransparency(..) => Yes, + Repr(..) => No, + Stability { .. } => Yes, + Cold(..) => No, + ConstContinue(..) => No, + LoopMatch(..) => No, + MayDangle(..) => No, + MustUse { .. } => Yes, + Naked(..) => No, + NoMangle(..) => No, + Optimize(..) => No, + PubTransparent(..) => Yes, + SkipDuringMethodDispatch { .. } => No, + TrackCaller(..) => Yes, + } + } +} diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index f8355be09ad..86c73f0d9a0 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -9,6 +9,7 @@ // tidy-alphabetical-end mod attributes; +mod encode_cross_crate; mod stability; mod version; @@ -17,6 +18,7 @@ pub mod lints; use std::num::NonZero; pub use attributes::*; +pub use encode_cross_crate::EncodeCrossCrate; use rustc_abi::Align; use rustc_ast::token::CommentKind; use rustc_ast::{AttrStyle, IntTy, UintTy}; diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 98dc898db23..d1dac1c7145 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -518,11 +518,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } = move_spans && can_suggest_clone { - self.suggest_cloning(err, ty, expr, Some(move_spans)); + self.suggest_cloning(err, place.as_ref(), ty, expr, Some(move_spans)); } else if self.suggest_hoisting_call_outside_loop(err, expr) && can_suggest_clone { // The place where the type moves would be misleading to suggest clone. // #121466 - self.suggest_cloning(err, ty, expr, Some(move_spans)); + self.suggest_cloning(err, place.as_ref(), ty, expr, Some(move_spans)); } } @@ -1224,6 +1224,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn suggest_cloning( &self, err: &mut Diag<'_>, + place: PlaceRef<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>, use_spans: Option<UseSpans<'tcx>>, @@ -1238,7 +1239,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } if self.implements_clone(ty) { - self.suggest_cloning_inner(err, ty, expr); + if self.in_move_closure(expr) { + if let Some(name) = self.describe_place(place) { + self.suggest_clone_of_captured_var_in_move_closure(err, &name, use_spans); + } + } else { + self.suggest_cloning_inner(err, ty, expr); + } } else if let ty::Adt(def, args) = ty.kind() && def.did().as_local().is_some() && def.variants().iter().all(|variant| { @@ -1505,7 +1512,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let hir::ExprKind::AddrOf(_, _, borrowed_expr) = expr.kind && let Some(ty) = typeck_results.expr_ty_opt(borrowed_expr) { - self.suggest_cloning(&mut err, ty, borrowed_expr, Some(move_spans)); + self.suggest_cloning(&mut err, place.as_ref(), ty, borrowed_expr, Some(move_spans)); } else if typeck_results.expr_adjustments(expr).first().is_some_and(|adj| { matches!( adj.kind, @@ -1518,7 +1525,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) }) && let Some(ty) = typeck_results.expr_ty_opt(expr) { - self.suggest_cloning(&mut err, ty, expr, Some(move_spans)); + self.suggest_cloning(&mut err, place.as_ref(), ty, expr, Some(move_spans)); } } self.buffer_error(err); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 7b4e38969ee..9ad91d605a7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1284,8 +1284,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && !spans.is_empty() { let mut span: MultiSpan = spans.clone().into(); + err.arg("ty", param_ty.to_string()); + let msg = err.dcx.eagerly_translate_to_string( + fluent::borrowck_moved_a_fn_once_in_call_def, + err.args.iter(), + ); + err.remove_arg("ty"); for sp in spans { - span.push_span_label(sp, fluent::borrowck_moved_a_fn_once_in_call_def); + span.push_span_label(sp, msg.clone()); } span.push_span_label( fn_call_span, diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index b21d348183f..92ca868eb99 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -325,25 +325,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.cannot_move_out_of(span, &description) } - fn suggest_clone_of_captured_var_in_move_closure( + pub(in crate::diagnostics) fn suggest_clone_of_captured_var_in_move_closure( &self, err: &mut Diag<'_>, - upvar_hir_id: HirId, upvar_name: &str, use_spans: Option<UseSpans<'tcx>>, ) { let tcx = self.infcx.tcx; - let typeck_results = tcx.typeck(self.mir_def_id()); let Some(use_spans) = use_spans else { return }; // We only care about the case where a closure captured a binding. let UseSpans::ClosureUse { args_span, .. } = use_spans else { return }; let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; - // Fetch the type of the expression corresponding to the closure-captured binding. - let Some(captured_ty) = typeck_results.node_type_opt(upvar_hir_id) else { return }; - if !self.implements_clone(captured_ty) { - // We only suggest cloning the captured binding if the type can actually be cloned. - return; - }; // Find the closure that captured the binding. let mut expr_finder = FindExprBySpan::new(args_span, tcx); expr_finder.include_closures = true; @@ -396,7 +388,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .indentation_before(stmt.span) .unwrap_or_else(|| " ".to_string()); err.multipart_suggestion_verbose( - "clone the value before moving it into the closure", + "consider cloning the value before moving it into the closure", vec![ ( stmt.span.shrink_to_lo(), @@ -426,7 +418,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .indentation_before(closure_expr.span) .unwrap_or_else(|| " ".to_string()); err.multipart_suggestion_verbose( - "clone the value before moving it into the closure", + "consider cloning the value before moving it into the closure", vec![ ( closure_expr.span.shrink_to_lo(), @@ -523,20 +515,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ); let closure_span = tcx.def_span(def_id); - let mut err = self - .cannot_move_out_of(span, &place_description) + self.cannot_move_out_of(span, &place_description) .with_span_label(upvar_span, "captured outer variable") .with_span_label( closure_span, format!("captured by this `{closure_kind}` closure"), - ); - self.suggest_clone_of_captured_var_in_move_closure( - &mut err, - upvar_hir_id, - &upvar_name, - use_spans, - ); - err + ) } _ => { let source = self.borrowed_content_source(deref_base); @@ -597,7 +581,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }; if let Some(expr) = self.find_expr(span) { - self.suggest_cloning(err, place_ty, expr, None); + self.suggest_cloning(err, move_from.as_ref(), place_ty, expr, None); } err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { @@ -629,7 +613,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }; if let Some(expr) = self.find_expr(use_span) { - self.suggest_cloning(err, place_ty, expr, Some(use_spans)); + self.suggest_cloning( + err, + original_path.as_ref(), + place_ty, + expr, + Some(use_spans), + ); } err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { @@ -832,7 +822,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let place_desc = self.local_name(*local).map(|sym| format!("`{sym}`")); if let Some(expr) = self.find_expr(binding_span) { - self.suggest_cloning(err, bind_to.ty, expr, None); + let local_place: PlaceRef<'tcx> = (*local).into(); + self.suggest_cloning(err, local_place, bind_to.ty, expr, None); } err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index fe34cf5d6fa..a5ee7349fc6 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -660,6 +660,7 @@ impl Subdiagnostic for FormatUnusedArg { fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { diag.arg("named", self.named); let msg = diag.eagerly_translate(crate::fluent_generated::builtin_macros_format_unused_arg); + diag.remove_arg("named"); diag.span_label(self.span, msg); } } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index a2e34d1f8fb..7852aebe0c2 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1591,9 +1591,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { (value1, value2) } - fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) { // TODO(antoyo): generate the correct landing pad - self.cleanup_landing_pad(pers_fn) + self.cleanup_landing_pad(pers_fn); } #[cfg(feature = "master")] diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index ee46b49a094..9c62244f3c9 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -587,7 +587,7 @@ fn thin_lto( } fn enable_autodiff_settings(ad: &[config::AutoDiff]) { - for &val in ad { + for val in ad { // We intentionally don't use a wildcard, to not forget handling anything new. match val { config::AutoDiff::PrintPerf => { @@ -599,6 +599,10 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff]) { config::AutoDiff::PrintTA => { llvm::set_print_type(true); } + config::AutoDiff::PrintTAFn(fun) => { + llvm::set_print_type(true); // Enable general type printing + llvm::set_print_type_fun(&fun); // Set specific function to analyze + } config::AutoDiff::Inline => { llvm::set_inline(true); } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 5e9594dd06b..d0aa7320b4b 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1166,11 +1166,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { (self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1)) } - fn filter_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) { + fn filter_landing_pad(&mut self, pers_fn: &'ll Value) { let ty = self.type_struct(&[self.type_ptr(), self.type_i32()], false); let landing_pad = self.landing_pad(ty, pers_fn, 1); self.add_clause(landing_pad, self.const_array(self.type_ptr(), &[])); - (self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1)) } fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) { diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 2ad39fc8538..b94716b89d6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -57,14 +57,19 @@ pub(crate) use self::Enzyme_AD::*; #[cfg(llvm_enzyme)] pub(crate) mod Enzyme_AD { + use std::ffi::{CString, c_char}; + use libc::c_void; + unsafe extern "C" { pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); + pub(crate) fn EnzymeSetCLString(arg1: *mut ::std::os::raw::c_void, arg2: *const c_char); } unsafe extern "C" { static mut EnzymePrintPerf: c_void; static mut EnzymePrintActivity: c_void; static mut EnzymePrintType: c_void; + static mut EnzymeFunctionToAnalyze: c_void; static mut EnzymePrint: c_void; static mut EnzymeStrictAliasing: c_void; static mut looseTypeAnalysis: c_void; @@ -86,6 +91,15 @@ pub(crate) mod Enzyme_AD { EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8); } } + pub(crate) fn set_print_type_fun(fun_name: &str) { + let c_fun_name = CString::new(fun_name).unwrap(); + unsafe { + EnzymeSetCLString( + std::ptr::addr_of_mut!(EnzymeFunctionToAnalyze), + c_fun_name.as_ptr() as *const c_char, + ); + } + } pub(crate) fn set_print(print: bool) { unsafe { EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8); @@ -132,6 +146,9 @@ pub(crate) mod Fallback_AD { pub(crate) fn set_print_type(print: bool) { unimplemented!() } + pub(crate) fn set_print_type_fun(fun_name: &str) { + unimplemented!() + } pub(crate) fn set_print(print: bool) { unimplemented!() } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f35f551d590..d19de6f5d26 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -516,7 +516,7 @@ pub trait BuilderMethods<'a, 'tcx>: // These are used by everyone except msvc fn cleanup_landing_pad(&mut self, pers_fn: Self::Function) -> (Self::Value, Self::Value); - fn filter_landing_pad(&mut self, pers_fn: Self::Function) -> (Self::Value, Self::Value); + fn filter_landing_pad(&mut self, pers_fn: Self::Function); fn resume(&mut self, exn0: Self::Value, exn1: Self::Value); // These are used only by msvc diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 69c71aef9f3..609749554ce 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -291,6 +291,9 @@ impl Subdiagnostic for FrameNote { span.push_span_label(self.span, fluent::const_eval_frame_note_last); } let msg = diag.eagerly_translate(fluent::const_eval_frame_note); + diag.remove_arg("times"); + diag.remove_arg("where_"); + diag.remove_arg("instance"); diag.span_note(span, msg); } } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 77667ba823a..337b1617676 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -878,9 +878,9 @@ mod size_asserts { use super::*; // tidy-alphabetical-start - static_assert_size!(Immediate, 48); static_assert_size!(ImmTy<'_>, 64); - static_assert_size!(Operand, 56); + static_assert_size!(Immediate, 48); static_assert_size!(OpTy<'_>, 72); + static_assert_size!(Operand, 56); // tidy-alphabetical-end } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index f5d3de7b1b2..e4885af7faf 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -1056,9 +1056,9 @@ mod size_asserts { use super::*; // tidy-alphabetical-start + static_assert_size!(MPlaceTy<'_>, 64); static_assert_size!(MemPlace, 48); static_assert_size!(MemPlaceMeta, 24); - static_assert_size!(MPlaceTy<'_>, 64); static_assert_size!(Place, 48); static_assert_size!(PlaceTy<'_>, 64); // tidy-alphabetical-end diff --git a/compiler/rustc_error_codes/src/error_codes/E0775.md b/compiler/rustc_error_codes/src/error_codes/E0775.md index efbd51e89ea..9fcd3a6eef7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0775.md +++ b/compiler/rustc_error_codes/src/error_codes/E0775.md @@ -8,7 +8,7 @@ Erroneous code example: ```ignore (no longer emitted) #![feature(cmse_nonsecure_entry)] -pub extern "C-cmse-nonsecure-entry" fn entry_function() {} +pub extern "cmse-nonsecure-entry" fn entry_function() {} ``` To fix this error, compile your code for a Rust target that supports the diff --git a/compiler/rustc_error_codes/src/error_codes/E0781.md b/compiler/rustc_error_codes/src/error_codes/E0781.md index 7641acfb524..22abe0e3cb1 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0781.md +++ b/compiler/rustc_error_codes/src/error_codes/E0781.md @@ -1,12 +1,12 @@ -The `C-cmse-nonsecure-call` ABI can only be used with function pointers. +The `cmse-nonsecure-call` ABI can only be used with function pointers. Erroneous code example: ```compile_fail,E0781 -#![feature(abi_c_cmse_nonsecure_call)] +#![feature(abi_cmse_nonsecure_call)] -pub extern "C-cmse-nonsecure-call" fn test() {} +pub extern "cmse-nonsecure-call" fn test() {} ``` -The `C-cmse-nonsecure-call` ABI should be used by casting function pointers to +The `cmse-nonsecure-call` ABI should be used by casting function pointers to specific addresses. diff --git a/compiler/rustc_error_codes/src/error_codes/E0798.md b/compiler/rustc_error_codes/src/error_codes/E0798.md index da08cde3010..e5f356ef4d5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0798.md +++ b/compiler/rustc_error_codes/src/error_codes/E0798.md @@ -1,4 +1,4 @@ -Functions marked as `C-cmse-nonsecure-call` place restrictions on their +Functions marked as `cmse-nonsecure-call` place restrictions on their inputs and outputs. - inputs must fit in the 4 available 32-bit argument registers. Alignment @@ -12,12 +12,12 @@ see [arm's aapcs32](https://github.com/ARM-software/abi-aa/releases). Erroneous code example: -```ignore (only fails on supported targets) -#![feature(abi_c_cmse_nonsecure_call)] +```ignore (host errors will not match for target) +#![feature(abi_cmse_nonsecure_call)] #[no_mangle] pub fn test( - f: extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32, u32) -> u32, + f: extern "cmse-nonsecure-call" fn(u32, u32, u32, u32, u32) -> u32, ) -> u32 { f(1, 2, 3, 4, 5) } @@ -27,12 +27,12 @@ Arguments' alignment is respected. In the example below, padding is inserted so that the `u64` argument is passed in registers r2 and r3. There is then no room left for the final `f32` argument -```ignore (only fails on supported targets) -#![feature(abi_c_cmse_nonsecure_call)] +```ignore (host errors will not match for target) +#![feature(abi_cmse_nonsecure_call)] #[no_mangle] pub fn test( - f: extern "C-cmse-nonsecure-call" fn(u32, u64, f32) -> u32, + f: extern "cmse-nonsecure-call" fn(u32, u64, f32) -> u32, ) -> u32 { f(1, 2, 3.0) } diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 22cc1e894da..0aff1c06e0a 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -690,5 +690,5 @@ E0805: 0805, // E0723, // unstable feature in `const` context // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. // E0744, // merged into E0728 -// E0776, // Removed; cmse_nonsecure_entry is now `C-cmse-nonsecure-entry` +// E0776, // Removed; `#[cmse_nonsecure_entry]` is now `extern "cmse-nonsecure-entry"` // E0796, // unused error code. We use `static_mut_refs` lint instead. diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index a11f81b55bb..8da7cdd9358 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -289,6 +289,9 @@ pub struct DiagInner { pub suggestions: Suggestions, pub args: DiagArgMap, + // This is used to store args and restore them after a subdiagnostic is rendered. + pub reserved_args: DiagArgMap, + /// This is not used for highlighting or rendering any error message. Rather, it can be used /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of /// `span` if there is one. Otherwise, it is `DUMMY_SP`. @@ -319,6 +322,7 @@ impl DiagInner { children: vec![], suggestions: Suggestions::Enabled(vec![]), args: Default::default(), + reserved_args: Default::default(), sort_span: DUMMY_SP, is_lint: None, long_ty_path: None, @@ -390,7 +394,27 @@ impl DiagInner { } pub(crate) fn arg(&mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) { - self.args.insert(name.into(), arg.into_diag_arg(&mut self.long_ty_path)); + let name = name.into(); + let value = arg.into_diag_arg(&mut self.long_ty_path); + // This assertion is to avoid subdiagnostics overwriting an existing diagnostic arg. + debug_assert!( + !self.args.contains_key(&name) || self.args.get(&name) == Some(&value), + "arg {} already exists", + name + ); + self.args.insert(name, value); + } + + pub fn remove_arg(&mut self, name: &str) { + self.args.swap_remove(name); + } + + pub fn store_args(&mut self) { + self.reserved_args = self.args.clone(); + } + + pub fn restore_args(&mut self) { + self.args = std::mem::take(&mut self.reserved_args); } /// Fields used for Hash, and PartialEq trait. @@ -1423,6 +1447,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.downgrade_to_delayed_bug(); self.emit() } + + pub fn remove_arg(&mut self, name: &str) { + if let Some(diag) = self.diag.as_mut() { + diag.remove_arg(name); + } + } } /// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.) diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml index a5ae06473cb..78d7b698b72 100644 --- a/compiler/rustc_feature/Cargo.toml +++ b/compiler/rustc_feature/Cargo.toml @@ -5,8 +5,9 @@ edition = "2024" [dependencies] # tidy-alphabetical-start +rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_span = { path = "../rustc_span" } -serde = { version = "1.0.125", features = [ "derive" ] } +serde = { version = "1.0.125", features = ["derive"] } serde_json = "1.0.59" # tidy-alphabetical-end diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 8c0f279e343..8e1392998d4 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -5,6 +5,7 @@ use std::sync::LazyLock; use AttributeDuplicates::*; use AttributeGate::*; use AttributeType::*; +use rustc_attr_data_structures::EncodeCrossCrate; use rustc_data_structures::fx::FxHashMap; use rustc_span::edition::Edition; use rustc_span::{Symbol, sym}; @@ -368,12 +369,6 @@ macro_rules! experimental { }; } -#[derive(PartialEq)] -pub enum EncodeCrossCrate { - Yes, - No, -} - pub struct BuiltinAttribute { pub name: Symbol, /// Whether this attribute is encode cross crate. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index c54b831e244..ddb99585bc2 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -54,6 +54,7 @@ declare_features! ( /// Allows using the `amdgpu-kernel` ABI. (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None, 120495), + (removed, abi_c_cmse_nonsecure_call, "CURRENT_RUSTC_VERSION", Some(81391), Some("renamed to abi_cmse_nonsecure_call"), 142146), (removed, advanced_slice_patterns, "1.42.0", Some(62254), Some("merged into `#![feature(slice_patterns)]`"), 67712), (removed, allocator, "1.0.0", None, None), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index d9d5334615a..e73a4e1766c 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -353,8 +353,8 @@ declare_features! ( /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. (unstable, abi_avr_interrupt, "1.45.0", Some(69664)), - /// Allows `extern "C-cmse-nonsecure-call" fn()`. - (unstable, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391)), + /// Allows `extern "cmse-nonsecure-call" fn()`. + (unstable, abi_cmse_nonsecure_call, "CURRENT_RUSTC_VERSION", Some(81391)), /// Allows `extern "custom" fn()`. (unstable, abi_custom, "CURRENT_RUSTC_VERSION", Some(140829)), /// Allows `extern "gpu-kernel" fn()`. @@ -431,7 +431,7 @@ declare_features! ( (unstable, closure_lifetime_binder, "1.64.0", Some(97362)), /// Allows `#[track_caller]` on closures and coroutines. (unstable, closure_track_caller, "1.57.0", Some(87417)), - /// Allows `extern "C-cmse-nonsecure-entry" fn()`. + /// Allows `extern "cmse-nonsecure-entry" fn()`. (unstable, cmse_nonsecure_entry, "1.48.0", Some(75835)), /// Allows `async {}` expressions in const contexts. (unstable, const_async_blocks, "1.53.0", Some(85368)), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 679904c7cfe..88e0ee1cc0b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4992,9 +4992,9 @@ mod size_asserts { static_assert_size!(LetStmt<'_>, 72); static_assert_size!(Param<'_>, 32); static_assert_size!(Pat<'_>, 72); + static_assert_size!(PatKind<'_>, 48); static_assert_size!(Path<'_>, 40); static_assert_size!(PathSegment<'_>, 48); - static_assert_size!(PatKind<'_>, 48); static_assert_size!(QPath<'_>, 24); static_assert_size!(Res, 12); static_assert_size!(Stmt<'_>, 32); diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 8c43d10b9e4..4ec2bbfc5ab 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -73,10 +73,10 @@ hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are fo .label = `for<...>` is here hir_analysis_cmse_call_generic = - function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type + function pointers with the `"cmse-nonsecure-call"` ABI cannot contain generics in their type hir_analysis_cmse_entry_generic = - functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type + functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type hir_analysis_cmse_inputs_stack_spill = arguments for `{$abi}` function too large to pass via registers diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 318aaab50f4..c920e25ad37 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -127,6 +127,7 @@ pub(crate) enum AssocItemNotFoundSugg<'a> { SimilarInOtherTrait { #[primary_span] span: Span, + trait_name: &'a str, assoc_kind: &'static str, suggested_name: Symbol, }, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index ebeb3b58208..82e5f65476f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -18,7 +18,7 @@ pub(crate) fn validate_cmse_abi<'tcx>( fn_sig: ty::PolyFnSig<'tcx>, ) { match abi { - ExternAbi::CCmseNonSecureCall => { + ExternAbi::CmseNonSecureCall => { let hir_node = tcx.hir_node(hir_id); let hir::Node::Ty(hir::Ty { span: bare_fn_span, @@ -38,7 +38,7 @@ pub(crate) fn validate_cmse_abi<'tcx>( dcx, span, E0781, - "the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers" + "the `\"cmse-nonsecure-call\"` ABI is only allowed on function pointers" ) .emit(); return; @@ -78,7 +78,7 @@ pub(crate) fn validate_cmse_abi<'tcx>( } }; } - ExternAbi::CCmseNonSecureEntry => { + ExternAbi::CmseNonSecureEntry => { let hir_node = tcx.hir_node(hir_id); let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else { // might happen when this ABI is used incorrectly. That will be handled elsewhere @@ -203,11 +203,11 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError match layout_err { TooGeneric(ty) => { match abi { - ExternAbi::CCmseNonSecureCall => { + ExternAbi::CmseNonSecureCall => { // prevent double reporting of this error !ty.is_impl_trait() } - ExternAbi::CCmseNonSecureEntry => true, + ExternAbi::CmseNonSecureEntry => true, _ => bug!("invalid ABI: {abi}"), } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 0e79a8918b0..f211137ddd6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -309,6 +309,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // change the associated item. err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait { span: assoc_ident.span, + trait_name: &trait_name, assoc_kind: assoc_kind_str, suggested_name, }); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 4ac260cb15f..6467adb54da 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -1,12 +1,12 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{self as hir, ExprKind, PatKind}; +use rustc_hir::{self as hir, ExprKind, HirId, PatKind}; use rustc_hir_pretty::ty_to_string; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; use rustc_trait_selection::traits::{ - IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, + MatchExpressionArmCause, ObligationCause, ObligationCauseCode, }; use tracing::{debug, instrument}; @@ -414,105 +414,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn if_cause( &self, - span: Span, - cond_span: Span, - then_expr: &'tcx hir::Expr<'tcx>, + expr_id: HirId, else_expr: &'tcx hir::Expr<'tcx>, - then_ty: Ty<'tcx>, - else_ty: Ty<'tcx>, tail_defines_return_position_impl_trait: Option<LocalDefId>, ) -> ObligationCause<'tcx> { - let mut outer_span = if self.tcx.sess.source_map().is_multiline(span) { - // The `if`/`else` isn't in one line in the output, include some context to make it - // clear it is an if/else expression: - // ``` - // LL | let x = if true { - // | _____________- - // LL || 10i32 - // || ----- expected because of this - // LL || } else { - // LL || 10u32 - // || ^^^^^ expected `i32`, found `u32` - // LL || }; - // ||_____- `if` and `else` have incompatible types - // ``` - Some(span) - } else { - // The entire expression is in one line, only point at the arms - // ``` - // LL | let x = if true { 10i32 } else { 10u32 }; - // | ----- ^^^^^ expected `i32`, found `u32` - // | | - // | expected because of this - // ``` - None - }; - - let (error_sp, else_id) = if let ExprKind::Block(block, _) = &else_expr.kind { - let block = block.innermost_block(); - - // Avoid overlapping spans that aren't as readable: - // ``` - // 2 | let x = if true { - // | _____________- - // 3 | | 3 - // | | - expected because of this - // 4 | | } else { - // | |____________^ - // 5 | || - // 6 | || }; - // | || ^ - // | ||_____| - // | |______if and else have incompatible types - // | expected integer, found `()` - // ``` - // by not pointing at the entire expression: - // ``` - // 2 | let x = if true { - // | ------- `if` and `else` have incompatible types - // 3 | 3 - // | - expected because of this - // 4 | } else { - // | ____________^ - // 5 | | - // 6 | | }; - // | |_____^ expected integer, found `()` - // ``` - if block.expr.is_none() - && block.stmts.is_empty() - && let Some(outer_span) = &mut outer_span - && let Some(cond_span) = cond_span.find_ancestor_inside(*outer_span) - { - *outer_span = outer_span.with_hi(cond_span.hi()) - } - - (self.find_block_span(block), block.hir_id) - } else { - (else_expr.span, else_expr.hir_id) - }; - - let then_id = if let ExprKind::Block(block, _) = &then_expr.kind { - let block = block.innermost_block(); - // Exclude overlapping spans - if block.expr.is_none() && block.stmts.is_empty() { - outer_span = None; - } - block.hir_id - } else { - then_expr.hir_id - }; + let error_sp = self.find_block_span_from_hir_id(else_expr.hir_id); // Finally construct the cause: self.cause( error_sp, - ObligationCauseCode::IfExpression(Box::new(IfExpressionCause { - else_id, - then_id, - then_ty, - else_ty, - outer_span, - tail_defines_return_position_impl_trait, - })), + ObligationCauseCode::IfExpression { expr_id, tail_defines_return_position_impl_trait }, ) } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 24092c01125..a9367415263 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -46,8 +46,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::relate::RelateResult; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::{ - IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation, - PredicateObligations, SelectionError, + MatchExpressionArmCause, Obligation, PredicateObligation, PredicateObligations, SelectionError, }; use rustc_middle::span_bug; use rustc_middle::ty::adjustment::{ @@ -59,7 +58,7 @@ use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ - self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, + self, ImplSource, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, }; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; @@ -704,6 +703,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // be silent, as it causes a type mismatch later. } + Ok(Some(ImplSource::UserDefined(impl_source))) => { + queue.extend(impl_source.nested); + // Certain incoherent `CoerceUnsized` implementations may cause ICEs, + // so check the impl's validity. Taint the body so that we don't try + // to evaluate these invalid coercions in CTFE. We only need to do this + // for local impls, since upstream impls should be valid. + if impl_source.impl_def_id.is_local() + && let Err(guar) = + self.tcx.ensure_ok().coerce_unsized_info(impl_source.impl_def_id) + { + self.fcx.set_tainted_by_errors(guar); + } + } Ok(Some(impl_source)) => queue.extend(impl_source.nested_obligations()), } } @@ -1706,14 +1718,17 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); } } - ObligationCauseCode::IfExpression(box IfExpressionCause { - then_id, - else_id, - then_ty, - else_ty, + ObligationCauseCode::IfExpression { + expr_id, tail_defines_return_position_impl_trait: Some(rpit_def_id), - .. - }) => { + } => { + let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::If(_, then_expr, Some(else_expr)), + .. + }) = fcx.tcx.hir_node(expr_id) + else { + unreachable!(); + }; err = fcx.err_ctxt().report_mismatched_types( cause, fcx.param_env, @@ -1721,24 +1736,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { found, coercion_error, ); - let then_span = fcx.find_block_span_from_hir_id(then_id); - let else_span = fcx.find_block_span_from_hir_id(else_id); - // don't suggest wrapping either blocks in `if .. {} else {}` - let is_empty_arm = |id| { - let hir::Node::Block(blk) = fcx.tcx.hir_node(id) else { - return false; - }; - if blk.expr.is_some() || !blk.stmts.is_empty() { - return false; - } - let Some((_, hir::Node::Expr(expr))) = - fcx.tcx.hir_parent_iter(id).nth(1) - else { - return false; - }; - matches!(expr.kind, hir::ExprKind::If(..)) - }; - if !is_empty_arm(then_id) && !is_empty_arm(else_id) { + let then_span = fcx.find_block_span_from_hir_id(then_expr.hir_id); + let else_span = fcx.find_block_span_from_hir_id(else_expr.hir_id); + // Don't suggest wrapping whole block in `Box::new`. + if then_span != then_expr.span && else_span != else_expr.span { + let then_ty = fcx.typeck_results.borrow().expr_ty(then_expr); + let else_ty = fcx.typeck_results.borrow().expr_ty(else_expr); self.suggest_boxing_tail_for_return_position_impl_trait( fcx, &mut err, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 2bc9dadb665..3a0d57dca12 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -583,7 +583,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ascribed_ty } ExprKind::If(cond, then_expr, opt_else_expr) => { - self.check_expr_if(cond, then_expr, opt_else_expr, expr.span, expected) + self.check_expr_if(expr.hir_id, cond, then_expr, opt_else_expr, expr.span, expected) } ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected), ExprKind::Array(args) => self.check_expr_array(args, expected, expr), @@ -1343,6 +1343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // or 'if-else' expression. fn check_expr_if( &self, + expr_id: HirId, cond_expr: &'tcx hir::Expr<'tcx>, then_expr: &'tcx hir::Expr<'tcx>, opt_else_expr: Option<&'tcx hir::Expr<'tcx>>, @@ -1382,15 +1383,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tail_defines_return_position_impl_trait = self.return_position_impl_trait_from_match_expectation(orig_expected); - let if_cause = self.if_cause( - sp, - cond_expr.span, - then_expr, - else_expr, - then_ty, - else_ty, - tail_defines_return_position_impl_trait, - ); + let if_cause = + self.if_cause(expr_id, else_expr, tail_defines_return_position_impl_trait); coerce.coerce(self, &if_cause, else_expr, else_ty); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e9b58eb959b..491efba9eb0 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -35,7 +35,7 @@ use rustc_middle::ty::{ PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, }; -use rustc_span::{Span, Symbol}; +use rustc_span::{DUMMY_SP, Span, Symbol}; use snapshot::undo_log::InferCtxtUndoLogs; use tracing::{debug, instrument}; use type_variable::TypeVariableOrigin; @@ -1557,15 +1557,16 @@ impl<'tcx> InferCtxt<'tcx> { } } - /// Given a [`hir::HirId`] for a block, get the span of its last expression - /// or statement, peeling off any inner blocks. + /// Given a [`hir::HirId`] for a block (or an expr of a block), get the span + /// of its last expression or statement, peeling off any inner blocks. pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span { match self.tcx.hir_node(hir_id) { - hir::Node::Block(blk) => self.find_block_span(blk), - // The parser was in a weird state if either of these happen, but - // it's better not to panic. + hir::Node::Block(blk) + | hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Block(blk, _), .. }) => { + self.find_block_span(blk) + } hir::Node::Expr(e) => e.span, - _ => rustc_span::DUMMY_SP, + _ => DUMMY_SP, } } } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c52dbd892bf..c72f8571153 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -482,7 +482,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let name = lint_name.as_str(); let suggestion = RenamedLintSuggestion::WithoutSpan { replace }; let requested_level = RequestedLevel { level, lint_name }; - let lint = RenamedLintFromCommandLine { name, suggestion, requested_level }; + let lint = + RenamedLintFromCommandLine { name, replace, suggestion, requested_level }; self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint); } CheckLintNameResult::Removed(ref reason) => { @@ -824,7 +825,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { RenamedLintSuggestion::WithSpan { suggestion: sp, replace }; let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); - let lint = RenamedLint { name: name.as_str(), suggestion }; + let lint = RenamedLint { name: name.as_str(), replace, suggestion }; self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint); } diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs index 95b7b69bd5a..5465968e984 100644 --- a/compiler/rustc_lint/src/lifetime_syntax.rs +++ b/compiler/rustc_lint/src/lifetime_syntax.rs @@ -422,12 +422,12 @@ fn build_mismatch_suggestion( lifetime_name: &str, infos: &[&Info<'_>], ) -> lints::MismatchedLifetimeSyntaxesSuggestion { - let lifetime_name = lifetime_name.to_owned(); + let lifetime_name_sugg = lifetime_name.to_owned(); let suggestions = infos.iter().map(|info| info.suggestion(&lifetime_name)).collect(); lints::MismatchedLifetimeSyntaxesSuggestion::Explicit { - lifetime_name, + lifetime_name_sugg, suggestions, tool_only: false, } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index eedb897312e..5e05b58146e 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1089,6 +1089,7 @@ pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { #[diag(lint_renamed_lint)] pub(crate) struct RenamedLint<'a> { pub name: &'a str, + pub replace: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, } @@ -1109,6 +1110,7 @@ pub(crate) enum RenamedLintSuggestion<'a> { #[diag(lint_renamed_lint)] pub(crate) struct RenamedLintFromCommandLine<'a> { pub name: &'a str, + pub replace: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, #[subdiagnostic] @@ -3244,7 +3246,7 @@ pub(crate) enum MismatchedLifetimeSyntaxesSuggestion { }, Explicit { - lifetime_name: String, + lifetime_name_sugg: String, suggestions: Vec<(Span, String)>, tool_only: bool, }, @@ -3298,13 +3300,12 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { ); } - Explicit { lifetime_name, suggestions, tool_only } => { - diag.arg("lifetime_name", lifetime_name); - + Explicit { lifetime_name_sugg, suggestions, tool_only } => { + diag.arg("lifetime_name_sugg", lifetime_name_sugg); let msg = diag.eagerly_translate( fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit, ); - + diag.remove_arg("lifetime_name_sugg"); diag.multipart_suggestion_with_style( msg, suggestions, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 5fa00fcc4a0..10ac14a2fbf 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -131,8 +131,8 @@ declare_lint_pass! { UNUSED_IMPORTS, UNUSED_LABELS, UNUSED_LIFETIMES, - UNUSED_MACRO_RULES, UNUSED_MACROS, + UNUSED_MACRO_RULES, UNUSED_MUT, UNUSED_QUALIFICATIONS, UNUSED_UNSAFE, diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index bc9516b2e0c..04fdada8024 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -220,7 +220,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { } /// Generates the code for a field with no attributes. - fn generate_field_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream { + fn generate_field_arg(&mut self, binding_info: &BindingInfo<'_>) -> (TokenStream, TokenStream) { let diag = &self.parent.diag; let field = binding_info.ast(); @@ -230,12 +230,16 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { let ident = field.ident.as_ref().unwrap(); let ident = format_ident!("{}", ident); // strip `r#` prefix, if present - quote! { + let args = quote! { #diag.arg( stringify!(#ident), #field_binding ); - } + }; + let remove_args = quote! { + #diag.remove_arg(stringify!(#ident)); + }; + (args, remove_args) } /// Generates the necessary code for all attributes on a field. @@ -600,8 +604,13 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { calls.extend(call); } - - let plain_args: TokenStream = self + let store_args = quote! { + #diag.store_args(); + }; + let restore_args = quote! { + #diag.restore_args(); + }; + let (plain_args, remove_args): (TokenStream, TokenStream) = self .variant .bindings() .iter() @@ -610,12 +619,23 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { .collect(); let formatting_init = &self.formatting_init; + + // For #[derive(Subdiagnostic)] + // + // - Store args of the main diagnostic for later restore. + // - add args of subdiagnostic. + // - Generate the calls, such as note, label, etc. + // - Remove the arguments for allowing Vec<Subdiagnostic> to be used. + // - Restore the arguments for allowing main and subdiagnostic share the same fields. Ok(quote! { #init #formatting_init #attr_args + #store_args #plain_args #calls + #remove_args + #restore_args }) } } diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index fcae33c73c9..1089c4ac71c 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -314,7 +314,7 @@ fn add_library( crate_name: tcx.crate_name(cnum), non_static_deps: unavailable_as_static .drain(..) - .map(|cnum| NonStaticCrateDep { crate_name: tcx.crate_name(cnum) }) + .map(|cnum| NonStaticCrateDep { crate_name_: tcx.crate_name(cnum) }) .collect(), rustc_driver_help: linking_to_rustc_driver.then_some(RustcDriverHelp), }); diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 71da4290174..4a3b43167cf 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -45,7 +45,8 @@ pub struct CrateDepMultiple { #[derive(Subdiagnostic)] #[note(metadata_crate_dep_not_static)] pub struct NonStaticCrateDep { - pub crate_name: Symbol, + /// It's different from `crate_name` in main Diagnostic. + pub crate_name_: Symbol, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ed3c18a02a6..d74918235b6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -5,7 +5,7 @@ use std::io::{Read, Seek, Write}; use std::path::{Path, PathBuf}; use std::sync::Arc; -use rustc_ast::attr::AttributeExt; +use rustc_attr_data_structures::EncodeCrossCrate; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::sync::{join, par_for_each_in}; @@ -839,9 +839,13 @@ struct AnalyzeAttrState<'a> { /// visibility: this is a piece of data that can be computed once per defid, and not once per /// attribute. Some attributes would only be usable downstream if they are public. #[inline] -fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> bool { +fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState<'_>) -> bool { let mut should_encode = false; - if let Some(name) = attr.name() + if let hir::Attribute::Parsed(p) = attr + && p.encode_cross_crate() == EncodeCrossCrate::No + { + // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. + } else if let Some(name) = attr.name() && !rustc_feature::encode_cross_crate(name) { // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d877bd5c626..1a5a9765ce7 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -332,7 +332,11 @@ pub enum ObligationCauseCode<'tcx> { }, /// Computing common supertype in an if expression - IfExpression(Box<IfExpressionCause<'tcx>>), + IfExpression { + expr_id: HirId, + // Is the expectation of this match expression an RPIT? + tail_defines_return_position_impl_trait: Option<LocalDefId>, + }, /// Computing common supertype of an if expression with no else counter-part IfExpressionWithNoElse, @@ -550,18 +554,6 @@ pub struct PatternOriginExpr { pub peeled_prefix_suggestion_parentheses: bool, } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] -pub struct IfExpressionCause<'tcx> { - pub then_id: HirId, - pub else_id: HirId, - pub then_ty: Ty<'tcx>, - pub else_ty: Ty<'tcx>, - pub outer_span: Option<Span>, - // Is the expectation of this match expression an RPIT? - pub tail_defines_return_position_impl_trait: Option<LocalDefId>, -} - #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] #[derive(TypeVisitable, TypeFoldable)] pub struct DerivedCause<'tcx> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aa5355551ce..ca12f4aa80d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -781,8 +781,8 @@ bidirectional_lang_item_map! { Future, FutureOutput, Iterator, - Metadata, MetaSized, + Metadata, Option, PointeeSized, PointeeTrait, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 5cb943b0d8c..90b832df281 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1248,13 +1248,13 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi) | EfiApi | AvrInterrupt | AvrNonBlockingInterrupt + | CmseNonSecureCall + | CmseNonSecureEntry + | Custom | RiscvInterruptM | RiscvInterruptS - | CCmseNonSecureCall - | CCmseNonSecureEntry - | Custom - | Unadjusted - | RustInvalid => false, + | RustInvalid + | Unadjusted => false, Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind, } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 000ba7b6fa7..1214731a3b2 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -230,9 +230,9 @@ TrivialLiftImpls! { usize, u64, // tidy-alphabetical-start + crate::mir::Promoted, crate::mir::interpret::AllocId, crate::mir::interpret::Scalar, - crate::mir::Promoted, rustc_abi::ExternAbi, rustc_abi::Size, rustc_hir::Safety, @@ -267,9 +267,6 @@ TrivialTypeTraversalImpls! { crate::mir::SwitchTargets, crate::traits::IsConstable, crate::traits::OverflowError, - crate::ty::abstract_const::NotConstEvaluatable, - crate::ty::adjustment::AutoBorrowMutability, - crate::ty::adjustment::PointerCoercion, crate::ty::AdtKind, crate::ty::AssocItem, crate::ty::AssocKind, @@ -281,15 +278,18 @@ TrivialTypeTraversalImpls! { crate::ty::Placeholder<ty::BoundVar>, crate::ty::UserTypeAnnotationIndex, crate::ty::ValTree<'tcx>, + crate::ty::abstract_const::NotConstEvaluatable, + crate::ty::adjustment::AutoBorrowMutability, + crate::ty::adjustment::PointerCoercion, rustc_abi::FieldIdx, rustc_abi::VariantIdx, rustc_ast::InlineAsmOptions, rustc_ast::InlineAsmTemplatePiece, rustc_hir::CoroutineKind, - rustc_hir::def_id::LocalDefId, rustc_hir::HirId, rustc_hir::MatchSource, rustc_hir::RangeEnd, + rustc_hir::def_id::LocalDefId, rustc_span::Ident, rustc_span::Span, rustc_span::Symbol, @@ -303,9 +303,9 @@ TrivialTypeTraversalImpls! { // interners). TrivialTypeTraversalAndLiftImpls! { // tidy-alphabetical-start - crate::ty::instance::ReifyReason, crate::ty::ParamConst, crate::ty::ParamTy, + crate::ty::instance::ReifyReason, rustc_hir::def_id::DefId, // tidy-alphabetical-end } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 32df191cbca..20e836f6bf2 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -994,14 +994,15 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { pub(crate) uncovered: Uncovered, #[subdiagnostic] pub(crate) inform: Option<Inform>, - #[label(mir_build_confused)] - pub(crate) interpreted_as_const: Option<Span>, #[subdiagnostic] - pub(crate) interpreted_as_const_sugg: Option<InterpretedAsConst>, + pub(crate) interpreted_as_const: Option<InterpretedAsConst>, + #[subdiagnostic] + pub(crate) interpreted_as_const_sugg: Option<InterpretedAsConstSugg>, #[subdiagnostic] pub(crate) adt_defined_here: Option<AdtDefinedHere<'tcx>>, #[note(mir_build_privately_uninhabited)] pub(crate) witness_1_is_privately_uninhabited: bool, + pub(crate) witness_1: String, #[note(mir_build_pattern_ty)] pub(crate) _p: (), pub(crate) pattern_ty: Ty<'tcx>, @@ -1016,6 +1017,14 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { #[note(mir_build_more_information)] pub(crate) struct Inform; +#[derive(Subdiagnostic)] +#[label(mir_build_confused)] +pub(crate) struct InterpretedAsConst { + #[primary_span] + pub(crate) span: Span, + pub(crate) variable: String, +} + pub(crate) struct AdtDefinedHere<'tcx> { pub(crate) adt_def_span: Span, pub(crate) ty: Ty<'tcx>, @@ -1046,7 +1055,7 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { applicability = "maybe-incorrect", style = "verbose" )] -pub(crate) struct InterpretedAsConst { +pub(crate) struct InterpretedAsConstSugg { #[primary_span] pub(crate) span: Span, pub(crate) variable: String, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 9fd410e6bf1..41fbabc2539 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -690,8 +690,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let span = self.tcx.def_span(def_id); let variable = self.tcx.item_name(def_id).to_string(); // When we encounter a constant as the binding name, point at the `const` definition. - interpreted_as_const = Some(span); - interpreted_as_const_sugg = Some(InterpretedAsConst { span: pat.span, variable }); + interpreted_as_const = Some(InterpretedAsConst { span, variable: variable.clone() }); + interpreted_as_const_sugg = Some(InterpretedAsConstSugg { span: pat.span, variable }); } else if let PatKind::Constant { .. } = unpeeled_pat.kind && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) { @@ -743,6 +743,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { false }; + let witness_1 = cx.print_witness_pat(witnesses.get(0).unwrap()); + self.error = Err(self.tcx.dcx().emit_err(PatternNotCovered { span: pat.span, origin, @@ -751,6 +753,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { interpreted_as_const, interpreted_as_const_sugg, witness_1_is_privately_uninhabited, + witness_1, _p: (), pattern_ty, let_suggestion, diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 75f351f05c3..1bd770a8526 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -516,8 +516,12 @@ struct LocalLabel<'a> { /// A custom `Subdiagnostic` implementation so that the notes are delivered in a specific order impl Subdiagnostic for LocalLabel<'_> { fn add_to_diag<G: rustc_errors::EmissionGuarantee>(self, diag: &mut rustc_errors::Diag<'_, G>) { + // Becuase parent uses this field , we need to remove it delay before adding it. + diag.remove_arg("name"); diag.arg("name", self.name); + diag.remove_arg("is_generated_name"); diag.arg("is_generated_name", self.is_generated_name); + diag.remove_arg("is_dropped_first_edition_2024"); diag.arg("is_dropped_first_edition_2024", self.is_dropped_first_edition_2024); let msg = diag.eagerly_translate(crate::fluent_generated::mir_transform_tail_expr_local); diag.span_label(self.span, msg); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 06acf7bf992..f601d058b33 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -294,7 +294,7 @@ passes_duplicate_lang_item_crate_depends = .second_definition_path = second definition in `{$crate_name}` loaded from {$path} passes_enum_variant_same_name = - it is impossible to refer to the {$descr} `{$dead_name}` because it is shadowed by this enum variant with the same name + it is impossible to refer to the {$dead_descr} `{$dead_name}` because it is shadowed by this enum variant with the same name passes_export_name = attribute should be applied to a free function, impl method or static diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 4738036318d..ce43b2c281d 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -1056,7 +1056,7 @@ impl<'tcx> DeadVisitor<'tcx> { maybe_enum.variants().iter().find(|i| i.name == dead_item.name) { Some(crate::errors::EnumVariantSameName { - descr: tcx.def_descr(dead_item.def_id.to_def_id()), + dead_descr: tcx.def_descr(dead_item.def_id.to_def_id()), dead_name: dead_item.name, variant_span: tcx.def_span(variant.def_id), }) diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index c933647165c..d9ec167aae3 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1516,7 +1516,7 @@ pub(crate) struct EnumVariantSameName<'tcx> { #[primary_span] pub variant_span: Span, pub dead_name: Symbol, - pub descr: &'tcx str, + pub dead_descr: &'tcx str, } #[derive(Subdiagnostic)] @@ -1714,6 +1714,7 @@ impl Subdiagnostic for UnusedVariableStringInterp { #[derive(LintDiagnostic)] #[diag(passes_unused_variable_try_ignore)] pub(crate) struct UnusedVarTryIgnore { + pub name: String, #[subdiagnostic] pub sugg: UnusedVarTryIgnoreSugg, } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 125730377ef..3088e189c20 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1744,6 +1744,7 @@ impl<'tcx> Liveness<'_, 'tcx> { .map(|(_, pat_span, _)| *pat_span) .collect::<Vec<_>>(), errors::UnusedVarTryIgnore { + name: name.clone(), sugg: errors::UnusedVarTryIgnoreSugg { shorthands, non_shorthands, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9149974a617..8bca350c8ba 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -256,22 +256,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let label = match new_binding.is_import_user_facing() { - true => errors::NameDefinedMultipleTimeLabel::Reimported { span, name }, - false => errors::NameDefinedMultipleTimeLabel::Redefined { span, name }, + true => errors::NameDefinedMultipleTimeLabel::Reimported { span }, + false => errors::NameDefinedMultipleTimeLabel::Redefined { span }, }; let old_binding_label = (!old_binding.span.is_dummy() && old_binding.span != span).then(|| { let span = self.tcx.sess.source_map().guess_head_span(old_binding.span); match old_binding.is_import_user_facing() { - true => errors::NameDefinedMultipleTimeOldBindingLabel::Import { - span, - name, - old_kind, - }, + true => { + errors::NameDefinedMultipleTimeOldBindingLabel::Import { span, old_kind } + } false => errors::NameDefinedMultipleTimeOldBindingLabel::Definition { span, - name, old_kind, }, } @@ -281,6 +278,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .dcx() .create_err(errors::NameDefinedMultipleTime { span, + name, descr: ns.descr(), container, label, diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 7fe74378b67..6d3752c0c83 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -978,6 +978,7 @@ pub(crate) struct VariableNotInAllPatterns { pub(crate) struct NameDefinedMultipleTime { #[primary_span] pub(crate) span: Span, + pub(crate) name: Symbol, pub(crate) descr: &'static str, pub(crate) container: &'static str, #[subdiagnostic] @@ -992,13 +993,11 @@ pub(crate) enum NameDefinedMultipleTimeLabel { Reimported { #[primary_span] span: Span, - name: Symbol, }, #[label(resolve_name_defined_multiple_time_redefined)] Redefined { #[primary_span] span: Span, - name: Symbol, }, } @@ -1008,14 +1007,12 @@ pub(crate) enum NameDefinedMultipleTimeOldBindingLabel { Import { #[primary_span] span: Span, - name: Symbol, old_kind: &'static str, }, #[label(resolve_name_defined_multiple_time_old_binding_definition)] Definition { #[primary_span] span: Span, - name: Symbol, old_kind: &'static str, }, } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 931c6241bf2..3fe5db8ca54 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -49,6 +49,9 @@ pub struct DocFragment { pub doc: Symbol, pub kind: DocFragmentKind, pub indent: usize, + /// Because we tamper with the spans context, this information cannot be correctly retrieved + /// later on. So instead, we compute it and store it here. + pub from_expansion: bool, } #[derive(Clone, Copy, Debug)] @@ -208,17 +211,18 @@ pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>( for (attr, item_id) in attrs { if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { let doc = beautify_doc_string(doc_str, comment_kind); - let (span, kind) = if attr.is_doc_comment() { - (attr.span(), DocFragmentKind::SugaredDoc) + let (span, kind, from_expansion) = if attr.is_doc_comment() { + let span = attr.span(); + (span, DocFragmentKind::SugaredDoc, span.from_expansion()) } else { - ( - attr.value_span() - .map(|i| i.with_ctxt(attr.span().ctxt())) - .unwrap_or(attr.span()), - DocFragmentKind::RawDoc, - ) + let attr_span = attr.span(); + let (span, from_expansion) = match attr.value_span() { + Some(sp) => (sp.with_ctxt(attr_span.ctxt()), sp.from_expansion()), + None => (attr_span, attr_span.from_expansion()), + }; + (span, DocFragmentKind::RawDoc, from_expansion) }; - let fragment = DocFragment { span, doc, kind, item_id, indent: 0 }; + let fragment = DocFragment { span, doc, kind, item_id, indent: 0, from_expansion }; doc_fragments.push(fragment); } else if !doc_only { other_attrs.push(attr.clone()); @@ -505,17 +509,26 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>( display_text.map(String::into_boxed_str) } -/// Returns a span encompassing all the document fragments. -pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> { - if fragments.is_empty() { - return None; - } - let start = fragments[0].span; - if start == DUMMY_SP { +/// Returns a tuple containing a span encompassing all the document fragments and a boolean that is +/// `true` if any of the fragments are from a macro expansion. +pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Span, bool)> { + let (first_fragment, last_fragment) = match fragments { + [] => return None, + [first, .., last] => (first, last), + [first] => (first, first), + }; + if first_fragment.span == DUMMY_SP { return None; } - let end = fragments.last().expect("no doc strings provided").span; - Some(start.to(end)) + Some(( + first_fragment.span.to(last_fragment.span), + fragments.iter().any(|frag| frag.from_expansion), + )) +} + +/// Returns a span encompassing all the document fragments. +pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> { + span_of_fragments_with_expansion(fragments).map(|(sp, _)| sp) } /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. @@ -529,18 +542,22 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> { /// This method will return `Some` only if one of the following is true: /// /// - The doc is made entirely from sugared doc comments, which cannot contain escapes -/// - The doc is entirely from a single doc fragment with a string literal exactly equal to `markdown`. +/// - The doc is entirely from a single doc fragment with a string literal exactly equal to +/// `markdown`. /// - The doc comes from `include_str!` -/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment. +/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a +/// single doc fragment. +/// +/// This function is defined in the compiler so it can be used by both `rustdoc` and `clippy`. /// -/// This function is defined in the compiler so it can be used by -/// both `rustdoc` and `clippy`. +/// It returns a tuple containing a span encompassing all the document fragments and a boolean that +/// is `true` if any of the *matched* fragments are from a macro expansion. pub fn source_span_for_markdown_range( tcx: TyCtxt<'_>, markdown: &str, md_range: &Range<usize>, fragments: &[DocFragment], -) -> Option<Span> { +) -> Option<(Span, bool)> { let map = tcx.sess.source_map(); source_span_for_markdown_range_inner(map, markdown, md_range, fragments) } @@ -551,7 +568,7 @@ pub fn source_span_for_markdown_range_inner( markdown: &str, md_range: &Range<usize>, fragments: &[DocFragment], -) -> Option<Span> { +) -> Option<(Span, bool)> { use rustc_span::BytePos; if let &[fragment] = &fragments @@ -562,11 +579,14 @@ pub fn source_span_for_markdown_range_inner( && let Ok(md_range_hi) = u32::try_from(md_range.end) { // Single fragment with string that contains same bytes as doc. - return Some(Span::new( - fragment.span.lo() + rustc_span::BytePos(md_range_lo), - fragment.span.lo() + rustc_span::BytePos(md_range_hi), - fragment.span.ctxt(), - fragment.span.parent(), + return Some(( + Span::new( + fragment.span.lo() + rustc_span::BytePos(md_range_lo), + fragment.span.lo() + rustc_span::BytePos(md_range_hi), + fragment.span.ctxt(), + fragment.span.parent(), + ), + fragment.from_expansion, )); } @@ -598,19 +618,21 @@ pub fn source_span_for_markdown_range_inner( { match_data = Some((i, match_start)); } else { - // Heirustic produced ambiguity, return nothing. + // Heuristic produced ambiguity, return nothing. return None; } } } if let Some((i, match_start)) = match_data { - let sp = fragments[i].span; + let fragment = &fragments[i]; + let sp = fragment.span; // we need to calculate the span start, // then use that in our calulations for the span end let lo = sp.lo() + BytePos(match_start as u32); - return Some( + return Some(( sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)), - ); + fragment.from_expansion, + )); } return None; } @@ -664,8 +686,13 @@ pub fn source_span_for_markdown_range_inner( } } - Some(span_of_fragments(fragments)?.from_inner(InnerSpan::new( + let (span, _) = span_of_fragments_with_expansion(fragments)?; + let src_span = span.from_inner(InnerSpan::new( md_range.start + start_bytes, md_range.end + start_bytes + end_bytes, - ))) + )); + Some(( + src_span, + fragments.iter().any(|frag| frag.span.overlaps(src_span) && frag.from_expansion), + )) } diff --git a/compiler/rustc_resolve/src/rustdoc/tests.rs b/compiler/rustc_resolve/src/rustdoc/tests.rs index 221ac907e7c..6a98ae06630 100644 --- a/compiler/rustc_resolve/src/rustdoc/tests.rs +++ b/compiler/rustc_resolve/src/rustdoc/tests.rs @@ -10,7 +10,7 @@ use super::{DocFragment, DocFragmentKind, source_span_for_markdown_range_inner}; fn single_backtick() { let sm = SourceMap::new(FilePathMapping::empty()); sm.new_source_file(PathBuf::from("foo.rs").into(), r#"#[doc = "`"] fn foo() {}"#.to_string()); - let span = source_span_for_markdown_range_inner( + let (span, _) = source_span_for_markdown_range_inner( &sm, "`", &(0..1), @@ -20,6 +20,7 @@ fn single_backtick() { kind: DocFragmentKind::RawDoc, doc: sym::empty, // unused placeholder indent: 0, + from_expansion: false, }], ) .unwrap(); @@ -32,7 +33,7 @@ fn utf8() { // regression test for https://github.com/rust-lang/rust/issues/141665 let sm = SourceMap::new(FilePathMapping::empty()); sm.new_source_file(PathBuf::from("foo.rs").into(), r#"#[doc = "⚠"] fn foo() {}"#.to_string()); - let span = source_span_for_markdown_range_inner( + let (span, _) = source_span_for_markdown_range_inner( &sm, "⚠", &(0..3), @@ -42,6 +43,7 @@ fn utf8() { kind: DocFragmentKind::RawDoc, doc: sym::empty, // unused placeholder indent: 0, + from_expansion: false, }], ) .unwrap(); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index c62e4ac30ea..73bb0471c22 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -227,13 +227,15 @@ pub enum CoverageLevel { } /// The different settings that the `-Z autodiff` flag can have. -#[derive(Clone, Copy, PartialEq, Hash, Debug)] +#[derive(Clone, PartialEq, Hash, Debug)] pub enum AutoDiff { /// Enable the autodiff opt pipeline Enable, /// Print TypeAnalysis information PrintTA, + /// Print TypeAnalysis information for a specific function + PrintTAFn(String), /// Print ActivityAnalysis Information PrintAA, /// Print Performance Warnings from Enzyme diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 232531dc673..ecd82c0cc01 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -725,7 +725,7 @@ mod desc { pub(crate) const parse_list: &str = "a space-separated list of strings"; pub(crate) const parse_list_with_polarity: &str = "a comma-separated list of strings, with elements beginning with + or -"; - pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `PrintPasses`, `NoPostopt`, `LooseTypes`, `Inline`"; + pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintTAFn`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `PrintPasses`, `NoPostopt`, `LooseTypes`, `Inline`"; pub(crate) const parse_comma_list: &str = "a comma-separated list of strings"; pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_number: &str = "a number"; @@ -1365,9 +1365,22 @@ pub mod parse { let mut v: Vec<&str> = v.split(",").collect(); v.sort_unstable(); for &val in v.iter() { - let variant = match val { + // Split each entry on '=' if it has an argument + let (key, arg) = match val.split_once('=') { + Some((k, a)) => (k, Some(a)), + None => (val, None), + }; + + let variant = match key { "Enable" => AutoDiff::Enable, "PrintTA" => AutoDiff::PrintTA, + "PrintTAFn" => { + if let Some(fun) = arg { + AutoDiff::PrintTAFn(fun.to_string()) + } else { + return false; + } + } "PrintAA" => AutoDiff::PrintAA, "PrintPerf" => AutoDiff::PrintPerf, "PrintSteps" => AutoDiff::PrintSteps, diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index c0d9937e34d..24351eee1c4 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -479,6 +479,8 @@ impl RustcInternal for Abi { Abi::Vectorcall { unwind } => rustc_abi::ExternAbi::Vectorcall { unwind }, Abi::Thiscall { unwind } => rustc_abi::ExternAbi::Thiscall { unwind }, Abi::Aapcs { unwind } => rustc_abi::ExternAbi::Aapcs { unwind }, + Abi::CCmseNonSecureCall => rustc_abi::ExternAbi::CmseNonSecureCall, + Abi::CCmseNonSecureEntry => rustc_abi::ExternAbi::CmseNonSecureEntry, Abi::Win64 { unwind } => rustc_abi::ExternAbi::Win64 { unwind }, Abi::SysV64 { unwind } => rustc_abi::ExternAbi::SysV64 { unwind }, Abi::PtxKernel => rustc_abi::ExternAbi::PtxKernel, @@ -488,8 +490,6 @@ impl RustcInternal for Abi { Abi::EfiApi => rustc_abi::ExternAbi::EfiApi, Abi::AvrInterrupt => rustc_abi::ExternAbi::AvrInterrupt, Abi::AvrNonBlockingInterrupt => rustc_abi::ExternAbi::AvrNonBlockingInterrupt, - Abi::CCmseNonSecureCall => rustc_abi::ExternAbi::CCmseNonSecureCall, - Abi::CCmseNonSecureEntry => rustc_abi::ExternAbi::CCmseNonSecureEntry, Abi::System { unwind } => rustc_abi::ExternAbi::System { unwind }, Abi::RustCall => rustc_abi::ExternAbi::RustCall, Abi::Unadjusted => rustc_abi::ExternAbi::Unadjusted, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 2c652c7546e..7abec488151 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -871,8 +871,8 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi { ExternAbi::EfiApi => Abi::EfiApi, ExternAbi::AvrInterrupt => Abi::AvrInterrupt, ExternAbi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt, - ExternAbi::CCmseNonSecureCall => Abi::CCmseNonSecureCall, - ExternAbi::CCmseNonSecureEntry => Abi::CCmseNonSecureEntry, + ExternAbi::CmseNonSecureCall => Abi::CCmseNonSecureCall, + ExternAbi::CmseNonSecureEntry => Abi::CCmseNonSecureEntry, ExternAbi::System { unwind } => Abi::System { unwind }, ExternAbi::RustCall => Abi::RustCall, ExternAbi::Unadjusted => Abi::Unadjusted, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c9262d24a17..11463ad354a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -406,6 +406,7 @@ symbols! { abi_amdgpu_kernel, abi_avr_interrupt, abi_c_cmse_nonsecure_call, + abi_cmse_nonsecure_call, abi_custom, abi_efiapi, abi_gpu_kernel, diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index ce1bdcbb8ac..b13e2112478 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -85,24 +85,35 @@ impl AbiMap { (ExternAbi::System { .. }, _) => CanonAbi::C, // fallible lowerings + /* multi-platform */ + // always and forever + (ExternAbi::RustInvalid, _) => return AbiMapping::Invalid, + (ExternAbi::EfiApi, Arch::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), (ExternAbi::EfiApi, Arch::X86_64) => CanonAbi::X86(X86Call::Win64), (ExternAbi::EfiApi, Arch::Aarch64 | Arch::Riscv | Arch::X86) => CanonAbi::C, (ExternAbi::EfiApi, _) => return AbiMapping::Invalid, + /* arm */ (ExternAbi::Aapcs { .. }, Arch::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), (ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::CCmseNonSecureCall, Arch::Arm(ArmVer::ThumbV8M)) => { + (ExternAbi::CmseNonSecureCall, Arch::Arm(ArmVer::ThumbV8M)) => { CanonAbi::Arm(ArmCall::CCmseNonSecureCall) } - (ExternAbi::CCmseNonSecureEntry, Arch::Arm(ArmVer::ThumbV8M)) => { + (ExternAbi::CmseNonSecureEntry, Arch::Arm(ArmVer::ThumbV8M)) => { CanonAbi::Arm(ArmCall::CCmseNonSecureEntry) } - (ExternAbi::CCmseNonSecureCall | ExternAbi::CCmseNonSecureEntry, ..) => { + (ExternAbi::CmseNonSecureCall | ExternAbi::CmseNonSecureEntry, ..) => { return AbiMapping::Invalid; } + /* gpu */ + (ExternAbi::PtxKernel, Arch::Nvptx) => CanonAbi::GpuKernel, + (ExternAbi::GpuKernel, Arch::Amdgpu | Arch::Nvptx) => CanonAbi::GpuKernel, + (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid, + + /* x86 */ (ExternAbi::Cdecl { .. }, Arch::X86) => CanonAbi::C, (ExternAbi::Cdecl { .. }, _) => return AbiMapping::Deprecated(CanonAbi::C), @@ -130,10 +141,7 @@ impl AbiMap { (ExternAbi::Win64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::Win64), (ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::PtxKernel, Arch::Nvptx) => CanonAbi::GpuKernel, - (ExternAbi::GpuKernel, Arch::Amdgpu | Arch::Nvptx) => CanonAbi::GpuKernel, - (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid, - + /* interrupts */ (ExternAbi::AvrInterrupt, Arch::Avr) => CanonAbi::Interrupt(InterruptKind::Avr), (ExternAbi::AvrNonBlockingInterrupt, Arch::Avr) => { CanonAbi::Interrupt(InterruptKind::AvrNonBlocking) @@ -156,8 +164,7 @@ impl AbiMap { | ExternAbi::Msp430Interrupt | ExternAbi::RiscvInterruptM | ExternAbi::RiscvInterruptS - | ExternAbi::X86Interrupt - | ExternAbi::RustInvalid, + | ExternAbi::X86Interrupt, _, ) => return AbiMapping::Invalid, }; diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 3eea1e070a6..b2af99228fe 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -212,9 +212,6 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]), // We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`. ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]), - // FEAT_FP16 - // Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608 - ("fp16", Stable, &["neon"]), // FEAT_FP8 ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]), // FEAT_FP8DOT2 @@ -223,6 +220,9 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]), // FEAT_FP8FMA ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]), + // FEAT_FP16 + // Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608 + ("fp16", Stable, &["neon"]), // FEAT_FRINTTS ("frintts", Stable, &[]), // FEAT_HBC @@ -236,10 +236,10 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("lor", Stable, &[]), // FEAT_LSE ("lse", Stable, &[]), - // FEAT_LSE128 - ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]), // FEAT_LSE2 ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]), + // FEAT_LSE128 + ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]), // FEAT_LUT ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]), // FEAT_MOPS @@ -283,14 +283,14 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]), // FEAT_SME_B16B16 ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]), - // FEAT_SME_F16F16 - ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]), - // FEAT_SME_F64F64 - ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]), // FEAT_SME_F8F16 ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]), // FEAT_SME_F8F32 ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]), + // FEAT_SME_F16F16 + ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]), + // FEAT_SME_F64F64 + ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]), // FEAT_SME_FA64 ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]), // FEAT_SME_I16I64 @@ -376,8 +376,8 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), - ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), + ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), @@ -385,6 +385,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("apxf", Unstable(sym::apx_target_feature), &[]), ("avx", Stable, &["sse4.2"]), + ("avx2", Stable, &["avx"]), ( "avx10.1", Unstable(sym::avx10_target_feature), @@ -405,7 +406,6 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ], ), ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]), - ("avx2", Stable, &["avx"]), ("avx512bf16", Stable, &["avx512bw"]), ("avx512bitalg", Stable, &["avx512bw"]), ("avx512bw", Stable, &["avx512f"]), @@ -423,8 +423,8 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("avxifma", Stable, &["avx2"]), ("avxneconvert", Stable, &["avx2"]), ("avxvnni", Stable, &["avx2"]), - ("avxvnniint16", Stable, &["avx2"]), ("avxvnniint8", Stable, &["avx2"]), + ("avxvnniint16", Stable, &["avx2"]), ("bmi1", Stable, &[]), ("bmi2", Stable, &[]), ("cmpxchg16b", Stable, &[]), @@ -498,12 +498,12 @@ static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("altivec", Unstable(sym::powerpc_target_feature), &[]), ("msync", Unstable(sym::powerpc_target_feature), &[]), ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]), - ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]), ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]), ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]), ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]), ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]), ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]), + ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]), ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]), ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]), // tidy-alphabetical-end @@ -535,8 +535,8 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]), ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]), ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]), - ("za128rs", Unstable(sym::riscv_target_feature), &[]), ("za64rs", Unstable(sym::riscv_target_feature), &["za128rs"]), // Za64rs ⊃ Za128rs + ("za128rs", Unstable(sym::riscv_target_feature), &[]), ("zaamo", Unstable(sym::riscv_target_feature), &[]), ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]), ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]), @@ -613,18 +613,18 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]), ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]), ("zvkt", Unstable(sym::riscv_target_feature), &[]), - ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]), + ("zvl32b", Unstable(sym::riscv_target_feature), &[]), + ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]), ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]), - ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]), - ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]), ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]), - ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]), - ("zvl32b", Unstable(sym::riscv_target_feature), &[]), - ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]), ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]), - ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]), - ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]), + ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]), + ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]), + ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]), ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]), + ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]), + ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]), + ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]), // tidy-alphabetical-end ]; @@ -651,13 +651,13 @@ const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] = static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start - ("10e60", Unstable(sym::csky_target_feature), &["7e10"]), ("2e3", Unstable(sym::csky_target_feature), &["e2"]), ("3e3r1", Unstable(sym::csky_target_feature), &[]), ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]), ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]), ("3e7", Unstable(sym::csky_target_feature), &["2e3"]), ("7e10", Unstable(sym::csky_target_feature), &["3e7"]), + ("10e60", Unstable(sym::csky_target_feature), &["7e10"]), ("cache", Unstable(sym::csky_target_feature), &[]), ("doloop", Unstable(sym::csky_target_feature), &[]), ("dsp1e2", Unstable(sym::csky_target_feature), &[]), @@ -726,12 +726,12 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("guarded-storage", Unstable(sym::s390x_target_feature), &[]), ("high-word", Unstable(sym::s390x_target_feature), &[]), // LLVM does not define message-security-assist-extension versions 1, 2, 6, 10 and 11. - ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]), ("message-security-assist-extension3", Unstable(sym::s390x_target_feature), &[]), ("message-security-assist-extension4", Unstable(sym::s390x_target_feature), &[]), ("message-security-assist-extension5", Unstable(sym::s390x_target_feature), &[]), ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]), ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]), + ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]), ("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature), &[]), ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature), &[]), ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature), &[]), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 2c16672d786..bc464b099e2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -82,9 +82,7 @@ use crate::infer; use crate::infer::relate::{self, RelateResult, TypeRelation}; use crate::infer::{InferCtxt, InferCtxtExt as _, TypeTrace, ValuePairs}; use crate::solve::deeply_normalize_for_diagnostics; -use crate::traits::{ - IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, -}; +use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode}; mod note_and_explain; mod suggest; @@ -613,18 +611,28 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } }, - ObligationCauseCode::IfExpression(box IfExpressionCause { - then_id, - else_id, - then_ty, - else_ty, - outer_span, - .. - }) => { - let then_span = self.find_block_span_from_hir_id(then_id); - let else_span = self.find_block_span_from_hir_id(else_id); - if let hir::Node::Expr(e) = self.tcx.hir_node(else_id) - && let hir::ExprKind::If(_cond, _then, None) = e.kind + ObligationCauseCode::IfExpression { expr_id, .. } => { + let hir::Node::Expr(&hir::Expr { + kind: hir::ExprKind::If(cond_expr, then_expr, Some(else_expr)), + span: expr_span, + .. + }) = self.tcx.hir_node(expr_id) + else { + return; + }; + let then_span = self.find_block_span_from_hir_id(then_expr.hir_id); + let then_ty = self + .typeck_results + .as_ref() + .expect("if expression only expected inside FnCtxt") + .expr_ty(then_expr); + let else_span = self.find_block_span_from_hir_id(else_expr.hir_id); + let else_ty = self + .typeck_results + .as_ref() + .expect("if expression only expected inside FnCtxt") + .expr_ty(else_expr); + if let hir::ExprKind::If(_cond, _then, None) = else_expr.kind && else_ty.is_unit() { // Account for `let x = if a { 1 } else if b { 2 };` @@ -632,9 +640,32 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.note("consider adding an `else` block that evaluates to the expected type"); } err.span_label(then_span, "expected because of this"); + + let outer_span = if self.tcx.sess.source_map().is_multiline(expr_span) { + if then_span.hi() == expr_span.hi() || else_span.hi() == expr_span.hi() { + // Point at condition only if either block has the same end point as + // the whole expression, since that'll cause awkward overlapping spans. + Some(expr_span.shrink_to_lo().to(cond_expr.peel_drop_temps().span)) + } else { + Some(expr_span) + } + } else { + None + }; if let Some(sp) = outer_span { err.span_label(sp, "`if` and `else` have incompatible types"); } + + let then_id = if let hir::ExprKind::Block(then_blk, _) = then_expr.kind { + then_blk.hir_id + } else { + then_expr.hir_id + }; + let else_id = if let hir::ExprKind::Block(else_blk, _) = else_expr.kind { + else_blk.hir_id + } else { + else_expr.hir_id + }; if let Some(subdiag) = self.suggest_remove_semi_or_return_binding( Some(then_id), then_ty, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index be508c8cee1..0a4a9144c94 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -420,19 +420,33 @@ impl<T> Trait<T> for X { } // If two if arms can be coerced to a trait object, provide a structured // suggestion. - let ObligationCauseCode::IfExpression(cause) = cause.code() else { + let ObligationCauseCode::IfExpression { expr_id, .. } = cause.code() else { return; }; - let hir::Node::Block(blk) = self.tcx.hir_node(cause.then_id) else { - return; - }; - let Some(then) = blk.expr else { - return; - }; - let hir::Node::Block(blk) = self.tcx.hir_node(cause.else_id) else { - return; - }; - let Some(else_) = blk.expr else { + let hir::Node::Expr(&hir::Expr { + kind: + hir::ExprKind::If( + _, + &hir::Expr { + kind: + hir::ExprKind::Block( + &hir::Block { expr: Some(then), .. }, + _, + ), + .. + }, + Some(&hir::Expr { + kind: + hir::ExprKind::Block( + &hir::Block { expr: Some(else_), .. }, + _, + ), + .. + }), + ), + .. + }) = self.tcx.hir_node(*expr_id) + else { return; }; let expected = match values.found.kind() { @@ -486,8 +500,10 @@ impl<T> Trait<T> for X { } } (ty::Adt(_, _), ty::Adt(def, args)) - if let ObligationCauseCode::IfExpression(cause) = cause.code() - && let hir::Node::Block(blk) = self.tcx.hir_node(cause.then_id) + if let ObligationCauseCode::IfExpression { expr_id, .. } = cause.code() + && let hir::Node::Expr(if_expr) = self.tcx.hir_node(*expr_id) + && let hir::ExprKind::If(_, then_expr, _) = if_expr.kind + && let hir::ExprKind::Block(blk, _) = then_expr.kind && let Some(then) = blk.expr && def.is_box() && let boxed_ty = args.type_at(0) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index 3804c13acce..c0daf08ce07 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -8,9 +8,7 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::{MatchSource, Node}; -use rustc_middle::traits::{ - IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, -}; +use rustc_middle::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt}; @@ -196,8 +194,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause .code() { - ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { - let then_span = self.find_block_span_from_hir_id(*then_id); + ObligationCauseCode::IfExpression { expr_id, .. } => { + let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::If(_, then_expr, _), .. + }) = self.tcx.hir_node(*expr_id) + else { + return; + }; + let then_span = self.find_block_span_from_hir_id(then_expr.hir_id); Some(ConsiderAddingAwait::BothFuturesSugg { first: then_span.shrink_to_hi(), second: exp_span.shrink_to_hi(), @@ -232,8 +236,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span: then_span.shrink_to_hi(), }) } - ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { - let then_span = self.find_block_span_from_hir_id(*then_id); + ObligationCauseCode::IfExpression { expr_id, .. } => { + let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::If(_, then_expr, _), .. + }) = self.tcx.hir_node(*expr_id) + else { + return; + }; + let then_span = self.find_block_span_from_hir_id(then_expr.hir_id); Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() }) } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { diff --git a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs index 84e7686fdd3..ec3c1ba4a45 100644 --- a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs @@ -163,12 +163,14 @@ impl RegionExplanation<'_> { impl Subdiagnostic for RegionExplanation<'_> { fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { + diag.store_args(); diag.arg("pref_kind", self.prefix); diag.arg("suff_kind", self.suffix); diag.arg("desc_kind", self.desc.kind); diag.arg("desc_arg", self.desc.arg); let msg = diag.eagerly_translate(fluent::trait_selection_region_explanation); + diag.restore_args(); if let Some(span) = self.desc.span { diag.span_note(span, msg); } else { diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 3ee6e07b7a5..f9994448e28 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -29,8 +29,8 @@ pub enum TraitSolverLangItem { Future, FutureOutput, Iterator, - Metadata, MetaSized, + Metadata, Option, PointeeSized, PointeeTrait, diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index c8c293121ca..9064f13eb45 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -53,11 +53,11 @@ TrivialTypeTraversalImpls! { crate::BoundConstness, crate::DebruijnIndex, crate::PredicatePolarity, + crate::UniverseIndex, + crate::Variance, crate::solve::BuiltinImplSource, crate::solve::Certainty, crate::solve::GoalSource, - crate::UniverseIndex, - crate::Variance, rustc_ast_ir::Mutability, // tidy-alphabetical-end } |
