diff options
37 files changed, 320 insertions, 561 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 878a670cba3..48d24ecf412 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2082,7 +2082,12 @@ fn add_order_independent_options( // sections to ensure we have all the data for PGO. let keep_metadata = crate_type == CrateType::Dylib || sess.opts.cg.profile_generate.enabled(); - cmd.gc_sections(keep_metadata); + if crate_type != CrateType::Executable || !sess.opts.unstable_opts.export_executable_symbols + { + cmd.gc_sections(keep_metadata); + } else { + cmd.no_gc_sections(); + } } cmd.set_output_kind(link_output_kind, out_filename); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index d4a9db4af23..8e5ac9da4ac 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -640,9 +640,14 @@ impl<'a> Linker for GccLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { // Symbol visibility in object files typically takes care of this. - if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none() - { - return; + if crate_type == CrateType::Executable { + let should_export_executable_symbols = + self.sess.opts.unstable_opts.export_executable_symbols; + if self.sess.target.override_export_symbols.is_none() + && !should_export_executable_symbols + { + return; + } } // We manually create a list of exported symbols to ensure we don't expose any more. @@ -969,7 +974,11 @@ impl<'a> Linker for MsvcLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { // Symbol visibility takes care of this typically if crate_type == CrateType::Executable { - return; + let should_export_executable_symbols = + self.sess.opts.unstable_opts.export_executable_symbols; + if !should_export_executable_symbols { + return; + } } let path = tmpdir.join("lib.def"); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 58cee0c8bb0..268c4d76503 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -435,18 +435,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::Place(place) => place, LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx), LocalRef::Operand(..) => { - if let Some(elem) = place_ref - .projection - .iter() - .enumerate() - .find(|elem| matches!(elem.1, mir::ProjectionElem::Deref)) - { - base = elem.0 + 1; + if place_ref.has_deref() { + base = 1; let cg_base = self.codegen_consume( bx, - mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref }, + mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref }, ); - cg_base.deref(bx.cx()) } else { bug!("using operand local {:?} as place", place_ref); diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index bfdef2dc0e8..ecad0518533 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -249,6 +249,7 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[ ("bulk-memory", Some(sym::wasm_target_feature)), ("mutable-globals", Some(sym::wasm_target_feature)), ("reference-types", Some(sym::wasm_target_feature)), + ("sign-ext", Some(sym::wasm_target_feature)), ]; const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))]; diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 42de0dbdca9..d563e35f910 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -571,8 +571,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now determine the actual method to call. We can do that in two different ways and // compare them to ensure everything fits. - let ty::VtblEntry::Method(fn_inst) = self.get_vtable_entries(vptr)?[idx] else { - span_bug!(self.cur_span(), "dyn call index points at something that is not a method") + let Some(ty::VtblEntry::Method(fn_inst)) = self.get_vtable_entries(vptr)?.get(idx).copied() else { + throw_ub_format!("`dyn` call trying to call something that is not a method") }; if cfg!(debug_assertions) { let tcx = *self.tcx; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d07e17f6792..0a0eb99cd92 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -733,6 +733,7 @@ fn test_unstable_options_tracking_hash() { tracked!(debug_macros, true); tracked!(dep_info_omit_d_target, true); tracked!(drop_tracking, true); + tracked!(export_executable_symbols, true); tracked!(dual_proc_macros, true); tracked!(dwarf_version, Some(5)); tracked!(emit_thin_lto, false); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 702cc48ff7b..f7311ebdabf 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1461,6 +1461,14 @@ impl<'tcx> Place<'tcx> { self.projection.iter().any(|elem| elem.is_indirect()) } + /// If MirPhase >= Derefered and if projection contains Deref, + /// It's guaranteed to be in the first place + pub fn has_deref(&self) -> bool { + // To make sure this is not accidently used in wrong mir phase + debug_assert!(!self.projection[1..].contains(&PlaceElem::Deref)); + self.projection.first() == Some(&PlaceElem::Deref) + } + /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or /// a single deref of a local. #[inline(always)] @@ -1533,6 +1541,12 @@ impl<'tcx> PlaceRef<'tcx> { } } + /// If MirPhase >= Derefered and if projection contains Deref, + /// It's guaranteed to be in the first place + pub fn has_deref(&self) -> bool { + self.projection.first() == Some(&PlaceElem::Deref) + } + /// If this place represents a local variable like `_X` with no /// projections, return `Some(_X)`. #[inline] diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index b91ae083cf5..9c5896c4e4a 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -15,22 +15,9 @@ pub struct AddRetag; /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic /// copies. Data races are UB.) fn is_stable(place: PlaceRef<'_>) -> bool { - place.projection.iter().all(|elem| { - match elem { - // Which place this evaluates to can change with any memory write, - // so cannot assume this to be stable. - ProjectionElem::Deref => false, - // Array indices are interesting, but MIR building generates a *fresh* - // temporary for every array access, so the index cannot be changed as - // a side-effect. - ProjectionElem::Index { .. } | - // The rest is completely boring, they just offset by a constant. - ProjectionElem::Field { .. } | - ProjectionElem::ConstantIndex { .. } | - ProjectionElem::Subslice { .. } | - ProjectionElem::Downcast { .. } => true, - } - }) + // Which place this evaluates to can change with any memory write, + // so cannot assume deref to be stable. + !place.has_deref() } /// Determine whether this type may contain a reference (or box), and thus needs retagging. @@ -91,11 +78,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag { }; let place_base_raw = |place: &Place<'tcx>| { // If this is a `Deref`, get the type of what we are deref'ing. - let deref_base = - place.projection.iter().rposition(|p| matches!(p, ProjectionElem::Deref)); - if let Some(deref_base) = deref_base { - let base_proj = &place.projection[..deref_base]; - let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty; + if place.has_deref() { + let ty = &local_decls[place.local].ty; ty.is_unsafe_ptr() } else { // Not a deref, and thus not raw. diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 2eb38941f1a..c21c1efe991 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -36,13 +36,16 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) { tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| { // FIXME: when we make this a hard error, this should have its // own error code. - let message = if tcx.generics_of(def_id).own_requires_monomorphization() { - "`#[derive]` can't be used on a `#[repr(packed)]` struct with \ - type or const parameters (error E0133)" + let extra = if tcx.generics_of(def_id).own_requires_monomorphization() { + "with type or const parameters" } else { - "`#[derive]` can't be used on a `#[repr(packed)]` struct that \ - does not derive Copy (error E0133)" + "that does not derive `Copy`" }; + let message = format!( + "`{}` can't be derived on this `#[repr(packed)]` struct {} (error E0133)", + tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")), + extra + ); lint.build(message).emit(); }); } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index f6484a9b54d..85ad6b8f2fe 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -155,18 +155,18 @@ impl<'tcx> MirPass<'tcx> for ConstProp { } } -struct ConstPropMachine<'mir, 'tcx> { +pub struct ConstPropMachine<'mir, 'tcx> { /// The virtual call stack. stack: Vec<Frame<'mir, 'tcx>>, /// `OnlyInsideOwnBlock` locals that were written in the current block get erased at the end. - written_only_inside_own_block_locals: FxHashSet<Local>, + pub written_only_inside_own_block_locals: FxHashSet<Local>, /// Locals that need to be cleared after every block terminates. - only_propagate_inside_block_locals: BitSet<Local>, - can_const_prop: IndexVec<Local, ConstPropMode>, + pub only_propagate_inside_block_locals: BitSet<Local>, + pub can_const_prop: IndexVec<Local, ConstPropMode>, } impl ConstPropMachine<'_, '_> { - fn new( + pub fn new( only_propagate_inside_block_locals: BitSet<Local>, can_const_prop: IndexVec<Local, ConstPropMode>, ) -> Self { @@ -816,7 +816,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// The mode that `ConstProp` is allowed to run in for a given `Local`. #[derive(Clone, Copy, Debug, PartialEq)] -enum ConstPropMode { +pub enum ConstPropMode { /// The `Local` can be propagated into and reads of this `Local` can also be propagated. FullConstProp, /// The `Local` can only be propagated into and from its own block. @@ -828,7 +828,7 @@ enum ConstPropMode { NoPropagation, } -struct CanConstProp { +pub struct CanConstProp { can_const_prop: IndexVec<Local, ConstPropMode>, // False at the beginning. Once set, no more assignments are allowed to that local. found_assignment: BitSet<Local>, @@ -838,7 +838,7 @@ struct CanConstProp { impl CanConstProp { /// Returns true if `local` can be propagated - fn check<'tcx>( + pub fn check<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, body: &Body<'tcx>, diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 97b1433f5d2..3ae6a88a140 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -1,19 +1,24 @@ //! Propagates constants for early reporting of statically known //! assertion failures -use std::cell::Cell; - -use rustc_ast::Mutability; -use rustc_data_structures::fx::FxHashSet; +use crate::const_prop::CanConstProp; +use crate::const_prop::ConstPropMachine; +use crate::const_prop::ConstPropMode; +use crate::MirLint; +use rustc_const_eval::const_eval::ConstEvalErr; +use rustc_const_eval::interpret::{ + self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, + ScalarMaybeUninit, StackPopCleanup, +}; use rustc_hir::def::DefKind; use rustc_hir::HirId; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; -use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{ - AssertKind, BasicBlock, BinOp, Body, Constant, ConstantKind, Local, LocalDecl, LocalKind, - Location, Operand, Place, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement, - StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, + AssertKind, BinOp, Body, Constant, ConstantKind, Local, LocalDecl, Location, Operand, Place, + Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, + TerminatorKind, UnOp, RETURN_PLACE, }; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; @@ -22,42 +27,15 @@ use rustc_middle::ty::{ TypeVisitable, }; use rustc_session::lint; -use rustc_span::{def_id::DefId, Span}; +use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; -use rustc_target::spec::abi::Abi as CallAbi; use rustc_trait_selection::traits; - -use crate::MirLint; -use rustc_const_eval::const_eval::ConstEvalErr; -use rustc_const_eval::interpret::{ - self, compile_time_machine, AllocId, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult, - LocalState, LocalValue, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, ScalarMaybeUninit, - StackPopCleanup, StackPopUnwind, -}; +use std::cell::Cell; /// The maximum number of bytes that we'll allocate space for a local or the return value. /// Needed for #66397, because otherwise we eval into large places and that can cause OOM or just /// Severely regress performance. const MAX_ALLOC_LIMIT: u64 = 1024; - -/// Macro for machine-specific `InterpError` without allocation. -/// (These will never be shown to the user, but they help diagnose ICEs.) -macro_rules! throw_machine_stop_str { - ($($tt:tt)*) => {{ - // We make a new local type for it. The type itself does not carry any information, - // but its vtable (for the `MachineStopType` trait) does. - struct Zst; - // Printing this type shows the desired string. - impl std::fmt::Display for Zst { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, $($tt)*) - } - } - impl rustc_middle::mir::interpret::MachineStopType for Zst {} - throw_machine_stop!(Zst) - }}; -} - pub struct ConstProp; impl<'tcx> MirLint<'tcx> for ConstProp { @@ -151,172 +129,6 @@ impl<'tcx> MirLint<'tcx> for ConstProp { } } -struct ConstPropMachine<'mir, 'tcx> { - /// The virtual call stack. - stack: Vec<Frame<'mir, 'tcx>>, - /// `OnlyInsideOwnBlock` locals that were written in the current block get erased at the end. - written_only_inside_own_block_locals: FxHashSet<Local>, - /// Locals that need to be cleared after every block terminates. - only_propagate_inside_block_locals: BitSet<Local>, - can_const_prop: IndexVec<Local, ConstPropMode>, -} - -impl ConstPropMachine<'_, '_> { - fn new( - only_propagate_inside_block_locals: BitSet<Local>, - can_const_prop: IndexVec<Local, ConstPropMode>, - ) -> Self { - Self { - stack: Vec::new(), - written_only_inside_own_block_locals: Default::default(), - only_propagate_inside_block_locals, - can_const_prop, - } - } -} - -impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> { - compile_time_machine!(<'mir, 'tcx>); - const PANIC_ON_ALLOC_FAIL: bool = true; // all allocations are small (see `MAX_ALLOC_LIMIT`) - - type MemoryKind = !; - - fn load_mir( - _ecx: &InterpCx<'mir, 'tcx, Self>, - _instance: ty::InstanceDef<'tcx>, - ) -> InterpResult<'tcx, &'tcx Body<'tcx>> { - throw_machine_stop_str!("calling functions isn't supported in ConstProp") - } - - fn find_mir_or_eval_fn( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _instance: ty::Instance<'tcx>, - _abi: CallAbi, - _args: &[OpTy<'tcx>], - _destination: &PlaceTy<'tcx>, - _target: Option<BasicBlock>, - _unwind: StackPopUnwind, - ) -> InterpResult<'tcx, Option<(&'mir Body<'tcx>, ty::Instance<'tcx>)>> { - Ok(None) - } - - fn call_intrinsic( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _instance: ty::Instance<'tcx>, - _args: &[OpTy<'tcx>], - _destination: &PlaceTy<'tcx>, - _target: Option<BasicBlock>, - _unwind: StackPopUnwind, - ) -> InterpResult<'tcx> { - throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp") - } - - fn assert_panic( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _msg: &rustc_middle::mir::AssertMessage<'tcx>, - _unwind: Option<rustc_middle::mir::BasicBlock>, - ) -> InterpResult<'tcx> { - bug!("panics terminators are not evaluated in ConstProp") - } - - fn binary_ptr_op( - _ecx: &InterpCx<'mir, 'tcx, Self>, - _bin_op: BinOp, - _left: &ImmTy<'tcx>, - _right: &ImmTy<'tcx>, - ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> { - // We can't do this because aliasing of memory can differ between const eval and llvm - throw_machine_stop_str!("pointer arithmetic or comparisons aren't supported in ConstProp") - } - - fn access_local<'a>( - frame: &'a Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, - local: Local, - ) -> InterpResult<'tcx, &'a interpret::Operand<Self::Provenance>> { - let l = &frame.locals[local]; - - if matches!( - l.value, - LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit)) - ) { - // For us "uninit" means "we don't know its value, might be initiailized or not". - // So stop here. - throw_machine_stop_str!("tried to access a local with unknown value") - } - - l.access() - } - - fn access_local_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self>, - frame: usize, - local: Local, - ) -> InterpResult<'tcx, &'a mut interpret::Operand<Self::Provenance>> { - if ecx.machine.can_const_prop[local] == ConstPropMode::NoPropagation { - throw_machine_stop_str!("tried to write to a local that is marked as not propagatable") - } - if frame == 0 && ecx.machine.only_propagate_inside_block_locals.contains(local) { - trace!( - "mutating local {:?} which is restricted to its block. \ - Will remove it from const-prop after block is finished.", - local - ); - ecx.machine.written_only_inside_own_block_locals.insert(local); - } - ecx.machine.stack[frame].locals[local].access_mut() - } - - fn before_access_global( - _tcx: TyCtxt<'tcx>, - _machine: &Self, - _alloc_id: AllocId, - alloc: ConstAllocation<'tcx, Self::Provenance, Self::AllocExtra>, - _static_def_id: Option<DefId>, - is_write: bool, - ) -> InterpResult<'tcx> { - if is_write { - throw_machine_stop_str!("can't write to global"); - } - // If the static allocation is mutable, then we can't const prop it as its content - // might be different at runtime. - if alloc.inner().mutability == Mutability::Mut { - throw_machine_stop_str!("can't access mutable globals in ConstProp"); - } - - Ok(()) - } - - #[inline(always)] - fn expose_ptr( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _ptr: Pointer<AllocId>, - ) -> InterpResult<'tcx> { - throw_machine_stop_str!("exposing pointers isn't supported in ConstProp") - } - - #[inline(always)] - fn init_frame_extra( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - frame: Frame<'mir, 'tcx>, - ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> { - Ok(frame) - } - - #[inline(always)] - fn stack<'a>( - ecx: &'a InterpCx<'mir, 'tcx, Self>, - ) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { - &ecx.machine.stack - } - - #[inline(always)] - fn stack_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self>, - ) -> &'a mut Vec<Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>> { - &mut ecx.machine.stack - } -} - /// Finds optimization opportunities on the MIR. struct ConstPropagator<'mir, 'tcx> { ecx: InterpCx<'mir, 'tcx, ConstPropMachine<'mir, 'tcx>>, @@ -711,139 +523,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } -/// The mode that `ConstProp` is allowed to run in for a given `Local`. -#[derive(Clone, Copy, Debug, PartialEq)] -enum ConstPropMode { - /// The `Local` can be propagated into and reads of this `Local` can also be propagated. - FullConstProp, - /// The `Local` can only be propagated into and from its own block. - OnlyInsideOwnBlock, - /// The `Local` can be propagated into but reads cannot be propagated. - OnlyPropagateInto, - /// The `Local` cannot be part of propagation at all. Any statement - /// referencing it either for reading or writing will not get propagated. - NoPropagation, -} - -struct CanConstProp { - can_const_prop: IndexVec<Local, ConstPropMode>, - // False at the beginning. Once set, no more assignments are allowed to that local. - found_assignment: BitSet<Local>, - // Cache of locals' information - local_kinds: IndexVec<Local, LocalKind>, -} - -impl CanConstProp { - /// Returns true if `local` can be propagated - fn check<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - body: &Body<'tcx>, - ) -> IndexVec<Local, ConstPropMode> { - let mut cpv = CanConstProp { - can_const_prop: IndexVec::from_elem(ConstPropMode::FullConstProp, &body.local_decls), - found_assignment: BitSet::new_empty(body.local_decls.len()), - local_kinds: IndexVec::from_fn_n( - |local| body.local_kind(local), - body.local_decls.len(), - ), - }; - for (local, val) in cpv.can_const_prop.iter_enumerated_mut() { - let ty = body.local_decls[local].ty; - match tcx.layout_of(param_env.and(ty)) { - Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {} - // Either the layout fails to compute, then we can't use this local anyway - // or the local is too large, then we don't want to. - _ => { - *val = ConstPropMode::NoPropagation; - continue; - } - } - // Cannot use args at all - // Cannot use locals because if x < y { y - x } else { x - y } would - // lint for x != y - // FIXME(oli-obk): lint variables until they are used in a condition - // FIXME(oli-obk): lint if return value is constant - if cpv.local_kinds[local] == LocalKind::Arg { - *val = ConstPropMode::OnlyPropagateInto; - trace!( - "local {:?} can't be const propagated because it's a function argument", - local - ); - } else if cpv.local_kinds[local] == LocalKind::Var { - *val = ConstPropMode::OnlyInsideOwnBlock; - trace!( - "local {:?} will only be propagated inside its block, because it's a user variable", - local - ); - } - } - cpv.visit_body(&body); - cpv.can_const_prop - } -} - -impl Visitor<'_> for CanConstProp { - fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) { - use rustc_middle::mir::visit::PlaceContext::*; - match context { - // Projections are fine, because `&mut foo.x` will be caught by - // `MutatingUseContext::Borrow` elsewhere. - MutatingUse(MutatingUseContext::Projection) - // These are just stores, where the storing is not propagatable, but there may be later - // mutations of the same local via `Store` - | MutatingUse(MutatingUseContext::Call) - | MutatingUse(MutatingUseContext::AsmOutput) - | MutatingUse(MutatingUseContext::Deinit) - // Actual store that can possibly even propagate a value - | MutatingUse(MutatingUseContext::SetDiscriminant) - | MutatingUse(MutatingUseContext::Store) => { - if !self.found_assignment.insert(local) { - match &mut self.can_const_prop[local] { - // If the local can only get propagated in its own block, then we don't have - // to worry about multiple assignments, as we'll nuke the const state at the - // end of the block anyway, and inside the block we overwrite previous - // states as applicable. - ConstPropMode::OnlyInsideOwnBlock => {} - ConstPropMode::NoPropagation => {} - ConstPropMode::OnlyPropagateInto => {} - other @ ConstPropMode::FullConstProp => { - trace!( - "local {:?} can't be propagated because of multiple assignments. Previous state: {:?}", - local, other, - ); - *other = ConstPropMode::OnlyInsideOwnBlock; - } - } - } - } - // Reading constants is allowed an arbitrary number of times - NonMutatingUse(NonMutatingUseContext::Copy) - | NonMutatingUse(NonMutatingUseContext::Move) - | NonMutatingUse(NonMutatingUseContext::Inspect) - | NonMutatingUse(NonMutatingUseContext::Projection) - | NonUse(_) => {} - - // These could be propagated with a smarter analysis or just some careful thinking about - // whether they'd be fine right now. - MutatingUse(MutatingUseContext::Yield) - | MutatingUse(MutatingUseContext::Drop) - | MutatingUse(MutatingUseContext::Retag) - // These can't ever be propagated under any scheme, as we can't reason about indirect - // mutation. - | NonMutatingUse(NonMutatingUseContext::SharedBorrow) - | NonMutatingUse(NonMutatingUseContext::ShallowBorrow) - | NonMutatingUse(NonMutatingUseContext::UniqueBorrow) - | NonMutatingUse(NonMutatingUseContext::AddressOf) - | MutatingUse(MutatingUseContext::Borrow) - | MutatingUse(MutatingUseContext::AddressOf) => { - trace!("local {:?} can't be propagaged because it's used: {:?}", local, context); - self.can_const_prop[local] = ConstPropMode::NoPropagation; - } - } - } -} - impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { fn visit_body(&mut self, body: &Body<'tcx>) { for (bb, data) in body.basic_blocks().iter_enumerated() { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 1b583417ca0..28e2e0db89a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1282,6 +1282,8 @@ options! { "emit a section containing stack size metadata (default: no)"), emit_thin_lto: bool = (true, parse_bool, [TRACKED], "emit the bc module with thin LTO info (default: yes)"), + export_executable_symbols: bool = (false, parse_bool, [TRACKED], + "export symbols from executables, as if they were dynamic libraries"), fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index faa4f3700bb..1d7406e00ad 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -538,9 +538,9 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { impl ConstraintLocator<'_> { #[instrument(skip(self), level = "debug")] - fn check(&mut self, def_id: LocalDefId) { + fn check(&mut self, item_def_id: LocalDefId) { // Don't try to check items that cannot possibly constrain the type. - if !self.tcx.has_typeck_results(def_id) { + if !self.tcx.has_typeck_results(item_def_id) { debug!("no constraint: no typeck results"); return; } @@ -555,26 +555,20 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { // // because we again need to reveal `Foo` so we can check whether the // // constant does not contain interior mutability. // ``` - let tables = self.tcx.typeck(def_id); + let tables = self.tcx.typeck(item_def_id); if let Some(_) = tables.tainted_by_errors { self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error() }); return; } - if tables.concrete_opaque_types.get(&self.def_id).is_none() { + if !tables.concrete_opaque_types.contains_key(&self.def_id) { debug!("no constraints in typeck results"); return; } // Use borrowck to get the type with unerased regions. - let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; + let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types; debug!(?concrete_opaque_types); - for &(def_id, concrete_type) in concrete_opaque_types { - if def_id != self.def_id { - // Ignore constraints for other opaque types. - continue; - } - + if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { debug!(?concrete_type, "found constraint"); - if let Some(prev) = self.found { if concrete_type.ty != prev.ty && !(concrete_type, prev).references_error() { prev.report_mismatch(&concrete_type, self.tcx); diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index b1513e5e0f3..a5118e5333b 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -317,11 +317,11 @@ use crate::vec::Vec; /// /// ```text /// 0 -/// 5 -/// 10 -/// 20 -/// 20 -/// 40 +/// 8 +/// 16 +/// 16 +/// 32 +/// 32 /// ``` /// /// At first, we have no memory allocated at all, but as we append to the diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 1d3466696ed..ac286c171f0 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -22,6 +22,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::marker::Destruct; + use self::Ordering::*; /// Trait for equality comparisons which are [partial equivalence @@ -603,7 +605,8 @@ impl Ordering { pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T); #[stable(feature = "reverse_cmp_key", since = "1.19.0")] -impl<T: PartialOrd> PartialOrd for Reverse<T> { +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> { #[inline] fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> { other.0.partial_cmp(&self.0) @@ -761,6 +764,7 @@ impl<T: Clone> Clone for Reverse<T> { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] +#[const_trait] pub trait Ord: Eq + PartialOrd<Self> { /// This method returns an [`Ordering`] between `self` and `other`. /// @@ -796,8 +800,15 @@ pub trait Ord: Eq + PartialOrd<Self> { fn max(self, other: Self) -> Self where Self: Sized, + Self: ~const Destruct, { - max_by(self, other, Ord::cmp) + // HACK(fee1-dead): go back to using `self.max_by(other, Ord::cmp)` + // when trait methods are allowed to be used when a const closure is + // expected. + match self.cmp(&other) { + Ordering::Less | Ordering::Equal => other, + Ordering::Greater => self, + } } /// Compares and returns the minimum of two values. @@ -816,8 +827,15 @@ pub trait Ord: Eq + PartialOrd<Self> { fn min(self, other: Self) -> Self where Self: Sized, + Self: ~const Destruct, { - min_by(self, other, Ord::cmp) + // HACK(fee1-dead): go back to using `self.min_by(other, Ord::cmp)` + // when trait methods are allowed to be used when a const closure is + // expected. + match self.cmp(&other) { + Ordering::Less | Ordering::Equal => self, + Ordering::Greater => other, + } } /// Restrict a value to a certain interval. @@ -841,6 +859,8 @@ pub trait Ord: Eq + PartialOrd<Self> { fn clamp(self, min: Self, max: Self) -> Self where Self: Sized, + Self: ~const Destruct, + Self: ~const PartialOrd, { assert!(min <= max); if self < min { @@ -862,7 +882,8 @@ pub macro Ord($item:item) { } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Ordering { +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +impl const Ord for Ordering { #[inline] fn cmp(&self, other: &Ordering) -> Ordering { (*self as i32).cmp(&(*other as i32)) @@ -870,7 +891,8 @@ impl Ord for Ordering { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Ordering { +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +impl const PartialOrd for Ordering { #[inline] fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> { (*self as i32).partial_cmp(&(*other as i32)) @@ -1187,8 +1209,9 @@ pub macro PartialOrd($item:item) { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")] -pub fn min<T: Ord>(v1: T, v2: T) -> T { +pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { v1.min(v2) } @@ -1250,8 +1273,9 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")] -pub fn max<T: Ord>(v1: T, v2: T) -> T { +pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { v1.max(v2) } @@ -1304,7 +1328,8 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialEq for $t { #[inline] fn eq(&self, other: &$t) -> bool { (*self) == (*other) } #[inline] @@ -1314,7 +1339,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq for () { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialEq for () { #[inline] fn eq(&self, _other: &()) -> bool { true @@ -1341,7 +1367,8 @@ mod impls { macro_rules! partial_ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { match (*self <= *other, *self >= *other) { @@ -1364,7 +1391,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for () { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialOrd for () { #[inline] fn partial_cmp(&self, _: &()) -> Option<Ordering> { Some(Equal) @@ -1372,7 +1400,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for bool { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialOrd for bool { #[inline] fn partial_cmp(&self, other: &bool) -> Option<Ordering> { Some(self.cmp(other)) @@ -1384,7 +1413,8 @@ mod impls { macro_rules! ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { Some(self.cmp(other)) @@ -1400,7 +1430,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const Ord for $t { #[inline] fn cmp(&self, other: &$t) -> Ordering { // The order here is important to generate more optimal assembly. @@ -1414,7 +1445,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for () { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const Ord for () { #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal @@ -1422,7 +1454,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for bool { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const Ord for bool { #[inline] fn cmp(&self, other: &bool) -> Ordering { // Casting to i8's and converting the difference to an Ordering generates @@ -1441,7 +1474,8 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[unstable(feature = "never_type", issue = "35121")] - impl PartialEq for ! { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } @@ -1451,14 +1485,16 @@ mod impls { impl Eq for ! {} #[unstable(feature = "never_type", issue = "35121")] - impl PartialOrd for ! { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self } } #[unstable(feature = "never_type", issue = "35121")] - impl Ord for ! { + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self } diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 7ae1bfd4f35..81b6d5737ea 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -96,6 +96,7 @@ use crate::intrinsics; #[inline] #[stable(feature = "unreachable", since = "1.27.0")] #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unreachable_unchecked() -> ! { // SAFETY: the safety contract for `intrinsics::unreachable` must // be upheld by the caller. diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 9ae31a31aaa..7e65f4ebdad 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2449,6 +2449,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) - #[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] @@ -2535,6 +2536,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us #[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] @@ -2564,14 +2566,23 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) { /// /// * `dst` must be properly aligned. /// -/// Additionally, the caller must ensure that writing `count * -/// size_of::<T>()` bytes to the given region of memory results in a valid -/// value of `T`. Using a region of memory typed as a `T` that contains an -/// invalid value of `T` is undefined behavior. -/// /// Note that even if the effectively copied size (`count * size_of::<T>()`) is /// `0`, the pointer must be non-null and properly aligned. /// +/// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB) +/// later if the written bytes are not a valid representation of some `T`. For instance, the +/// following is an **incorrect** use of this function: +/// +/// ```rust,no_run +/// unsafe { +/// let mut value: u8 = 0; +/// let ptr: *mut bool = &mut value as *mut u8 as *mut bool; +/// let _bool = ptr.read(); // This is fine, `ptr` points to a valid `bool`. +/// ptr.write_bytes(42u8, 1); // This function itself does not cause UB... +/// let _bool = ptr.read(); // ...but it makes this operation UB! ⚠️ +/// } +/// ``` +/// /// [valid]: crate::ptr#safety /// /// # Examples @@ -2588,38 +2599,6 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) { /// } /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]); /// ``` -/// -/// Creating an invalid value: -/// -/// ``` -/// use std::ptr; -/// -/// let mut v = Box::new(0i32); -/// -/// unsafe { -/// // Leaks the previously held value by overwriting the `Box<T>` with -/// // a null pointer. -/// ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1); -/// } -/// -/// // At this point, using or dropping `v` results in undefined behavior. -/// // drop(v); // ERROR -/// -/// // Even leaking `v` "uses" it, and hence is undefined behavior. -/// // mem::forget(v); // ERROR -/// -/// // In fact, `v` is invalid according to basic type layout invariants, so *any* -/// // operation touching it is undefined behavior. -/// // let v2 = v; // ERROR -/// -/// unsafe { -/// // Let us instead put in a valid value -/// ptr::write(&mut v as *mut Box<i32>, Box::new(42i32)); -/// } -/// -/// // Now the box is fine -/// assert_eq!(*v, 42); -/// ``` #[doc(alias = "memset")] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f24a7ab61ae..30f2f0ee05c 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -105,6 +105,7 @@ #![feature(const_cell_into_inner)] #![feature(const_char_convert)] #![feature(const_clone)] +#![feature(const_cmp)] #![feature(const_discriminant)] #![feature(const_eval_select)] #![feature(const_float_bits_conv)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 66af4916074..6dc8563c421 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1124,6 +1124,7 @@ impl<T> fmt::Debug for Discriminant<T> { #[stable(feature = "discriminant_value", since = "1.21.0")] #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_discriminant")] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const fn discriminant<T>(v: &T) -> Discriminant<T> { Discriminant(intrinsics::discriminant_value(v)) } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index eb458f3866e..a66de19bad0 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -449,6 +449,7 @@ macro_rules! int_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_add`. @@ -517,6 +518,7 @@ macro_rules! int_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_sub`. @@ -585,6 +587,7 @@ macro_rules! int_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_mul`. @@ -757,6 +760,7 @@ macro_rules! int_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. @@ -803,6 +807,7 @@ macro_rules! int_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 715e78350a4..73365544233 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -459,6 +459,7 @@ macro_rules! uint_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_add`. @@ -528,6 +529,7 @@ macro_rules! uint_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_sub`. @@ -574,6 +576,7 @@ macro_rules! uint_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_mul`. @@ -933,6 +936,7 @@ macro_rules! uint_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. @@ -979,6 +983,7 @@ macro_rules! uint_impl { without modifying the original"] #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: Self) -> Self { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 6cdbab30589..e289a8e6bd5 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -449,6 +449,7 @@ impl<T: ?Sized> *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn offset(self, count: isize) -> *const T where T: Sized, @@ -471,6 +472,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset`. let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() }; @@ -641,6 +643,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "ptr_offset_from", since = "1.47.0")] #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized, @@ -663,6 +666,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize { // SAFETY: the caller must uphold the safety contract for `offset_from`. unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) } @@ -731,6 +735,7 @@ impl<T: ?Sized> *const T { #[unstable(feature = "ptr_sub_ptr", issue = "95892")] #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub_ptr(self, origin: *const T) -> usize where T: Sized, @@ -862,6 +867,7 @@ impl<T: ?Sized> *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn add(self, count: usize) -> Self where T: Sized, @@ -884,6 +890,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add`. let this = unsafe { self.cast::<u8>().add(count).cast::<()>() }; @@ -946,6 +953,7 @@ impl<T: ?Sized> *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -969,6 +977,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub`. let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() }; @@ -1205,6 +1214,7 @@ impl<T: ?Sized> *const T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where T: Sized, @@ -1224,6 +1234,7 @@ impl<T: ?Sized> *const T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where T: Sized, diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e323f63115b..fc3dd2a9b25 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -461,6 +461,7 @@ impl<T: ?Sized> *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn offset(self, count: isize) -> *mut T where T: Sized, @@ -485,6 +486,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset`. let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() }; @@ -824,6 +826,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "ptr_offset_from", since = "1.47.0")] #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized, @@ -844,6 +847,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize { // SAFETY: the caller must uphold the safety contract for `offset_from`. unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) } @@ -913,6 +917,7 @@ impl<T: ?Sized> *mut T { #[unstable(feature = "ptr_sub_ptr", issue = "95892")] #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub_ptr(self, origin: *const T) -> usize where T: Sized, @@ -976,6 +981,7 @@ impl<T: ?Sized> *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn add(self, count: usize) -> Self where T: Sized, @@ -998,6 +1004,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add`. let this = unsafe { self.cast::<u8>().add(count).cast::<()>() }; @@ -1060,6 +1067,7 @@ impl<T: ?Sized> *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -1083,6 +1091,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub`. let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() }; @@ -1319,6 +1328,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where T: Sized, @@ -1338,6 +1348,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where T: Sized, @@ -1357,6 +1368,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_from(self, src: *const T, count: usize) where T: Sized, @@ -1376,6 +1388,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) where T: Sized, diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index 6a01b4a2e28..8801c670bc9 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -37,12 +37,11 @@ pub unsafe fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 { abort(); cfg_if::cfg_if! { - if #[cfg(unix)] { + if #[cfg(any(unix, target_os = "solid_asp3"))] { unsafe fn abort() -> ! { libc::abort(); } } else if #[cfg(any(target_os = "hermit", - target_os = "solid_asp3", all(target_vendor = "fortanix", target_env = "sgx") ))] { unsafe fn abort() -> ! { diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 08b45ac11a1..8e478cd7bc8 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -382,6 +382,14 @@ pub mod token_stream { bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)), }) } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } + + fn count(self) -> usize { + self.0.count() + } } #[stable(feature = "proc_macro_lib2", since = "1.29.0")] diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index f4f2e3f2434..18f7f6a35e9 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2577,6 +2577,7 @@ impl<T: Read> Read for Take<T> { let max = cmp::min(buf.len() as u64, self.limit) as usize; let n = self.inner.read(&mut buf[..max])?; + assert!(n as u64 <= self.limit, "number of read bytes exceeds limit"); self.limit -= n as u64; Ok(n) } diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index d5a8c93b0ce..f357f33ec52 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -583,6 +583,25 @@ fn test_write_all_vectored() { } } +// Issue 94981 +#[test] +#[should_panic = "number of read bytes exceeds limit"] +fn test_take_wrong_length() { + struct LieAboutSize(bool); + + impl Read for LieAboutSize { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + // Lie about the read size at first time of read. + if core::mem::take(&mut self.0) { Ok(buf.len() + 1) } else { Ok(buf.len()) } + } + } + + let mut buffer = vec![0; 4]; + let mut reader = LieAboutSize(true).take(4); + // Primed the `Limit` by lying about the read size. + let _ = reader.read(&mut buffer[..]); +} + #[bench] fn bench_take_read(b: &mut test::Bencher) { b.iter(|| { diff --git a/library/std/src/sys/solid/abi/mod.rs b/library/std/src/sys/solid/abi/mod.rs index 1afc83f766d..8440d572cfb 100644 --- a/library/std/src/sys/solid/abi/mod.rs +++ b/library/std/src/sys/solid/abi/mod.rs @@ -4,32 +4,6 @@ mod fs; pub mod sockets; pub use self::fs::*; -#[inline(always)] -pub fn breakpoint_program_exited(tid: usize) { - unsafe { - match () { - // SOLID_BP_PROGRAM_EXITED = 15 - #[cfg(target_arch = "arm")] - () => core::arch::asm!("bkpt #15", in("r0") tid), - #[cfg(target_arch = "aarch64")] - () => core::arch::asm!("hlt #15", in("x0") tid), - } - } -} - -#[inline(always)] -pub fn breakpoint_abort() { - unsafe { - match () { - // SOLID_BP_CSABORT = 16 - #[cfg(target_arch = "arm")] - () => core::arch::asm!("bkpt #16"), - #[cfg(target_arch = "aarch64")] - () => core::arch::asm!("hlt #16"), - } - } -} - // `solid_types.h` pub use super::itron::abi::{ER, ER_ID, E_TMOUT, ID}; diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs index 2d21e4764fc..778a589d1b7 100644 --- a/library/std/src/sys/solid/mod.rs +++ b/library/std/src/sys/solid/mod.rs @@ -76,20 +76,9 @@ pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind { error::decode_error_kind(code) } -#[inline(always)] +#[inline] pub fn abort_internal() -> ! { - loop { - abi::breakpoint_abort(); - } -} - -// This function is needed by the panic runtime. The symbol is named in -// pre-link args for the target specification, so keep that in sync. -#[cfg(not(test))] -#[no_mangle] -// NB. used by both libunwind and libpanic_abort -pub extern "C" fn __rust_abort() { - abort_internal(); + unsafe { libc::abort() } } pub fn hashmap_random_keys() -> (u64, u64) { diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs index 719d95bbe50..b5649d6e0ff 100644 --- a/library/std/src/sys/solid/os.rs +++ b/library/std/src/sys/solid/os.rs @@ -11,7 +11,7 @@ use crate::path::{self, PathBuf}; use crate::sys_common::rwlock::StaticRwLock; use crate::vec; -use super::{abi, error, itron, memchr}; +use super::{error, itron, memchr}; // `solid` directly maps `errno`s to μITRON error codes. impl itron::error::ItronError { @@ -184,11 +184,8 @@ pub fn home_dir() -> Option<PathBuf> { None } -pub fn exit(_code: i32) -> ! { - let tid = itron::task::try_current_task_id().unwrap_or(0); - loop { - abi::breakpoint_program_exited(tid as usize); - } +pub fn exit(code: i32) -> ! { + rtabort!("exit({}) called", code); } pub fn getpid() -> u32 { diff --git a/src/test/run-make/export-executable-symbols/Makefile b/src/test/run-make/export-executable-symbols/Makefile new file mode 100644 index 00000000000..5006f9cb8cf --- /dev/null +++ b/src/test/run-make/export-executable-symbols/Makefile @@ -0,0 +1,11 @@ +-include ../../run-make-fulldeps/tools.mk + +# ignore-wasm32 +# ignore-wasm64 +# ignore-none no-std is not supported +# only-linux + +all: + $(RUSTC) -Zexport-executable-symbols main.rs --target $(TARGET) --crate-type=bin + nm $(TMPDIR)/main | $(CGREP) exported_symbol + diff --git a/src/test/run-make/export-executable-symbols/main.rs b/src/test/run-make/export-executable-symbols/main.rs new file mode 100644 index 00000000000..c498381a33f --- /dev/null +++ b/src/test/run-make/export-executable-symbols/main.rs @@ -0,0 +1,8 @@ +// edition:2018 + +fn main() {} + +#[no_mangle] +pub fn exported_symbol() -> i8 { + 42 +} diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index bcf323e1cab..86e42440bd0 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -37,6 +37,7 @@ -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) -Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes) + -Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries -Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no) -Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no) -Z fuel=val -- set the optimization fuel quota for a crate diff --git a/src/test/ui/derives/deriving-with-repr-packed.rs b/src/test/ui/derives/deriving-with-repr-packed.rs index b78eeaa9055..3884e397764 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.rs +++ b/src/test/ui/derives/deriving-with-repr-packed.rs @@ -1,29 +1,43 @@ #![deny(unaligned_references)] -// check that derive on a packed struct with non-Copy fields -// correctly. This can't be made to work perfectly because -// we can't just use the field from the struct as it might -// not be aligned. +// Check that deriving certain builtin traits on certain packed structs cause +// errors. This happens when the derived trait would need to use a potentially +// misaligned reference. But there are two cases that are allowed: +// - If all the fields within the struct meet the required alignment: 1 for +// `repr(packed)`, or `N` for `repr(packed(N))`. +// - If `Default` is the only trait derived, because it doesn't involve any +// references. -#[derive(Copy, Clone, PartialEq, Eq)] -//~^ ERROR `#[derive]` can't be used +#[derive(Copy, Clone, Default, PartialEq, Eq)] +//~^ ERROR `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters //~| hard error -//~^^^ ERROR `#[derive]` can't be used +//~^^^ ERROR `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters //~| hard error #[repr(packed)] pub struct Foo<T>(T, T, T); -#[derive(PartialEq, Eq)] -//~^ ERROR `#[derive]` can't be used +#[derive(Default, Hash)] +//~^ ERROR `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` //~| hard error #[repr(packed)] pub struct Bar(u32, u32, u32); -#[derive(PartialEq)] +// This one is fine because the field alignment is 1. +#[derive(Default, Hash)] +#[repr(packed)] +pub struct Bar2(u8, i8, bool); + +// This one is fine because the field alignment is 2, matching `packed(2)`. +#[derive(Default, Hash)] +#[repr(packed(2))] +pub struct Bar3(u16, i16, bool); + +// This one is fine because it's not packed. +#[derive(Debug, Default)] struct Y(usize); -#[derive(PartialEq)] -//~^ ERROR `#[derive]` can't be used +#[derive(Debug, Default)] +//~^ ERROR `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` //~| hard error #[repr(packed)] struct X(Y); diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index 1002b359f60..1f98da5b70e 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -1,7 +1,7 @@ -error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) - --> $DIR/deriving-with-repr-packed.rs:8:16 +error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133) + --> $DIR/deriving-with-repr-packed.rs:11:16 | -LL | #[derive(Copy, Clone, PartialEq, Eq)] +LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^ | note: the lint level is defined here @@ -13,43 +13,43 @@ LL | #![deny(unaligned_references)] = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) - --> $DIR/deriving-with-repr-packed.rs:8:23 +error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133) + --> $DIR/deriving-with-repr-packed.rs:11:32 | -LL | #[derive(Copy, Clone, PartialEq, Eq)] - | ^^^^^^^^^ +LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] + | ^^^^^^^^^ | = 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 #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) - --> $DIR/deriving-with-repr-packed.rs:16:10 +error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133) + --> $DIR/deriving-with-repr-packed.rs:19:19 | -LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ +LL | #[derive(Default, Hash)] + | ^^^^ | = 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 #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) - --> $DIR/deriving-with-repr-packed.rs:25:10 +error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133) + --> $DIR/deriving-with-repr-packed.rs:39:10 | -LL | #[derive(PartialEq)] - | ^^^^^^^^^ +LL | #[derive(Debug, Default)] + | ^^^^^ | = 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 #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors Future incompatibility report: Future breakage diagnostic: -error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) - --> $DIR/deriving-with-repr-packed.rs:8:16 +error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133) + --> $DIR/deriving-with-repr-packed.rs:11:16 | -LL | #[derive(Copy, Clone, PartialEq, Eq)] +LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^ | note: the lint level is defined here @@ -62,11 +62,11 @@ LL | #![deny(unaligned_references)] = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) - --> $DIR/deriving-with-repr-packed.rs:8:23 +error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133) + --> $DIR/deriving-with-repr-packed.rs:11:32 | -LL | #[derive(Copy, Clone, PartialEq, Eq)] - | ^^^^^^^^^ +LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] + | ^^^^^^^^^ | note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 @@ -78,11 +78,11 @@ LL | #![deny(unaligned_references)] = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) - --> $DIR/deriving-with-repr-packed.rs:16:10 +error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133) + --> $DIR/deriving-with-repr-packed.rs:19:19 | -LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ +LL | #[derive(Default, Hash)] + | ^^^^ | note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 @@ -91,14 +91,14 @@ LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) - --> $DIR/deriving-with-repr-packed.rs:25:10 +error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133) + --> $DIR/deriving-with-repr-packed.rs:39:10 | -LL | #[derive(PartialEq)] - | ^^^^^^^^^ +LL | #[derive(Debug, Default)] + | ^^^^^ | note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 @@ -107,5 +107,5 @@ LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/process/nofile-limit.rs b/src/test/ui/process/nofile-limit.rs index 549135a46cf..3ddf8d6ef24 100644 --- a/src/test/ui/process/nofile-limit.rs +++ b/src/test/ui/process/nofile-limit.rs @@ -6,7 +6,7 @@ // dont-check-compiler-stderr // only-linux // no-prefer-dynamic -// compile-flags: -Ctarget-feature=+crt-static -Crpath=no +// compile-flags: -Ctarget-feature=+crt-static -Crpath=no -Crelocation-model=static #![feature(exit_status_error)] #![feature(rustc_private)] extern crate libc; diff --git a/src/tools/miri b/src/tools/miri -Subproject 963f08b702caf7a06eed564312933ec50dd07f5 +Subproject b938529fb8ed8f7b5b374282ffc3ffa74c31311 |
