diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 8556e8288670f..ff389607457d4 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -757,9 +757,11 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result; } - // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier + // This is only used by the MutVisitor. We include this symmetry here to make writing other + // functions easier. $(${ignore($lt)} - #[expect(unused, rustc::pass_by_value)] + #[cfg_attr(not(bootstrap), expect(unused, rustc::disallowed_pass_by_ref))] + #[cfg_attr(bootstrap, expect(unused, rustc::pass_by_value))] #[inline] )? fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 24a7215ddb385..ee21f0df5e217 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2521,16 +2521,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExprKind::Block(block, _) => { if let [stmt] = block.stmts.as_slice() && let StmtKind::Expr(expr) = &stmt.kind - && matches!( - expr.kind, - ExprKind::Block(..) - | ExprKind::Path(..) - | ExprKind::Struct(..) - | ExprKind::Call(..) - | ExprKind::Tup(..) - | ExprKind::Array(..) - | ExprKind::ConstBlock(..) - ) { return self.lower_expr_to_const_arg_direct(expr); } @@ -2553,6 +2543,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let span = expr.span; let literal = self.lower_lit(literal, span); + if !matches!(literal.node, LitKind::Int(..)) { + let err = + self.dcx().struct_span_err(expr.span, "negated literal must be an integer"); + + return ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Error(err.emit()), + span, + }; + } + ConstArg { hir_id: self.lower_node_id(expr.id), kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true }, diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 941885d232c27..e35c10996ceb2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -9,7 +9,7 @@ use rustc_hir::{ use super::prelude::*; use super::util::parse_version; -use crate::session_diagnostics::{self}; +use crate::session_diagnostics; macro_rules! reject_outside_std { ($cx: ident) => { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index e98969dda300b..987c0cb04c84d 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -1,6 +1,6 @@ use std::num::IntErrorKind; -use rustc_ast::{self as ast}; +use rustc_ast as ast; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index 423b6a15b646d..b294328b0bb17 100644 --- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs @@ -1,6 +1,6 @@ //! Attributes injected into the crate root from command line using `-Z crate-attr`. -use rustc_ast::{self as ast}; +use rustc_ast as ast; use rustc_errors::Diag; use rustc_parse::parser::attr::InnerAttrPolicy; use rustc_parse::{parse_in, source_str_to_stream}; diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index d9b82e97cb462..650e6262b35e8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -26,15 +26,14 @@ pub(crate) fn expand_deriving_eq( additional_bounds: Vec::new(), supports_unions: true, methods: vec![MethodDef { - name: sym::assert_receiver_is_total_eq, + name: sym::assert_fields_are_eq, generics: Bounds::empty(), explicit_self: true, nonself_args: vec![], ret_ty: Unit, attributes: thin_vec![ - cx.attr_word(sym::inline, span), cx.attr_nested_word(sym::doc, sym::hidden, span), - cx.attr_nested_word(sym::coverage, sym::off, span) + cx.attr_nested_word(sym::coverage, sym::off, span), ], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, combine_substructure: combine_substructure(Box::new(|a, b, c| { diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index e1937f5c11eb5..f65da57317ce0 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1655,6 +1655,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { unimplemented!(); } + fn get_funclet_cleanuppad(&self, _funclet: &Funclet) -> RValue<'gcc> { + unimplemented!(); + } + // Atomic Operations fn atomic_cmpxchg( &mut self, diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4ffc836f5559c..16c9d557d6b65 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1296,6 +1296,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ret } + fn get_funclet_cleanuppad(&self, funclet: &Funclet<'ll>) -> &'ll Value { + funclet.cleanuppad() + } + // Atomic Operations fn atomic_cmpxchg( &mut self, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 4ecc3086e1bdf..348c54b00ba97 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -21,8 +21,8 @@ use crate::debuginfo::metadata::{ size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags, }; use crate::debuginfo::utils::DIB; +use crate::llvm; use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; -use crate::llvm::{self}; // The names of the associated constants in each variant wrapper struct. // These have to match up with the names being used in `intrinsic.natvis`. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index caff358607974..556158c286a84 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -21,8 +21,8 @@ use crate::debuginfo::metadata::{ file_metadata_from_def_id, type_di_node, unknown_file_metadata, }; use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item}; +use crate::llvm; use crate::llvm::debuginfo::{DIFlags, DIType}; -use crate::llvm::{self}; mod cpp_like; mod native; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 1ae6e6e5eecab..a3299af35ac21 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -5,9 +5,8 @@ use rustc_abi::{Size, TagEncoding, VariantIdx, Variants}; use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name; use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo}; use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods}; -use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_middle::ty::{self}; +use rustc_middle::{bug, ty}; use smallvec::smallvec; use crate::common::{AsCCharPtr, CodegenCx}; @@ -18,8 +17,8 @@ use crate::debuginfo::metadata::{ unknown_file_metadata, visibility_di_flags, }; use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item}; +use crate::llvm; use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; -use crate::llvm::{self}; /// Build the debuginfo node for an enum type. The listing below shows how such a /// type looks like at the LLVM IR/DWARF level. It is a `DW_TAG_structure_type` diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 37200fdc41afa..316ec9cb73e78 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -12,8 +12,8 @@ use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use crate::common::CodegenCx; use crate::debuginfo::utils::{DIB, create_DIArray, debug_context}; +use crate::llvm; use crate::llvm::debuginfo::{DIFlags, DIScope, DIType}; -use crate::llvm::{self}; mod private { use rustc_macros::HashStable; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 6bcc8135f35e8..854fbbcea3ee1 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -13,8 +13,8 @@ use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; use rustc_data_structures::assert_matches; +use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_hir::{self as hir}; use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::offload_meta::OffloadMetadata; diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 35de8b5e1486b..4859380daa662 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -215,19 +215,18 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { mir::UnwindAction::Continue => None, mir::UnwindAction::Unreachable => None, mir::UnwindAction::Terminate(reason) => { - if fx.mir[self.bb].is_cleanup && base::wants_new_eh_instructions(fx.cx.tcx().sess) { + if fx.mir[self.bb].is_cleanup && base::wants_wasm_eh(fx.cx.tcx().sess) { + // For wasm, we need to generate a nested `cleanuppad within %outer_pad` + // to catch exceptions during cleanup and call `panic_in_cleanup`. + Some(fx.terminate_block(reason, Some(self.bb))) + } else if fx.mir[self.bb].is_cleanup + && base::wants_new_eh_instructions(fx.cx.tcx().sess) + { // MSVC SEH will abort automatically if an exception tries to // propagate out from cleanup. - - // FIXME(@mirkootter): For wasm, we currently do not support terminate during - // cleanup, because this requires a few more changes: The current code - // caches the `terminate_block` for each function; funclet based code - however - - // requires a different terminate_block for each funclet - // Until this is implemented, we just do not unwind inside cleanup blocks - None } else { - Some(fx.terminate_block(reason)) + Some(fx.terminate_block(reason, None)) } } }; @@ -239,7 +238,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { if let Some(unwind_block) = unwind_block { let ret_llbb = if let Some((_, target)) = destination { - fx.llbb(target) + self.llbb_with_cleanup(fx, target) } else { fx.unreachable_block() }; @@ -310,7 +309,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { ) -> MergingSucc { let unwind_target = match unwind { mir::UnwindAction::Cleanup(cleanup) => Some(self.llbb_with_cleanup(fx, cleanup)), - mir::UnwindAction::Terminate(reason) => Some(fx.terminate_block(reason)), + mir::UnwindAction::Terminate(reason) => Some(fx.terminate_block(reason, None)), mir::UnwindAction::Continue => None, mir::UnwindAction::Unreachable => None, }; @@ -318,7 +317,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { if operands.iter().any(|x| matches!(x, InlineAsmOperandRef::Label { .. })) { assert!(unwind_target.is_none()); let ret_llbb = if let Some(target) = destination { - fx.llbb(target) + self.llbb_with_cleanup(fx, target) } else { fx.unreachable_block() }; @@ -335,7 +334,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { MergingSucc::False } else if let Some(cleanup) = unwind_target { let ret_llbb = if let Some(target) = destination { - fx.llbb(target) + self.llbb_with_cleanup(fx, target) } else { fx.unreachable_block() }; @@ -1830,8 +1829,39 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }) } - fn terminate_block(&mut self, reason: UnwindTerminateReason) -> Bx::BasicBlock { - if let Some((cached_bb, cached_reason)) = self.terminate_block + fn terminate_block( + &mut self, + reason: UnwindTerminateReason, + outer_catchpad_bb: Option, + ) -> Bx::BasicBlock { + // mb_funclet_bb should be present if and only if the target is wasm and + // we're terminating because of an unwind in a cleanup block. In that + // case we have nested funclets and the inner catch_switch needs to know + // what outer catch_pad it is contained in. + debug_assert!( + outer_catchpad_bb.is_some() + == (base::wants_wasm_eh(self.cx.tcx().sess) + && reason == UnwindTerminateReason::InCleanup) + ); + + // When we aren't in a wasm InCleanup block, there's only one terminate + // block needed so we cache at START_BLOCK index. + let mut cache_bb = mir::START_BLOCK; + // In wasm eh InCleanup, use the outer funclet's cleanup BB as the cache + // key. + if let Some(outer_bb) = outer_catchpad_bb { + let cleanup_kinds = + self.cleanup_kinds.as_ref().expect("cleanup_kinds required for funclets"); + cache_bb = cleanup_kinds[outer_bb] + .funclet_bb(outer_bb) + .expect("funclet_bb should be in a funclet"); + + // Ensure the outer funclet is created first + if self.funclets[cache_bb].is_none() { + self.landing_pad_for(cache_bb); + } + } + if let Some((cached_bb, cached_reason)) = self.terminate_blocks[cache_bb] && reason == cached_reason { return cached_bb; @@ -1869,12 +1899,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // cp_terminate: // %cp = catchpad within %cs [null, i32 64, null] // ... + // + // By contrast, on WebAssembly targets, we specifically _do_ want to + // catch foreign exceptions. The situation with MSVC is a + // regrettable hack which we don't want to extend to other targets + // unless necessary. For WebAssembly, to generate catch(...) and + // catch only C++ exception instead of generating a catch_all, we + // need to call the intrinsics @llvm.wasm.get.exception and + // @llvm.wasm.get.ehselector in the catch pad. Since we don't do + // this, we generate a catch_all. We originally got this behavior + // by accident but it luckily matches our intention. llbb = Bx::append_block(self.cx, self.llfn, "cs_terminate"); - let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate"); let mut cs_bx = Bx::build(self.cx, llbb); - let cs = cs_bx.catch_switch(None, None, &[cp_llbb]); + + // For wasm InCleanup blocks, our catch_switch is nested within the + // outer catchpad, so we need to provide it as the parent value to + // catch_switch. + let mut outer_cleanuppad = None; + if outer_catchpad_bb.is_some() { + // Get the outer funclet's catchpad + let outer_funclet = self.funclets[cache_bb] + .as_ref() + .expect("landing_pad_for didn't create funclet"); + outer_cleanuppad = Some(cs_bx.get_funclet_cleanuppad(outer_funclet)); + } + let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate"); + let cs = cs_bx.catch_switch(outer_cleanuppad, None, &[cp_llbb]); + drop(cs_bx); bx = Bx::build(self.cx, cp_llbb); let null = @@ -1895,13 +1948,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { // Specifying more arguments than necessary usually doesn't // hurt, but the `WasmEHPrepare` LLVM pass does not recognize - // anything other than a single `null` as a `catch (...)` block, + // anything other than a single `null` as a `catch_all` block, // leading to problems down the line during instruction // selection. &[null] as &[_] }; funclet = Some(bx.catch_pad(cs, args)); + // On wasm, if we wanted to generate a catch(...) and only catch C++ + // exceptions, we'd call @llvm.wasm.get.exception and + // @llvm.wasm.get.ehselector selectors here. We want a catch_all so + // we leave them out. This is intentionally diverging from the MSVC + // behavior. } else { llbb = Bx::append_block(self.cx, self.llfn, "terminate"); bx = Bx::build(self.cx, llbb); @@ -1927,7 +1985,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.unreachable(); - self.terminate_block = Some((llbb, reason)); + self.terminate_blocks[cache_bb] = Some((llbb, reason)); llbb } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 819abb9ae644d..1a0f66d31cca4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -90,8 +90,11 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// Cached unreachable block unreachable_block: Option, - /// Cached terminate upon unwinding block and its reason - terminate_block: Option<(Bx::BasicBlock, UnwindTerminateReason)>, + /// Cached terminate upon unwinding block and its reason. For non-wasm + /// targets, there is at most one such block per function, stored at index + /// `START_BLOCK`. For wasm targets, each funclet needs its own terminate + /// block, indexed by the cleanup block that is the funclet's head. + terminate_blocks: IndexVec>, /// A bool flag for each basic block indicating whether it is a cold block. /// A cold block is a block that is unlikely to be executed at runtime. @@ -227,7 +230,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( personality_slot: None, cached_llbbs, unreachable_block: None, - terminate_block: None, + terminate_blocks: IndexVec::from_elem(None, &mir.basic_blocks), cleanup_kinds, landing_pads: IndexVec::from_elem(None, &mir.basic_blocks), funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()), diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 3486bd140eceb..edabd8188a3b6 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -552,12 +552,12 @@ pub trait BuilderMethods<'a, 'tcx>: fn set_personality_fn(&mut self, personality: Self::Function); - // These are used by everyone except msvc + // These are used by everyone except msvc and wasm EH fn cleanup_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 + // These are used by msvc and wasm EH fn cleanup_pad(&mut self, parent: Option, args: &[Self::Value]) -> Self::Funclet; fn cleanup_ret(&mut self, funclet: &Self::Funclet, unwind: Option); fn catch_pad(&mut self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet; @@ -567,6 +567,7 @@ pub trait BuilderMethods<'a, 'tcx>: unwind: Option, handlers: &[Self::BasicBlock], ) -> Self::Value; + fn get_funclet_cleanuppad(&self, funclet: &Self::Funclet) -> Self::Value; fn atomic_cmpxchg( &mut self, diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 6694a6e8ae403..41d21bd74f98c 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -110,7 +110,7 @@ pub fn get_span_and_frames<'tcx>( tcx: TyCtxtAt<'tcx>, stack: &[Frame<'tcx, impl Provenance, impl Sized>], ) -> (Span, Vec) { - let mut stacktrace = Frame::generate_stacktrace_from_stack(stack); + let mut stacktrace = Frame::generate_stacktrace_from_stack(stack, *tcx); // Filter out `requires_caller_location` frames. stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx)); let span = stacktrace.last().map(|f| f.span).unwrap_or(tcx.span); diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index c2f772d560752..3a887f8afaa57 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -635,7 +635,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { #[must_use] pub fn generate_stacktrace(&self) -> Vec> { - Frame::generate_stacktrace_from_stack(self.stack()) + Frame::generate_stacktrace_from_stack(self.stack(), *self.tcx) } pub fn adjust_nan(&self, f: F2, inputs: &[F1]) -> F2 diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index a55bea60cd6e2..6da6ed2ec757a 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -321,12 +321,15 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> { } #[must_use] - pub fn generate_stacktrace_from_stack(stack: &[Self]) -> Vec> { + pub fn generate_stacktrace_from_stack( + stack: &[Self], + tcx: TyCtxt<'tcx>, + ) -> Vec> { let mut frames = Vec::new(); // This deliberately does *not* honor `requires_caller_location` since it is used for much // more than just panics. for frame in stack.iter().rev() { - let span = match frame.loc { + let mut span = match frame.loc { Left(loc) => { // If the stacktrace passes through MIR-inlined source scopes, add them. let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc); @@ -340,6 +343,10 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> { } Right(span) => span, }; + if span.is_dummy() { + // Some statements lack a proper span; point at the function instead. + span = tcx.def_span(frame.instance.def_id()); + } frames.push(FrameInfo { span, instance: frame.instance }); } trace!("generate stacktrace: {:#?}", frames); diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs index afbb0cef9f956..d35e2c61f1e19 100644 --- a/compiler/rustc_data_structures/src/sync/vec.rs +++ b/compiler/rustc_data_structures/src/sync/vec.rs @@ -46,20 +46,17 @@ impl AppendOnlyVec { } pub fn iter_enumerated(&self) -> impl Iterator { - (0..) - .map(|i| (i, self.get(i))) - .take_while(|(_, o)| o.is_some()) - .filter_map(|(i, o)| Some((i, o?))) + (0..).map_while(|i| Some((i, self.get(i)?))) } pub fn iter(&self) -> impl Iterator { - (0..).map(|i| self.get(i)).take_while(|o| o.is_some()).flatten() + (0..).map_while(|i| self.get(i)) } } impl AppendOnlyVec { pub fn contains(&self, val: T) -> bool { - self.iter_enumerated().any(|(_, v)| v == val) + self.iter().any(|v| v == val) } } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index c10e7f3bfb8b9..f7ecfb6cd09cb 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -2,8 +2,8 @@ use std::cell::OnceCell; use std::ops::ControlFlow; use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::graph; use rustc_data_structures::graph::vec_graph::VecGraph; -use rustc_data_structures::graph::{self}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 22636959f0db5..3f511fd65a416 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -24,12 +24,11 @@ use rustc_ast_pretty::pprust::expr_to_string; use rustc_attr_parsing::AttributeParser; use rustc_errors::{Applicability, LintDiagnostic, msg}; use rustc_feature::GateIssue; -use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, DocAttribute}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::FnKind as HirFnKind; -use rustc_hir::{Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr}; +use rustc_hir::{self as hir, Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr}; use rustc_middle::bug; use rustc_middle::lint::LevelAndSource; use rustc_middle::ty::layout::LayoutOf; @@ -44,9 +43,9 @@ use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym}; use rustc_target::asm::InlineAsmArch; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; +use rustc_trait_selection::traits; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; -use rustc_trait_selection::traits::{self}; use crate::errors::BuiltinEllipsisInclusiveRangePatterns; use crate::lints::{ @@ -59,7 +58,7 @@ use crate::lints::{ BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, - BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel, + BuiltinUnusedDocCommentSub, BuiltinWhileTrue, EqInternalMethodImplemented, InvalidAsmLabel, }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext}; declare_lint! { @@ -3184,3 +3183,62 @@ impl EarlyLintPass for SpecialModuleName { } } } + +declare_lint! { + /// The `internal_eq_trait_method_impls` lint detects manual + /// implementations of `Eq::assert_receiver_is_total_eq`. + /// + /// ### Example + /// + /// ```rust + /// #[derive(PartialEq)] + /// pub struct Foo; + /// + /// impl Eq for Foo { + /// fn assert_receiver_is_total_eq(&self) {} + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// This method existed so that `#[derive(Eq)]` could check that all + /// fields of a type implement `Eq`. Other users were never supposed + /// to implement it and it was hidden from documentation. + /// + /// Unfortunately, it was not explicitly marked as unstable and some + /// people have now mistakenly assumed they had to implement this method. + /// + /// As the method is never called by the standard library, you can safely + /// remove any implementations of the method and just write `impl Eq for Foo {}`. + /// + /// This is a [future-incompatible] lint to transition this to a hard + /// error in the future. See [issue #152336] for more details. + /// + /// [issue #152336]: https://github.com/rust-lang/rust/issues/152336 + pub INTERNAL_EQ_TRAIT_METHOD_IMPLS, + Warn, + "manual implementation of the internal `Eq::assert_receiver_is_total_eq` method", + @future_incompatible = FutureIncompatibleInfo { + reason: fcw!(FutureReleaseError #152336), + report_in_deps: false, + }; +} + +declare_lint_pass!(InternalEqTraitMethodImpls => [INTERNAL_EQ_TRAIT_METHOD_IMPLS]); + +impl<'tcx> LateLintPass<'tcx> for InternalEqTraitMethodImpls { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx rustc_hir::ImplItem<'tcx>) { + if let ImplItemImplKind::Trait { defaultness: _, trait_item_def_id: Ok(trait_item_def_id) } = + item.impl_kind + && cx.tcx.is_diagnostic_item(sym::assert_receiver_is_total_eq, trait_item_def_id) + { + cx.emit_span_lint( + INTERNAL_EQ_TRAIT_METHOD_IMPLS, + item.span, + EqInternalMethodImplemented, + ); + } + } +} diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs similarity index 75% rename from compiler/rustc_lint/src/pass_by_value.rs rename to compiler/rustc_lint/src/disallowed_pass_by_ref.rs index 5a4eb29433815..2a572a5a76bdb 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs @@ -3,34 +3,34 @@ use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind, f use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use crate::lints::PassByValueDiag; +use crate::lints::DisallowedPassByRefDiag; use crate::{LateContext, LateLintPass, LintContext}; declare_tool_lint! { - /// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to - /// always be passed by value. This is usually used for types that are thin wrappers around - /// references, so there is no benefit to an extra layer of indirection. (Example: `Ty` which - /// is a reference to an `Interned`) - pub rustc::PASS_BY_VALUE, + /// The `disallowed_pass_by_ref` lint detects if types marked with `#[rustc_pass_by_value]` are + /// passed by reference. Types with this marker are usually thin wrappers around references, so + /// there is no benefit to an extra layer of indirection. (Example: `Ty` which is a reference + /// to an `Interned`) + pub rustc::DISALLOWED_PASS_BY_REF, Warn, "pass by reference of a type flagged as `#[rustc_pass_by_value]`", report_in_external_macro: true } -declare_lint_pass!(PassByValue => [PASS_BY_VALUE]); +declare_lint_pass!(DisallowedPassByRef => [DISALLOWED_PASS_BY_REF]); -impl<'tcx> LateLintPass<'tcx> for PassByValue { +impl<'tcx> LateLintPass<'tcx> for DisallowedPassByRef { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) { match &ty.kind { TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => { if cx.tcx.trait_impl_of_assoc(ty.hir_id.owner.to_def_id()).is_some() { return; } - if let Some(t) = path_for_pass_by_value(cx, inner_ty) { + if let Some(t) = path_for_rustc_pass_by_value(cx, inner_ty) { cx.emit_span_lint( - PASS_BY_VALUE, + DISALLOWED_PASS_BY_REF, ty.span, - PassByValueDiag { ty: t, suggestion: ty.span }, + DisallowedPassByRefDiag { ty: t, suggestion: ty.span }, ); } } @@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue { } } -fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { +fn path_for_rustc_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind { match path.res { Res::Def(_, def_id) if find_attr!(cx.tcx, def_id, RustcPassByValue(_)) => { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index cd0d8765dd933..34276eb76cf39 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -37,6 +37,7 @@ mod context; mod dangling; mod default_could_be_derived; mod deref_into_dyn_supertrait; +mod disallowed_pass_by_ref; mod drop_forget_useless; mod early; mod enum_intrinsics_non_enums; @@ -65,7 +66,6 @@ mod non_local_def; mod nonstandard_style; mod noop_method_call; mod opaque_hidden_inferred_bound; -mod pass_by_value; mod passes; mod precedence; mod ptr_nulls; @@ -88,6 +88,7 @@ use builtin::*; use dangling::*; use default_could_be_derived::DefaultCouldBeDerived; use deref_into_dyn_supertrait::*; +use disallowed_pass_by_ref::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; @@ -109,7 +110,6 @@ use non_local_def::*; use nonstandard_style::*; use noop_method_call::*; use opaque_hidden_inferred_bound::*; -use pass_by_value::*; use precedence::*; use ptr_nulls::*; use redundant_semicolon::*; @@ -250,6 +250,7 @@ late_lint_methods!( FunctionCastsAsInteger: FunctionCastsAsInteger, CheckTransmutes: CheckTransmutes, LifetimeSyntax: LifetimeSyntax, + InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, ] ] ); @@ -658,8 +659,8 @@ fn register_internals(store: &mut LintStore) { store.register_late_mod_pass(|_| Box::new(TypeIr)); store.register_lints(&BadOptAccess::lint_vec()); store.register_late_mod_pass(|_| Box::new(BadOptAccess)); - store.register_lints(&PassByValue::lint_vec()); - store.register_late_mod_pass(|_| Box::new(PassByValue)); + store.register_lints(&DisallowedPassByRef::lint_vec()); + store.register_late_mod_pass(|_| Box::new(DisallowedPassByRef)); store.register_lints(&SpanUseEqCtxt::lint_vec()); store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt)); store.register_lints(&SymbolInternStringLiteral::lint_vec()); @@ -677,7 +678,7 @@ fn register_internals(store: &mut LintStore) { LintId::of(POTENTIAL_QUERY_INSTABILITY), LintId::of(UNTRACKED_QUERY_INFORMATION), LintId::of(USAGE_OF_TY_TYKIND), - LintId::of(PASS_BY_VALUE), + LintId::of(DISALLOWED_PASS_BY_REF), LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), LintId::of(USAGE_OF_QUALIFIED_TY), LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT), diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 4b7e102e239ec..1d8f2d4e3442d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1807,10 +1807,10 @@ pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { pub end_span: Span, } -// pass_by_value.rs +// disallowed_pass_by_ref.rs #[derive(LintDiagnostic)] #[diag("passing `{$ty}` by reference")] -pub(crate) struct PassByValueDiag { +pub(crate) struct DisallowedPassByRefDiag { pub ty: String, #[suggestion("try passing by value", code = "{ty}", applicability = "maybe-incorrect")] pub suggestion: Span, @@ -3932,3 +3932,8 @@ pub(crate) struct MalformedOnConstAttrLint { #[label("invalid option found here")] pub span: Span, } + +#[derive(LintDiagnostic)] +#[diag("`Eq::assert_receiver_is_total_eq` should never be implemented by hand")] +#[note("this method was used to add checks to the `Eq` derive macro")] +pub(crate) struct EqInternalMethodImplemented; diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs index 18a947dc1ee06..50471b40ecdea 100644 --- a/compiler/rustc_lint/src/map_unit_fn.rs +++ b/compiler/rustc_lint/src/map_unit_fn.rs @@ -1,5 +1,5 @@ use rustc_hir::{Expr, ExprKind, Stmt, StmtKind}; -use rustc_middle::ty::{self}; +use rustc_middle::ty; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 6ef9d4e9769ce..6052a16a7f117 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -1,7 +1,7 @@ use rustc_ast::Mutability; use rustc_hir::{Expr, ExprKind, UnOp}; +use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout}; -use rustc_middle::ty::{self}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; diff --git a/compiler/rustc_lint/src/transmute.rs b/compiler/rustc_lint/src/transmute.rs index b55d209130b02..570f069eeee94 100644 --- a/compiler/rustc_lint/src/transmute.rs +++ b/compiler/rustc_lint/src/transmute.rs @@ -1,8 +1,8 @@ use rustc_ast::LitKind; use rustc_errors::Applicability; +use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{self as hir}; use rustc_macros::Diagnostic; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint, impl_lint_pass}; diff --git a/compiler/rustc_lint/src/unqualified_local_imports.rs b/compiler/rustc_lint/src/unqualified_local_imports.rs index 0076cae3cff3c..d3aff05123763 100644 --- a/compiler/rustc_lint/src/unqualified_local_imports.rs +++ b/compiler/rustc_lint/src/unqualified_local_imports.rs @@ -1,4 +1,4 @@ -use rustc_hir::{self as hir}; +use rustc_hir as hir; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::kw; diff --git a/compiler/rustc_lint/src/unused/must_use.rs b/compiler/rustc_lint/src/unused/must_use.rs index f2d621c2ad5ed..f37cf4c8dc8c0 100644 --- a/compiler/rustc_lint/src/unused/must_use.rs +++ b/compiler/rustc_lint/src/unused/must_use.rs @@ -151,7 +151,6 @@ pub fn is_ty_must_use<'tcx>( cx: &LateContext<'tcx>, ty: Ty<'tcx>, expr: &hir::Expr<'_>, - span: Span, simplify_uninhabited: bool, ) -> IsTyMustUse { if ty.is_unit() { @@ -165,12 +164,12 @@ pub fn is_ty_must_use<'tcx>( match *ty.kind() { _ if is_uninhabited(ty) => IsTyMustUse::Trivial, ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => { - is_ty_must_use(cx, boxed, expr, span, simplify_uninhabited) + is_ty_must_use(cx, boxed, expr, simplify_uninhabited) .map(|inner| MustUsePath::Boxed(Box::new(inner))) } ty::Adt(def, args) if cx.tcx.is_lang_item(def.did(), LangItem::Pin) => { let pinned_ty = args.type_at(0); - is_ty_must_use(cx, pinned_ty, expr, span, simplify_uninhabited) + is_ty_must_use(cx, pinned_ty, expr, simplify_uninhabited) .map(|inner| MustUsePath::Pinned(Box::new(inner))) } // Consider `Result` (e.g. `Result<(), !>`) equivalent to `T`. @@ -180,7 +179,7 @@ pub fn is_ty_must_use<'tcx>( && is_uninhabited(args.type_at(1)) => { let ok_ty = args.type_at(0); - is_ty_must_use(cx, ok_ty, expr, span, simplify_uninhabited) + is_ty_must_use(cx, ok_ty, expr, simplify_uninhabited) .map(|path| MustUsePath::Result(Box::new(path))) } // Consider `ControlFlow` (e.g. `ControlFlow`) equivalent to `T`. @@ -190,7 +189,7 @@ pub fn is_ty_must_use<'tcx>( && is_uninhabited(args.type_at(0)) => { let continue_ty = args.type_at(1); - is_ty_must_use(cx, continue_ty, expr, span, simplify_uninhabited) + is_ty_must_use(cx, continue_ty, expr, simplify_uninhabited) .map(|path| MustUsePath::ControlFlow(Box::new(path))) } // Suppress warnings on `Result<(), Uninhabited>` (e.g. `Result<(), !>`). @@ -210,7 +209,7 @@ pub fn is_ty_must_use<'tcx>( IsTyMustUse::Trivial } ty::Adt(def, _) => { - is_def_must_use(cx, def.did(), span).map_or(IsTyMustUse::No, IsTyMustUse::Yes) + is_def_must_use(cx, def.did(), expr.span).map_or(IsTyMustUse::No, IsTyMustUse::Yes) } ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => { elaborate(cx.tcx, cx.tcx.explicit_item_self_bounds(def).iter_identity_copied()) @@ -223,7 +222,7 @@ pub fn is_ty_must_use<'tcx>( { let def_id = poly_trait_predicate.trait_ref.def_id; - is_def_must_use(cx, def_id, span) + is_def_must_use(cx, def_id, expr.span) } else { None } @@ -236,7 +235,7 @@ pub fn is_ty_must_use<'tcx>( .find_map(|predicate| { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() { let def_id = trait_ref.def_id; - is_def_must_use(cx, def_id, span) + is_def_must_use(cx, def_id, expr.span) .map(|inner| MustUsePath::TraitObject(Box::new(inner))) } else { None @@ -260,9 +259,7 @@ pub fn is_ty_must_use<'tcx>( .zip(elem_exprs) .enumerate() .filter_map(|(i, (ty, expr))| { - is_ty_must_use(cx, ty, expr, expr.span, simplify_uninhabited) - .yes() - .map(|path| (i, path)) + is_ty_must_use(cx, ty, expr, simplify_uninhabited).yes().map(|path| (i, path)) }) .collect::>(); @@ -276,21 +273,23 @@ pub fn is_ty_must_use<'tcx>( // If the array is empty we don't lint, to avoid false positives Some(0) | None => IsTyMustUse::No, // If the array is definitely non-empty, we can do `#[must_use]` checking. - Some(len) => is_ty_must_use(cx, ty, expr, span, simplify_uninhabited) + Some(len) => is_ty_must_use(cx, ty, expr, simplify_uninhabited) .map(|inner| MustUsePath::Array(Box::new(inner), len)), }, - ty::Closure(..) | ty::CoroutineClosure(..) => IsTyMustUse::Yes(MustUsePath::Closure(span)), + ty::Closure(..) | ty::CoroutineClosure(..) => { + IsTyMustUse::Yes(MustUsePath::Closure(expr.span)) + } ty::Coroutine(def_id, ..) => { // async fn should be treated as "implementor of `Future`" if cx.tcx.coroutine_is_async(def_id) && let Some(def_id) = cx.tcx.lang_items().future_trait() { IsTyMustUse::Yes(MustUsePath::Opaque(Box::new( - is_def_must_use(cx, def_id, span) + is_def_must_use(cx, def_id, expr.span) .expect("future trait is marked as `#[must_use]`"), ))) } else { - IsTyMustUse::Yes(MustUsePath::Coroutine(span)) + IsTyMustUse::Yes(MustUsePath::Coroutine(expr.span)) } } _ => IsTyMustUse::No, @@ -339,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { let ty = cx.typeck_results().expr_ty(expr); - let must_use_result = is_ty_must_use(cx, ty, expr, expr.span, false); + let must_use_result = is_ty_must_use(cx, ty, expr, false); let type_lint_emitted_or_trivial = match must_use_result { IsTyMustUse::Yes(path) => { emit_must_use_untranslated(cx, &path, "", "", 1, false, expr_is_from_block); diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index ebfcb50e9cde5..cd9c53134ae20 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -293,12 +293,10 @@ fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) { // Generate a function to check whether we should cache the query to disk, for some key. if let Some(CacheOnDiskIf { block, .. }) = modifiers.cache_on_disk_if.as_ref() { - // `pass_by_value`: some keys are marked with `rustc_pass_by_value`, but we take keys by - // reference here. - // FIXME: `pass_by_value` is badly named; `allow(rustc::pass_by_value)` actually means - // "allow pass by reference of `rustc_pass_by_value` types". + // `disallowed_pass_by_ref` is needed because some keys are `rustc_pass_by_value`. streams.cache_on_disk_if_fns_stream.extend(quote! { - #[allow(unused_variables, rustc::pass_by_value)] + #[cfg_attr(not(bootstrap), allow(unused_variables, rustc::disallowed_pass_by_ref))] + #[cfg_attr(bootstrap, allow(unused_variables, rustc::pass_by_value))] #[inline] pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: &#key_ty) -> bool #block diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index c926604a41952..0ddcdac817b80 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -9,6 +9,7 @@ use rustc_span::def_id::{CrateNum, LocalDefId}; use rustc_span::{ExpnHash, ExpnId}; use crate::mir; +use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex}; use crate::ty::{Ty, TyCtxt}; macro_rules! declare_hooks { @@ -107,6 +108,13 @@ declare_hooks! { /// /// Creates the MIR for a given `DefId`, including unreachable code. hook build_mir_inner_impl(def: LocalDefId) -> mir::Body<'tcx>; + + hook try_mark_green(dep_node: &crate::dep_graph::DepNode) -> bool; + + hook encode_all_query_results( + encoder: &mut CacheEncoder<'_, 'tcx>, + query_result_index: &mut EncodedDepNodeIndex + ) -> (); } #[cold] diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index e874e7e22b5c9..8db48fc2f9956 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -1,6 +1,6 @@ use std::collections::hash_map::Entry; -use std::mem; use std::sync::Arc; +use std::{fmt, mem}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; @@ -261,7 +261,7 @@ impl OnDiskCache { tcx.sess.time("encode_query_results", || { let enc = &mut encoder; let qri = &mut query_result_index; - (tcx.query_system.fns.encode_query_results)(tcx, enc, qri); + tcx.encode_all_query_results(enc, qri); }); // Encode side effects. @@ -508,7 +508,7 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> { // tag matches and the correct amount of bytes was read. fn decode_tagged(decoder: &mut D, expected_tag: T) -> V where - T: Decodable + Eq + std::fmt::Debug, + T: Decodable + Eq + fmt::Debug, V: Decodable, D: Decoder, { @@ -829,6 +829,13 @@ pub struct CacheEncoder<'a, 'tcx> { symbol_index_table: FxHashMap, } +impl<'a, 'tcx> fmt::Debug for CacheEncoder<'a, 'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Add more details here if/when necessary. + f.write_str("CacheEncoder") + } +} + impl<'a, 'tcx> CacheEncoder<'a, 'tcx> { #[inline] fn source_file_index(&mut self, source_file: Arc) -> SourceFileIndex { diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 9141f49bd45de..c2d524d200dee 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -11,11 +11,10 @@ use rustc_macros::HashStable; use rustc_span::{ErrorGuaranteed, Span}; pub use sealed::IntoQueryParam; -use crate::dep_graph; use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables}; -use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; +use crate::query::on_disk_cache::OnDiskCache; use crate::query::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra}; use crate::query::{QueryCache, QueryInfo, QueryJob}; use crate::ty::TyCtxt; @@ -216,17 +215,6 @@ impl<'tcx, C: QueryCache> QueryVTable<'tcx, C> { } } -pub struct QuerySystemFns { - pub local_providers: Providers, - pub extern_providers: ExternProviders, - pub encode_query_results: for<'tcx> fn( - tcx: TyCtxt<'tcx>, - encoder: &mut CacheEncoder<'_, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex, - ), - pub try_mark_green: for<'tcx> fn(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool, -} - pub struct QuerySystem<'tcx> { pub arenas: WorkerLocal>, pub query_vtables: QueryVTables<'tcx>, @@ -237,7 +225,8 @@ pub struct QuerySystem<'tcx> { /// This is `None` if we are not incremental compilation mode pub on_disk_cache: Option, - pub fns: QuerySystemFns, + pub local_providers: Providers, + pub extern_providers: ExternProviders, pub jobs: AtomicU64, } @@ -327,10 +316,6 @@ impl<'tcx> TyCtxt<'tcx> { pub fn at(self, span: Span) -> TyCtxtAt<'tcx> { TyCtxtAt { tcx: self, span } } - - pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool { - (self.query_system.fns.try_mark_green)(self, dep_node) - } } macro_rules! query_helper_param_ty { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 4856df3a6222a..5f78f414a742a 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -21,9 +21,8 @@ use crate::arena::ArenaAllocatable; use crate::infer::canonical::{CanonicalVarKind, CanonicalVarKinds}; use crate::mir::interpret::{AllocId, ConstAllocation, CtfeProvenance}; use crate::mir::mono::MonoItem; -use crate::mir::{self}; -use crate::traits; use crate::ty::{self, AdtDef, GenericArgsRef, Ty, TyCtxt}; +use crate::{mir, traits}; /// The shorthand encoding uses an enum's variant index `usize` /// and is offset by this value so it never matches a real variant. diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index a4aeaacbf05db..317efbd777b1d 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -5,10 +5,10 @@ use std::fmt; use rustc_abi::ExternAbi; use rustc_data_structures::debug_assert_matches; use rustc_errors::ErrorGuaranteed; +use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{self as hir}; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, search_graph}; diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 6acf0aff800fd..935e5da68e823 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -3,9 +3,7 @@ use std::fmt; use rustc_data_structures::intern::Interned; use rustc_macros::HashStable; use rustc_type_ir::ir_print::IrPrint; -use rustc_type_ir::{ - FlagComputation, Flags, {self as ir}, -}; +use rustc_type_ir::{self as ir, FlagComputation, Flags}; use super::TyCtxt; use crate::ty; diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index ed5f0b2e8f759..ad6c1f7dce5b8 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -1,7 +1,7 @@ //! See docs in builder/expr/mod.rs use rustc_abi::Size; -use rustc_ast::{self as ast}; +use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, Scalar}; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index dd8491b00cee9..0960859fb2a4f 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -302,7 +302,8 @@ impl<'a, 'tcx> ValueSet<'a, 'tcx> { /// Insert a `(Value, Ty)` pair to be deduplicated. /// Returns `true` as second tuple field if this value did not exist previously. - #[allow(rustc::pass_by_value)] // closures take `&VnIndex` + #[cfg_attr(not(bootstrap), allow(rustc::disallowed_pass_by_ref))] // closures take `&VnIndex` + #[cfg_attr(bootstrap, allow(rustc::pass_by_value))] fn insert(&mut self, ty: Ty<'tcx>, value: Value<'a, 'tcx>) -> (VnIndex, bool) { debug_assert!(match value { Value::Opaque(_) | Value::Address { .. } => false, 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 667a702e40565..03c459c312b67 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 @@ -23,8 +23,8 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::{Analysis, MaybeReachable, ResultsCursor}; +use rustc_session::lint; use rustc_session::lint::builtin::TAIL_EXPR_DROP_ORDER; -use rustc_session::lint::{self}; use rustc_span::{DUMMY_SP, Span, Symbol}; use tracing::debug; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 52dcade91aeaf..44e8f13dd2364 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1628,8 +1628,7 @@ impl<'a> Parser<'a> { let first_expr = self.parse_expr()?; if self.eat(exp!(Semi)) { // Repeating array syntax: `[ 0; 512 ]` - let count = - self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?; + let count = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?; self.expect(close)?; ExprKind::Repeat(first_expr, count) } else if self.eat(exp!(Comma)) { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 69610d062919d..5554488b66c4f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2,11 +2,11 @@ use std::fmt::Write; use std::mem; use ast::token::IdentIsRaw; +use rustc_ast as ast; use rustc_ast::ast::*; use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::util::case::Case; -use rustc_ast::{self as ast}; use rustc_ast_pretty::pprust; use rustc_errors::codes::*; use rustc_errors::{Applicability, PResult, StashKey, msg, struct_span_code_err}; @@ -1587,9 +1587,7 @@ impl<'a> Parser<'a> { let rhs = match (self.eat(exp!(Eq)), const_arg) { (true, true) => ConstItemRhsKind::TypeConst { - rhs: Some( - self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?, - ), + rhs: Some(self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?), }, (true, false) => ConstItemRhsKind::Body { rhs: Some(self.parse_expr()?) }, (false, true) => ConstItemRhsKind::TypeConst { rhs: None }, diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 9196d8d156d8e..e514a08c8fb3a 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -915,28 +915,7 @@ impl<'a> Parser<'a> { }); } - let mgca_disambiguation = self.mgca_direct_lit_hack(&expr); - Ok((expr, mgca_disambiguation)) - } - - /// Under `min_generic_const_args` we still allow *some* anon consts to be written without - /// a `const` block as it makes things quite a lot nicer. This function is useful for contexts - /// where we would like to use `MgcaDisambiguation::Direct` but need to fudge it to be `AnonConst` - /// in the presence of literals. - // - /// FIXME(min_generic_const_args): In the long term it would be nice to have a way to directly - /// represent literals in `hir::ConstArgKind` so that we can remove this special case by not - /// needing an anon const. - pub fn mgca_direct_lit_hack(&self, expr: &Expr) -> MgcaDisambiguation { - match &expr.kind { - ast::ExprKind::Lit(_) => MgcaDisambiguation::AnonConst, - ast::ExprKind::Unary(ast::UnOp::Neg, expr) - if matches!(expr.kind, ast::ExprKind::Lit(_)) => - { - MgcaDisambiguation::AnonConst - } - _ => MgcaDisambiguation::Direct, - } + Ok((expr, MgcaDisambiguation::Direct)) } /// Parse a generic argument in a path segment. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 6ff165eb22b71..40335ef1b1bc7 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -658,8 +658,7 @@ impl<'a> Parser<'a> { }; let ty = if self.eat(exp!(Semi)) { - let mut length = - self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?; + let mut length = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?; if let Err(e) = self.expect(exp!(CloseBracket)) { // Try to recover from `X` when `X::` works diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 890c0b2ef92c7..afb41f69b5ebb 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -12,7 +12,7 @@ use rustc_data_structures::sync::AtomicU64; use rustc_middle::dep_graph; use rustc_middle::queries::{self, ExternProviders, Providers}; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; -use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; +use rustc_middle::query::plumbing::{QuerySystem, QueryVTable}; use rustc_middle::query::{AsLocalKey, QueryCache, QueryMode}; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -59,12 +59,8 @@ pub fn query_system<'tcx>( arenas: Default::default(), query_vtables: make_query_vtables(incremental), on_disk_cache, - fns: QuerySystemFns { - local_providers, - extern_providers, - encode_query_results: encode_all_query_results, - try_mark_green, - }, + local_providers, + extern_providers, jobs: AtomicU64::new(1), } } @@ -74,4 +70,6 @@ rustc_middle::rustc_with_all_queries! { define_queries! } pub fn provide(providers: &mut rustc_middle::util::Providers) { providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings; providers.hooks.query_key_hash_verify_all = query_key_hash_verify_all; + providers.hooks.encode_all_query_results = encode_all_query_results; + providers.hooks.try_mark_green = try_mark_green; } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 7b5fd76c31958..275fe5b63d8b0 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -226,13 +226,13 @@ macro_rules! hash_result { macro_rules! call_provider { ([][$tcx:expr, $name:ident, $key:expr]) => {{ - ($tcx.query_system.fns.local_providers.$name)($tcx, $key) + ($tcx.query_system.local_providers.$name)($tcx, $key) }}; ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{ if let Some(key) = $key.as_local_key() { - ($tcx.query_system.fns.local_providers.$name)($tcx, key) + ($tcx.query_system.local_providers.$name)($tcx, key) } else { - ($tcx.query_system.fns.extern_providers.$name)($tcx, $key) + ($tcx.query_system.extern_providers.$name)($tcx, $key) } }}; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 45cbc0b3c828d..b88227264537f 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -25,7 +25,7 @@ use std::cell::Ref; use std::collections::BTreeSet; -use std::fmt::{self}; +use std::fmt; use std::ops::ControlFlow; use std::sync::Arc; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3d40b7317459b..422a15b060cc0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -432,6 +432,7 @@ symbols! { assert, assert_eq, assert_eq_macro, + assert_fields_are_eq, assert_inhabited, assert_macro, assert_mem_uninitialized_valid, @@ -1089,6 +1090,7 @@ symbols! { integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below integral, internal, + internal_eq_trait_method_impls, internal_features, into_async_iter_into_iter, into_future, diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs index 1d83799d7dab1..683b615eec83b 100644 --- a/compiler/rustc_target/src/callconv/powerpc64.rs +++ b/compiler/rustc_target/src/callconv/powerpc64.rs @@ -5,7 +5,7 @@ use rustc_abi::{Endian, HasDataLayout, TyAbiInterface}; use crate::callconv::{Align, ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::spec::{Abi, HasTargetSpec, Os}; +use crate::spec::{HasTargetSpec, Os}; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { @@ -106,9 +106,9 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - let abi = if cx.target_spec().options.abi == Abi::ElfV2 { + let abi = if cx.target_spec().options.llvm_abiname == "elfv2" { ELFv2 - } else if cx.target_spec().options.abi == Abi::ElfV1 { + } else if cx.target_spec().options.llvm_abiname == "elfv1" { ELFv1 } else if cx.target_spec().os == Os::Aix { AIX 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 165e563ebad50..22342a956710f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -53,11 +53,11 @@ use std::{cmp, fmt, iter}; use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart, pluralize}; +use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; -use rustc_hir::{self as hir}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::extension; use rustc_middle::bug; diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 8705a9c3d2679..9a6bfa823f2a5 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -1,8 +1,7 @@ -use core::fmt; use core::iter::{FusedIterator, TrustedLen}; use core::mem::{self, ManuallyDrop, SizedTypeProperties}; use core::ptr::{self, NonNull}; -use core::slice::{self}; +use core::{fmt, slice}; use super::Vec; use crate::alloc::{Allocator, Global}; diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index af1bd53179739..4f67a2c04fefc 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -9,8 +9,7 @@ use core::num::NonZero; use core::ops::Deref; use core::panic::UnwindSafe; use core::ptr::{self, NonNull}; -use core::slice::{self}; -use core::{array, fmt}; +use core::{array, fmt, slice}; #[cfg(not(no_global_oom_handling))] use super::AsVecIntoIter; diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index 7c908841c90ec..de6ef3d803263 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -1,6 +1,6 @@ use core::clone::TrivialClone; use core::iter::TrustedLen; -use core::slice::{self}; +use core::slice; use super::{IntoIter, Vec}; use crate::alloc::Allocator; diff --git a/library/alloc/src/vec/spec_from_iter.rs b/library/alloc/src/vec/spec_from_iter.rs index e1f0b639bdfd6..ccbc2936fb4e8 100644 --- a/library/alloc/src/vec/spec_from_iter.rs +++ b/library/alloc/src/vec/spec_from_iter.rs @@ -1,5 +1,5 @@ use core::mem::ManuallyDrop; -use core::ptr::{self}; +use core::ptr; use super::{IntoIter, SpecExtend, SpecFromIterNested, Vec}; diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index 46611f611dc2c..3eb8ca44a9d14 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -1,5 +1,4 @@ -use core::ptr::{self}; -use core::slice::{self}; +use core::{ptr, slice}; use super::{Drain, Vec}; use crate::alloc::{Allocator, Global}; diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 78ea1f1113258..b3dc435dda176 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -336,16 +336,24 @@ pub macro PartialEq($item:item) { #[rustc_diagnostic_item = "Eq"] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] pub const trait Eq: [const] PartialEq + PointeeSized { - // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a - // type implements `Eq` itself. The current deriving infrastructure means doing this assertion - // without using a method on this trait is nearly impossible. + // This method was used solely by `#[derive(Eq)]` to assert that every component of a + // type implements `Eq` itself. // // This should never be implemented by hand. #[doc(hidden)] #[coverage(off)] #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "assert_receiver_is_total_eq"] + #[deprecated(since = "1.95.0", note = "implementation detail of `#[derive(Eq)]`")] fn assert_receiver_is_total_eq(&self) {} + + // FIXME (#152504): this method is used solely by `#[derive(Eq)]` to assert that + // every component of a type implements `Eq` itself. It will be removed again soon. + #[doc(hidden)] + #[coverage(off)] + #[unstable(feature = "derive_eq_internals", issue = "none")] + fn assert_fields_are_eq(&self) {} } /// Derive macro generating an impl of the trait [`Eq`]. diff --git a/library/coretests/tests/cmp.rs b/library/coretests/tests/cmp.rs index 55e35a4a7250e..0a14470060c3d 100644 --- a/library/coretests/tests/cmp.rs +++ b/library/coretests/tests/cmp.rs @@ -1,5 +1,5 @@ +use core::cmp; use core::cmp::Ordering::{self, *}; -use core::cmp::{self}; #[test] fn test_int_totalord() { diff --git a/library/coretests/tests/iter/adapters/array_chunks.rs b/library/coretests/tests/iter/adapters/array_chunks.rs index e6e279b14e626..480d3138bdb35 100644 --- a/library/coretests/tests/iter/adapters/array_chunks.rs +++ b/library/coretests/tests/iter/adapters/array_chunks.rs @@ -1,4 +1,4 @@ -use core::iter::{self}; +use core::iter; use super::*; diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index 74d99e0f1270e..2772222a05c9a 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -1,5 +1,5 @@ +use std::io; use std::io::prelude::Write; -use std::io::{self}; use std::time::Duration; use super::OutputFormatter; diff --git a/library/test/src/term.rs b/library/test/src/term.rs index d9880a776406d..1e4c7bc879cf7 100644 --- a/library/test/src/term.rs +++ b/library/test/src/term.rs @@ -12,8 +12,8 @@ #![deny(missing_docs)] +use std::io; use std::io::prelude::*; -use std::io::{self}; pub(crate) use terminfo::TerminfoTerminal; #[cfg(windows)] diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 6c35105225c01..d62fe1a1aa928 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -337,6 +337,7 @@ docker \ --env DEPLOY \ --env DEPLOY_ALT \ --env CI \ + --env GIT_DISCOVERY_ACROSS_FILESYSTEM=1 \ --env GITHUB_ACTIONS \ --env GITHUB_REF \ --env GITHUB_STEP_SUMMARY="/checkout/obj/${SUMMARY_FILE}" \ diff --git a/src/ci/scripts/free-disk-space-linux.sh b/src/ci/scripts/free-disk-space-linux.sh index ac3c9cfb28b87..ac06f3fad88c0 100755 --- a/src/ci/scripts/free-disk-space-linux.sh +++ b/src/ci/scripts/free-disk-space-linux.sh @@ -4,6 +4,11 @@ set -euo pipefail # Free disk space on Linux GitHub action runners # Script inspired by https://github.com/jlumbroso/free-disk-space + +# we need ~50GB of space +space_target_kb=$((50 * 1024 * 1024)) + + isX86() { local arch arch=$(uname -m) @@ -247,12 +252,87 @@ cleanSwap() { free -h } +sufficientSpaceEarlyExit() { + local available_space_kb=$(df -k . --output=avail | tail -n 1) + + if [ "$available_space_kb" -ge "$space_target_kb" ]; then + echo "Sufficient disk space available (${available_space_kb}KB >= ${space_target_kb}KB). Skipping cleanup." + exit 0 + fi +} + +# Try to find a different drive to put our data on so we don't need to run cleanup. +# The availability of the disks we're probing isn't guaranteed, +# so this is opportunistic. +checkAlternative() { + local gha_alt_disk="/mnt" + + local available_space_kb=$(df -k "$gha_alt_disk" --output=avail | tail -n 1) + + # mount options that trade durability for performance + # ignore-tidy-linelength + local mntopts="defaults,discard,journal_async_commit,barrier=0,noauto_da_alloc,lazytime,data=writeback" + + # GHA has a 2nd disk mounted at /mnt that is almost empty. + # Check if it's a valid mountpoint and it has enough available space. + if mountpoint "$gha_alt_disk" && [ "$available_space_kb" -ge "$space_target_kb" ]; then + local blkdev=$(df -k "$gha_alt_disk" --output=source | tail -n 1) + echo "Sufficient space available on $blkdev mounted at $gha_alt_disk" + # see cleanSwap(), swapfile may be mounted under /mnt + sudo swapoff -a || true + + # unmount from original location + sudo umount "$gha_alt_disk" + + # remount under the obj dir which is used by docker scripts to write most + # of our build output. And apply optimized mount options while we're at it. + mkdir ./obj + if ! sudo mount $blkdev ./obj -o $mntopts; then + sudo dmesg | tail -n 20 # kernel log should have more details for mount failures + echo "::warning::Failed to remount $blkdev to ./obj with options: $mntopts" + return + fi + + # ensure current user can access everything. + # later scripts assume they have recursive access to obj + sudo chown -R "$USER":"$USER" ./obj + + # Exit from this script to avoid wasting time removing disk space, + # as we already have enough disk space in the alternative drive. + exit 0 + fi + + # ephemeral NVMe drives on AWS + for dev in /dev/nvme*n1; do + # check that it's a blockdev, not mounted and doesn't have partitions + if [ -b "$dev" ] && [ "$(mount | grep "$dev" | wc -l)" -eq 0 ] && [ "$(lsblk -no PARTTYPE "$dev" | grep . | wc -l)" -eq 0 ]; then + echo "Found unused block device $dev, creating filesystem" + if ! sudo mkfs.ext4 -E lazy_itable_init=1,lazy_journal_init=1 "$dev" ; then + sudo dmesg | tail -n 5 # kernel log should have more details for mkfs failures + echo "Failed to create ext4 filesystem on $dev" + continue + fi + mkdir ./obj + sudo mount "$dev" ./obj -o $mntopts + sudo chown -R "$USER":"$USER" ./obj + + exit 0 + fi + done +} + + + # Display initial disk space stats AVAILABLE_INITIAL=$(getAvailableSpace) printDF "BEFORE CLEAN-UP:" echo "" + +sufficientSpaceEarlyExit +checkAlternative + execAndMeasureSpaceChange cleanPackages "Unused packages" execAndMeasureSpaceChange cleanDocker "Docker images" execAndMeasureSpaceChange cleanSwap "Swap storage" diff --git a/src/doc/reference b/src/doc/reference index 442cbef910566..50a1075e879be 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 442cbef9105662887d5eae2882ca551f3726bf28 +Subproject commit 50a1075e879be75aeec436252c84eef0fad489f4 diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 30dacde94cf03..2070a24f60c81 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -459,15 +459,15 @@ fn generate_item_def_id_path( let shortty = ItemType::from_def_id(def_id, tcx); let module_fqp = to_module_fqp(shortty, &fqp); - let mut is_absolute = false; - let url_parts = url_parts(cx.cache(), def_id, module_fqp, &cx.current, &mut is_absolute)?; - let mut url_parts = make_href(root_path, shortty, url_parts, &fqp, is_absolute); + let (parts, is_absolute) = url_parts(cx.cache(), def_id, module_fqp, &cx.current)?; + let mut url = make_href(root_path, shortty, parts, &fqp, is_absolute); + if def_id != original_def_id { let kind = ItemType::from_def_id(original_def_id, tcx); - url_parts = format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id)) + url = format!("{url}#{kind}.{}", tcx.item_name(original_def_id)) }; - Ok(HrefInfo { url: url_parts, kind: shortty, rust_path: fqp }) + Ok(HrefInfo { url, kind: shortty, rust_path: fqp }) } /// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block. @@ -511,16 +511,14 @@ fn url_parts( def_id: DefId, module_fqp: &[Symbol], relative_to: &[Symbol], - is_absolute: &mut bool, -) -> Result { +) -> Result<(UrlPartsBuilder, bool), HrefError> { match cache.extern_locations[&def_id.krate] { - ExternalLocation::Remote { ref url, is_absolute: abs } => { - *is_absolute = abs; - let mut builder = remote_url_prefix(url, abs, relative_to.len()); + ExternalLocation::Remote { ref url, is_absolute } => { + let mut builder = remote_url_prefix(url, is_absolute, relative_to.len()); builder.extend(module_fqp.iter().copied()); - Ok(builder) + Ok((builder, is_absolute)) } - ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to)), + ExternalLocation::Local => Ok((href_relative_parts(module_fqp, relative_to), false)), ExternalLocation::Unknown => Err(HrefError::DocumentationNotBuilt), } } @@ -596,13 +594,17 @@ pub(crate) fn href_with_root_path( } } - let mut is_absolute = false; - let (fqp, shortty, url_parts) = match cache.paths.get(&did) { - Some(&(ref fqp, shortty)) => (fqp, shortty, { - let module_fqp = to_module_fqp(shortty, fqp.as_slice()); - debug!(?fqp, ?shortty, ?module_fqp); - href_relative_parts(module_fqp, relative_to) - }), + let (fqp, shortty, url_parts, is_absolute) = match cache.paths.get(&did) { + Some(&(ref fqp, shortty)) => ( + fqp, + shortty, + { + let module_fqp = to_module_fqp(shortty, fqp.as_slice()); + debug!(?fqp, ?shortty, ?module_fqp); + href_relative_parts(module_fqp, relative_to) + }, + false, + ), None => { // Associated items are handled differently with "jump to def". The anchor is generated // directly here whereas for intra-doc links, we have some extra computation being @@ -610,7 +612,8 @@ pub(crate) fn href_with_root_path( let def_id_to_get = if root_path.is_some() { original_did } else { did }; if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&def_id_to_get) { let module_fqp = to_module_fqp(shortty, fqp); - (fqp, shortty, url_parts(cache, did, module_fqp, relative_to, &mut is_absolute)?) + let (parts, is_absolute) = url_parts(cache, did, module_fqp, relative_to)?; + (fqp, shortty, parts, is_absolute) } else if matches!(def_kind, DefKind::Macro(_)) { return generate_macro_def_id_path(did, cx, root_path); } else if did.is_local() { diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index fb1f0271c2ad7..5d5b8d5df685b 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -3,9 +3,8 @@ use std::fmt; use askama::Template; use rustc_abi::{Primitive, TagEncoding, Variants}; use rustc_hir::def_id::DefId; -use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{self}; +use rustc_middle::{span_bug, ty}; use rustc_span::symbol::Symbol; use crate::html::render::Context; diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index 1b3c96d82b410..cc78dec4eafa3 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -5,8 +5,8 @@ use std::path::PathBuf; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::DiagCtxtHandle; +use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir}; use rustc_macros::{Decodable, Encodable}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt}; diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs index f7d7df267967b..a8ea43cf73e32 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs @@ -5,7 +5,7 @@ use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_middle::ty::{self}; +use rustc_middle::ty; use super::ITER_OUT_OF_BOUNDS; diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs b/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs index 8ba0f835d3ddc..d2906b2776f8c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs @@ -8,7 +8,7 @@ use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{BinOpKind, Body, Expr, ExprKind, HirId, QPath}; use rustc_lint::LateContext; -use rustc_middle::ty::{self}; +use rustc_middle::ty; use rustc_span::source_map::Spanned; use super::MANUAL_CONTAINS; diff --git a/src/tools/clippy/clippy_lints/src/types/linked_list.rs b/src/tools/clippy/clippy_lints/src/types/linked_list.rs index 96126d3d4320a..abd6138655d76 100644 --- a/src/tools/clippy/clippy_lints/src/types/linked_list.rs +++ b/src/tools/clippy/clippy_lints/src/types/linked_list.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::sym; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir}; +use rustc_hir as hir; use rustc_lint::LateContext; use super::LINKEDLIST; diff --git a/src/tools/clippy/clippy_lints/src/types/owned_cow.rs b/src/tools/clippy/clippy_lints/src/types/owned_cow.rs index e70348b481c8e..3a806cfef691e 100644 --- a/src/tools/clippy/clippy_lints/src/types/owned_cow.rs +++ b/src/tools/clippy/clippy_lints/src/types/owned_cow.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet_opt; use clippy_utils::sym; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir}; +use rustc_hir as hir; use rustc_lint::LateContext; use rustc_span::Span; diff --git a/src/tools/lld-wrapper/src/main.rs b/src/tools/lld-wrapper/src/main.rs index 2f756ae3022f6..299f0329b940e 100644 --- a/src/tools/lld-wrapper/src/main.rs +++ b/src/tools/lld-wrapper/src/main.rs @@ -12,10 +12,9 @@ //! On Windows it spawns a `..\rust-lld.exe` child process. use std::env::consts::EXE_SUFFIX; -use std::env::{self}; use std::fmt::Display; use std::path::{Path, PathBuf}; -use std::process; +use std::{env, process}; trait UnwrapOrExitWith { fn unwrap_or_exit_with(self, context: &str) -> T; diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 71ec9723de8e9..35217da37e5b5 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -257,7 +257,7 @@ pub fn report_result<'tcx>( // The "active" thread might actually be terminated, so we ignore it. let mut any_pruned = false; for (thread, stack) in ecx.machine.threads.all_blocked_stacks() { - let stacktrace = Frame::generate_stacktrace_from_stack(stack); + let stacktrace = Frame::generate_stacktrace_from_stack(stack, *ecx.tcx); let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine); any_pruned |= was_pruned; report_msg( @@ -633,7 +633,8 @@ impl<'tcx> MiriMachine<'tcx> { pub fn emit_diagnostic(&self, e: NonHaltingDiagnostic) { use NonHaltingDiagnostic::*; - let stacktrace = Frame::generate_stacktrace_from_stack(self.threads.active_thread_stack()); + let stacktrace = + Frame::generate_stacktrace_from_stack(self.threads.active_thread_stack(), self.tcx); let (stacktrace, _was_pruned) = prune_stacktrace(stacktrace, self); let (label, diag_level) = match &e { diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 24f6dd59a9c50..5baf4ce6f907f 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -32,7 +32,7 @@ pub use crate::{ }, }; use dashmap::{DashMap, mapref::entry::Entry}; -pub use query_group::{self}; +pub use query_group; use rustc_hash::{FxHashSet, FxHasher}; use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 3029bca1d51fe..ae8eef2bbb5d9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -7,7 +7,7 @@ use cfg::CfgExpr; use either::Either; use intern::{ Symbol, - sym::{self}, + sym, }; use itertools::Itertools; use mbe::{DelimiterKind, expect_fragment}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 1290874177ac4..a0945c3bdce66 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -40,7 +40,7 @@ use rustc_hash::FxHashSet; use rustc_type_ir::{ AliasTyKind, BoundVarIndexKind, ConstKind, DebruijnIndex, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, Interner, OutlivesPredicate, TermKind, - TyKind::{self}, + TyKind, TypeFoldable, TypeVisitableExt, Upcast, UpcastFrom, elaborate, inherent::{Clause as _, GenericArgs as _, IntoKind as _, Region as _, Ty as _}, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs index 547d3686e3909..483c90d1032e5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs @@ -8,7 +8,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::{self}, + utils, }; // Assist: promote_local_to_const diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs index ca897aeb3eed6..2bc9f3c34a5ba 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs @@ -1,7 +1,7 @@ //! Simple logger that logs either to stderr or to a file, using `tracing_subscriber` //! filter syntax and `tracing_appender` for non blocking output. -use std::io::{self}; +use std::io; use anyhow::Context; use tracing::level_filters::LevelFilter; diff --git a/tests/codegen-llvm/double_panic_wasm.rs b/tests/codegen-llvm/double_panic_wasm.rs new file mode 100644 index 0000000000000..1eafe60503809 --- /dev/null +++ b/tests/codegen-llvm/double_panic_wasm.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -C panic=unwind -Copt-level=0 +//@ needs-unwind +//@ only-wasm32 + +#![crate_type = "lib"] + +// Test that `panic_in_cleanup` is called on webassembly targets when a panic +// occurs in a destructor during unwinding. + +extern "Rust" { + fn may_panic(); +} + +struct PanicOnDrop; + +impl Drop for PanicOnDrop { + fn drop(&mut self) { + unsafe { may_panic() } + } +} + +// CHECK-LABEL: @double_panic +// CHECK: invoke void @may_panic() +// CHECK: invoke void @{{.+}}drop_in_place{{.+}} +// CHECK: unwind label %[[TERMINATE:.*]] +// +// CHECK: [[TERMINATE]]: +// CHECK: call void @{{.*panic_in_cleanup}} +// CHECK: unreachable +#[no_mangle] +pub fn double_panic() { + let _guard = PanicOnDrop; + unsafe { may_panic() } +} diff --git a/tests/codegen-llvm/terminating-catchpad.rs b/tests/codegen-llvm/terminating-catchpad.rs index a2ec19871d1fc..7c98ea94fdc13 100644 --- a/tests/codegen-llvm/terminating-catchpad.rs +++ b/tests/codegen-llvm/terminating-catchpad.rs @@ -9,6 +9,10 @@ // Ensure a catch-all generates: // - `catchpad ... [ptr null]` on Wasm (otherwise LLVM gets confused) // - `catchpad ... [ptr null, i32 64, ptr null]` on Windows (otherwise we catch SEH exceptions) +// +// Unlike on windows, on Wasm, we specifically do want to catch foreign +// exceptions. To catch only C++ exceptions we'd need to call +// @llvm.wasm.get.exception and @llvm.wasm.get.ehselector in the catchpad. #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "lib"] @@ -36,8 +40,14 @@ fn panic_cannot_unwind() -> ! { #[no_mangle] #[rustc_nounwind] pub fn doesnt_unwind() { + // CHECK: catchswitch within none [label %{{.*}}] unwind to caller // emscripten: %catchpad = catchpad within %catchswitch [ptr null] // wasi: %catchpad = catchpad within %catchswitch [ptr null] // seh: %catchpad = catchpad within %catchswitch [ptr null, i32 64, ptr null] + // + // We don't call these intrinsics on wasm targets so we generate a catch_all + // instruction which also picks up foreign exceptions + // NOT: @llvm.wasm.get.exception + // NOT: @llvm.wasm.get.ehselector unwinds(); } diff --git a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs index 06d2232be5179..42d75be966840 100644 --- a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs +++ b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs @@ -1,8 +1,8 @@ //@ compile-flags: -Z unstable-options - +//@ ignore-stage1 (this can be removed when nightly goes to 1.96) #![feature(rustc_attrs)] #![feature(rustc_private)] -#![deny(rustc::pass_by_value)] +#![deny(rustc::disallowed_pass_by_ref)] #![allow(unused)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr index 69cf20656d7b1..b2906ea1e1195 100644 --- a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr +++ b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr @@ -7,8 +7,8 @@ LL | ty_ref: &Ty<'_>, note: the lint level is defined here --> $DIR/rustc_pass_by_value.rs:5:9 | -LL | #![deny(rustc::pass_by_value)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(rustc::disallowed_pass_by_ref)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: passing `TyCtxt<'_>` by reference --> $DIR/rustc_pass_by_value.rs:16:18 diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr index cc08c25906b66..7443c2977d54d 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr @@ -1,27 +1,14 @@ -error[E0277]: the trait bound `FreshTy(0): A` is not satisfied +error: type annotations needed for the literal --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:32:33 | LL | let _: dyn A; - | ^ the trait `A` is not implemented for `FreshTy(0)` - | -help: the trait `A` is implemented for `()` - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1 - | -LL | impl A for () { - | ^^^^^^^^^^^^^ + | ^ -error[E0277]: the trait bound `FreshTy(0): A` is not satisfied +error: type annotations needed for the literal --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:34:34 | LL | let _: &dyn A = &(); - | ^ the trait `A` is not implemented for `FreshTy(0)` - | -help: the trait `A` is implemented for `()` - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1 - | -LL | impl A for () { - | ^^^^^^^^^^^^^ + | ^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/mgca/array-expr-complex.stderr b/tests/ui/const-generics/mgca/array-expr-complex.stderr index beac1aa232f2f..544b0f05b4e44 100644 --- a/tests/ui/const-generics/mgca/array-expr-complex.stderr +++ b/tests/ui/const-generics/mgca/array-expr-complex.stderr @@ -5,16 +5,16 @@ LL | takes_array::<{ [1, 2, 1 + 2] }>(); | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr-complex.rs:10:19 + --> $DIR/array-expr-complex.rs:10:21 | LL | takes_array::<{ [X; 3] }>(); - | ^^^^^^^^^^ + | ^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr-complex.rs:12:19 + --> $DIR/array-expr-complex.rs:12:21 | LL | takes_array::<{ [0; Y] }>(); - | ^^^^^^^^^^ + | ^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs index cda519b96d4d8..98feccfc99c74 100644 --- a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs @@ -14,7 +14,7 @@ where fn bar() where - T: Trait2<3>, //~ ERROR: mismatched types + T: Trait2<3>, //~ ERROR: type annotations needed for the literal { } diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr index be40e44742267..169282547fc1d 100644 --- a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr @@ -4,12 +4,11 @@ error: expected `usize`, found const array LL | T: Trait1<{ [] }>, | ^^ -error[E0308]: mismatched types +error: type annotations needed for the literal --> $DIR/array-expr-type-mismatch-in-where-bound.rs:17:15 | LL | T: Trait2<3>, - | ^ expected `[u8; 3]`, found integer + | ^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 714d7a804d111..1c72afce52c7d 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,8 +1,8 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:13:33 + --> $DIR/explicit_anon_consts.rs:13:35 | LL | type Adt4 = Foo<{ 1 + 1 }>; - | ^^^^^^^^^ + | ^^^^^ error: complex const arguments must be placed inside of a `const` block --> $DIR/explicit_anon_consts.rs:21:34 @@ -17,22 +17,22 @@ LL | let _4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:45:43 + --> $DIR/explicit_anon_consts.rs:45:45 | LL | type const ITEM4: usize = { 1 + 1 }; - | ^^^^^^^^^ + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:62:23 + --> $DIR/explicit_anon_consts.rs:62:25 | LL | T4: Trait, - | ^^^^^^^^^ + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:71:50 + --> $DIR/explicit_anon_consts.rs:71:52 | LL | struct Default4; - | ^^^^^^^^^ + | ^^^^^ error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:42:51 diff --git a/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs b/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs index cd68a2c0d4301..4a3efb801cb01 100644 --- a/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs +++ b/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs @@ -1,4 +1,4 @@ -#![feature(adt_const_params, min_generic_const_args)] +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] #![expect(incomplete_features)] use std::marker::ConstParamTy; @@ -10,17 +10,22 @@ struct Foo { fn foo() {} +fn bar() {} + fn main() { foo::<{ Foo { field: -1_usize } }>(); //~^ ERROR: type annotations needed for the literal foo::<{ Foo { field: { -1_usize } } }>(); - //~^ ERROR: complex const arguments must be placed inside of a `const` block + //~^ ERROR: type annotations needed for the literal foo::<{ Foo { field: -true } }>(); - //~^ ERROR: the constant `true` is not of type `isize` + //~^ ERROR negated literal must be an integer foo::<{ Foo { field: { -true } } }>(); - //~^ ERROR: complex const arguments must be placed inside of a `const` block + //~^ ERROR negated literal must be an integer foo::<{ Foo { field: -"<3" } }>(); - //~^ ERROR: the constant `"<3"` is not of type `isize` + //~^ ERROR negated literal must be an integer foo::<{ Foo { field: { -"<3" } } }>(); - //~^ ERROR: complex const arguments must be placed inside of a `const` block + //~^ ERROR negated literal must be an integer + + bar::<{ -"hi" }>(); + //~^ ERROR: negated literal must be an integer } diff --git a/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr b/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr index 43ed4b71e33e7..60c559d1d5ba9 100644 --- a/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr +++ b/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr @@ -1,38 +1,44 @@ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/nonsensical-negated-literal.rs:16:26 +error: negated literal must be an integer + --> $DIR/nonsensical-negated-literal.rs:20:26 | -LL | foo::<{ Foo { field: { -1_usize } } }>(); - | ^^^^^^^^^^^^ +LL | foo::<{ Foo { field: -true } }>(); + | ^^^^^ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/nonsensical-negated-literal.rs:20:26 +error: negated literal must be an integer + --> $DIR/nonsensical-negated-literal.rs:22:28 | LL | foo::<{ Foo { field: { -true } } }>(); - | ^^^^^^^^^ + | ^^^^^ -error: complex const arguments must be placed inside of a `const` block +error: negated literal must be an integer --> $DIR/nonsensical-negated-literal.rs:24:26 | +LL | foo::<{ Foo { field: -"<3" } }>(); + | ^^^^^ + +error: negated literal must be an integer + --> $DIR/nonsensical-negated-literal.rs:26:28 + | LL | foo::<{ Foo { field: { -"<3" } } }>(); - | ^^^^^^^^^ + | ^^^^^ + +error: negated literal must be an integer + --> $DIR/nonsensical-negated-literal.rs:29:13 + | +LL | bar::<{ -"hi" }>(); + | ^^^^^ error: type annotations needed for the literal - --> $DIR/nonsensical-negated-literal.rs:14:26 + --> $DIR/nonsensical-negated-literal.rs:16:26 | LL | foo::<{ Foo { field: -1_usize } }>(); | ^^^^^^^^ -error: the constant `true` is not of type `isize` - --> $DIR/nonsensical-negated-literal.rs:18:13 - | -LL | foo::<{ Foo { field: -true } }>(); - | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` - -error: the constant `"<3"` is not of type `isize` - --> $DIR/nonsensical-negated-literal.rs:22:13 +error: type annotations needed for the literal + --> $DIR/nonsensical-negated-literal.rs:18:28 | -LL | foo::<{ Foo { field: -"<3" } }>(); - | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&'static str` +LL | foo::<{ Foo { field: { -1_usize } } }>(); + | ^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs index 3262e79478bdb..c57121a4a26a0 100644 --- a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs @@ -6,6 +6,7 @@ struct A; impl A { type const B = 4; //~^ ERROR: missing type for `const` item + //~| ERROR: type annotations needed for the literal } fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr index 77e54ab2f2e93..7fbb7461a4911 100644 --- a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr @@ -9,5 +9,11 @@ help: provide a type for the item LL | type const B: = 4; | ++++++++ -error: aborting due to 1 previous error +error: type annotations needed for the literal + --> $DIR/type_const-inherent-const-omitted-type.rs:7:20 + | +LL | type const B = 4; + | ^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs index c73785f9a3e38..b17a5b2b978a6 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -3,7 +3,6 @@ type const FREE: u32 = 5_usize; //~^ ERROR the constant `5` is not of type `u32` -//~| ERROR mismatched types type const FREE2: isize = FREE; //~^ ERROR the constant `5` is not of type `isize` @@ -14,7 +13,7 @@ trait Tr { impl Tr for () { type const N: usize = false; - //~^ ERROR mismatched types + //~^ ERROR the constant `false` is not of type `usize` } fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr index f7f64c535f602..e2c916cf6d05a 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -5,29 +5,16 @@ LL | type const FREE: u32 = 5_usize; | ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` error: the constant `5` is not of type `isize` - --> $DIR/type_const-mismatched-types.rs:8:1 + --> $DIR/type_const-mismatched-types.rs:7:1 | LL | type const FREE2: isize = FREE; | ^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `usize` -error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:16:27 +error: the constant `false` is not of type `usize` + --> $DIR/type_const-mismatched-types.rs:15:5 | LL | type const N: usize = false; - | ^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:4:24 - | -LL | type const FREE: u32 = 5_usize; - | ^^^^^^^ expected `u32`, found `usize` - | -help: change the type of the numeric literal from `usize` to `u32` - | -LL - type const FREE: u32 = 5_usize; -LL + type const FREE: u32 = 5_u32; - | - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs index a7ff9f0ce03f7..c8c7788eb135a 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs @@ -10,6 +10,7 @@ struct GoodS; impl BadTr for GoodS { type const NUM: = 84; //~^ ERROR: missing type for `const` item + //~| ERROR: type annotations needed for the literal } diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr index 11a60246f6a68..99dc6398170db 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr @@ -5,12 +5,18 @@ LL | type const NUM: = 84; | ^ help: provide a type for the associated constant: `usize` error: use of trait associated const not defined as `type const` - --> $DIR/type_const-only-in-impl-omitted-type.rs:16:43 + --> $DIR/type_const-only-in-impl-omitted-type.rs:17:43 | LL | fn accept_bad_tr>(_x: &T) {} | ^^^^^^^^^^^ | = note: the declaration in the trait must begin with `type const` not just `const` alone -error: aborting due to 2 previous errors +error: type annotations needed for the literal + --> $DIR/type_const-only-in-impl-omitted-type.rs:11:23 + | +LL | type const NUM: = 84; + | ^^ + +error: aborting due to 3 previous errors diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index 2a05d77f8f6da..19c8090e8de8b 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -62,10 +62,9 @@ impl ::core::cmp::PartialEq for Empty { } #[automatically_derived] impl ::core::cmp::Eq for Empty { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) {} + fn assert_fields_are_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Empty { @@ -139,10 +138,9 @@ impl ::core::cmp::PartialEq for Point { } #[automatically_derived] impl ::core::cmp::Eq for Point { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -227,10 +225,9 @@ impl ::core::cmp::PartialEq for PackedPoint { } #[automatically_derived] impl ::core::cmp::Eq for PackedPoint { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -310,10 +307,9 @@ impl ::core::cmp::PartialEq for TupleSingleField { } #[automatically_derived] impl ::core::cmp::Eq for TupleSingleField { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -385,10 +381,9 @@ impl ::core::cmp::PartialEq for SingleField { } #[automatically_derived] impl ::core::cmp::Eq for SingleField { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -490,10 +485,9 @@ impl ::core::cmp::PartialEq for Big { } #[automatically_derived] impl ::core::cmp::Eq for Big { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -754,10 +748,9 @@ impl ::core::cmp::PartialEq for Unsized { } #[automatically_derived] impl ::core::cmp::Eq for Unsized { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq<[u32]>; } } @@ -849,10 +842,9 @@ impl #[automatically_derived] impl ::core::cmp::Eq for Generic where T::A: ::core::cmp::Eq { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -971,10 +963,9 @@ impl ::core::cmp::Eq for PackedGeneric where T::A: ::core::cmp::Eq + ::core::marker::Copy { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -1056,10 +1047,9 @@ impl ::core::cmp::PartialEq for Enum0 { } #[automatically_derived] impl ::core::cmp::Eq for Enum0 { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) {} + fn assert_fields_are_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Enum0 { @@ -1126,10 +1116,9 @@ impl ::core::cmp::PartialEq for Enum1 { } #[automatically_derived] impl ::core::cmp::Eq for Enum1 { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -1192,10 +1181,9 @@ impl ::core::cmp::PartialEq for Fieldless1 { } #[automatically_derived] impl ::core::cmp::Eq for Fieldless1 { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) {} + fn assert_fields_are_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless1 { @@ -1269,10 +1257,9 @@ impl ::core::cmp::PartialEq for Fieldless { } #[automatically_derived] impl ::core::cmp::Eq for Fieldless { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) {} + fn assert_fields_are_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless { @@ -1379,10 +1366,9 @@ impl ::core::cmp::PartialEq for Mixed { } #[automatically_derived] impl ::core::cmp::Eq for Mixed { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; let _: ::core::cmp::AssertParamIsEq>; @@ -1577,10 +1563,9 @@ impl ::core::cmp::PartialEq for Fielded { } #[automatically_derived] impl ::core::cmp::Eq for Fielded { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; @@ -1699,10 +1684,9 @@ impl #[automatically_derived] impl ::core::cmp::Eq for EnumGeneric { - #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) { + fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; } diff --git a/tests/ui/deriving/internal_eq_trait_method_impls.rs b/tests/ui/deriving/internal_eq_trait_method_impls.rs new file mode 100644 index 0000000000000..b2605fe3c8668 --- /dev/null +++ b/tests/ui/deriving/internal_eq_trait_method_impls.rs @@ -0,0 +1,48 @@ +#![deny(deprecated, internal_eq_trait_method_impls)] +pub struct Bad; + +impl PartialEq for Bad { + fn eq(&self, _: &Self) -> bool { + true + } +} + +impl Eq for Bad { + fn assert_receiver_is_total_eq(&self) {} + //~^ ERROR: `Eq::assert_receiver_is_total_eq` should never be implemented by hand [internal_eq_trait_method_impls] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} + +#[derive(PartialEq, Eq)] +pub struct Good; + +#[derive(PartialEq)] +pub struct Good2; + +impl Eq for Good2 {} + +pub struct Foo; + +pub trait SameName { + fn assert_receiver_is_total_eq(&self) {} +} + +impl SameName for Foo { + fn assert_receiver_is_total_eq(&self) {} +} + +pub fn main() { + Foo.assert_receiver_is_total_eq(); + Good2.assert_receiver_is_total_eq(); + //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated] + Good.assert_receiver_is_total_eq(); + //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated] + Bad.assert_receiver_is_total_eq(); + //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated] +} + +#[forbid(internal_eq_trait_method_impls)] +mod forbid { + #[derive(PartialEq, Eq)] + pub struct Foo; +} diff --git a/tests/ui/deriving/internal_eq_trait_method_impls.stderr b/tests/ui/deriving/internal_eq_trait_method_impls.stderr new file mode 100644 index 0000000000000..8ff8fe337a78c --- /dev/null +++ b/tests/ui/deriving/internal_eq_trait_method_impls.stderr @@ -0,0 +1,41 @@ +error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` + --> $DIR/internal_eq_trait_method_impls.rs:36:11 + | +LL | Good2.assert_receiver_is_total_eq(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/internal_eq_trait_method_impls.rs:1:9 + | +LL | #![deny(deprecated, internal_eq_trait_method_impls)] + | ^^^^^^^^^^ + +error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` + --> $DIR/internal_eq_trait_method_impls.rs:38:10 + | +LL | Good.assert_receiver_is_total_eq(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` + --> $DIR/internal_eq_trait_method_impls.rs:40:9 + | +LL | Bad.assert_receiver_is_total_eq(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `Eq::assert_receiver_is_total_eq` should never be implemented by hand + --> $DIR/internal_eq_trait_method_impls.rs:11:5 + | +LL | fn assert_receiver_is_total_eq(&self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #152336 + = note: this method was used to add checks to the `Eq` derive macro +note: the lint level is defined here + --> $DIR/internal_eq_trait_method_impls.rs:1:21 + | +LL | #![deny(deprecated, internal_eq_trait_method_impls)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/internal-lints/rustc_pass_by_value_self.rs b/tests/ui/internal-lints/rustc_pass_by_value_self.rs index d2e0e272025f6..695c617d32f82 100644 --- a/tests/ui/internal-lints/rustc_pass_by_value_self.rs +++ b/tests/ui/internal-lints/rustc_pass_by_value_self.rs @@ -5,7 +5,7 @@ // Considering that all other `internal-lints` are tested here // this seems like the cleaner solution though. #![feature(rustc_attrs)] -#![deny(rustc::pass_by_value)] +#![deny(rustc::disallowed_pass_by_ref)] #![allow(unused)] #[rustc_pass_by_value] diff --git a/tests/ui/internal-lints/rustc_pass_by_value_self.stderr b/tests/ui/internal-lints/rustc_pass_by_value_self.stderr index fb39ed60b8235..d9e9f7e48506b 100644 --- a/tests/ui/internal-lints/rustc_pass_by_value_self.stderr +++ b/tests/ui/internal-lints/rustc_pass_by_value_self.stderr @@ -7,8 +7,8 @@ LL | fn by_ref(&self) {} note: the lint level is defined here --> $DIR/rustc_pass_by_value_self.rs:8:9 | -LL | #![deny(rustc::pass_by_value)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(rustc::disallowed_pass_by_ref)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: passing `Ty<'tcx>` by reference --> $DIR/rustc_pass_by_value_self.rs:30:21 diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index a48940460f91e..4a94b81452a90 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -8,7 +8,7 @@ macro-stats #[derive(Hash)] 2 17 8.5 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 503 503.0 macro-stats #[derive(Default)] 2 16 8.0 403 201.5 -macro-stats #[derive(Eq)] 1 11 11.0 319 319.0 +macro-stats #[derive(Eq)] 1 10 10.0 298 298.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 267 267.0 macro-stats #[derive(Copy)] 1 2 2.0 61 61.0