diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7a5eb28940e4..2e6c1dceef98 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1544,7 +1544,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::UnaryOp(_ /*un_op*/, operand) - | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) => { + | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) + | Rvalue::ShallowInitBox(operand, _ /*ty*/) => { self.consume_operand(location, (operand, span), state) } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 439aa1a91e06..99567da92ffe 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -297,9 +297,8 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::UnaryOp(_ /*un_op*/, operand) - | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) => { - self.consume_operand(location, operand) - } + | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) + | Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand), &Rvalue::Discriminant(place) => { self.access_place( diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2935559147b7..7d34d7c88e62 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1004,6 +1004,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } + Rvalue::ShallowInitBox(_operand, ty) => { + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]); + + self.prove_trait_ref( + trait_ref, + location.to_locations(), + ConstraintCategory::SizedBound, + ); + } + Rvalue::Cast(cast_kind, op, ty) => { match *cast_kind { CastKind::PointerCoercion( @@ -2220,6 +2231,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | Rvalue::Ref(..) | Rvalue::RawPtr(..) | Rvalue::Cast(..) + | Rvalue::ShallowInitBox(..) | Rvalue::BinaryOp(..) | Rvalue::CopyForDeref(..) | Rvalue::UnaryOp(..) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index e4865ece63b6..1a916c876824 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -902,6 +902,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: lval.write_cvalue_transmute(fx, operand); } Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), + Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } StatementKind::StorageLive(_) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 2cb96c4ec0f5..ca8c8dd06ba6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -710,6 +710,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: operand.val, layout, move_annotation: None } } mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), + mir::Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 9c9a921bd62d..564f67e5b1e4 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -646,6 +646,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} + Rvalue::ShallowInitBox(_, _) => {} + Rvalue::UnaryOp(op, operand) => { let ty = operand.ty(self.body, self.tcx); match op { diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 1fbd0cd23405..462254f064cf 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -237,7 +237,8 @@ where Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::UnaryOp(_, operand) - | Rvalue::Cast(_, operand, _) => in_operand::(cx, in_local, operand), + | Rvalue::Cast(_, operand, _) + | Rvalue::ShallowInitBox(operand, _) => in_operand::(cx, in_local, operand), Rvalue::BinaryOp(_, box (lhs, rhs)) => { in_operand::(cx, in_local, lhs) || in_operand::(cx, in_local, rhs) diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index 044b8b091b8d..d4cc21996aea 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -192,6 +192,7 @@ where } mir::Rvalue::Cast(..) + | mir::Rvalue::ShallowInitBox(..) | mir::Rvalue::Use(..) | mir::Rvalue::CopyForDeref(..) | mir::Rvalue::ThreadLocalRef(..) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 3b4f7ed3261a..57ad670c3f56 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -236,7 +236,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { if self.tcx.is_lang_item(def_id, LangItem::PanicDisplay) || self.tcx.is_lang_item(def_id, LangItem::BeginPanic) { - let args = Self::copy_fn_args(args); + let args = self.copy_fn_args(args); // &str or &&str assert!(args.len() == 1); diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 9220fde474e4..1ee2647d5bf7 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -19,8 +19,8 @@ use tracing::{info, instrument, trace}; use super::{ CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, - Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, interp_ok, throw_ub, - throw_ub_custom, + Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok, + throw_ub, throw_ub_custom, }; use crate::enter_trace_span; use crate::interpret::EnteredTraceSpan; @@ -43,22 +43,25 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> { FnArg::InPlace(mplace) => &mplace.layout, } } +} +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. - pub fn copy_fn_arg(&self) -> OpTy<'tcx, Prov> { - match self { + pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> { + match arg { FnArg::Copy(op) => op.clone(), FnArg::InPlace(mplace) => mplace.clone().into(), } } -} -impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Make a copy of the given fn_args. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. - pub fn copy_fn_args(args: &[FnArg<'tcx, M::Provenance>]) -> Vec> { - args.iter().map(|fn_arg| fn_arg.copy_fn_arg()).collect() + pub fn copy_fn_args( + &self, + args: &[FnArg<'tcx, M::Provenance>], + ) -> Vec> { + args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect() } /// Helper function for argument untupling. @@ -316,7 +319,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // We work with a copy of the argument for now; if this is in-place argument passing, we // will later protect the source it comes from. This means the callee cannot observe if we // did in-place of by-copy argument passing, except for pointer equality tests. - let caller_arg_copy = caller_arg.copy_fn_arg(); + let caller_arg_copy = self.copy_fn_arg(caller_arg); if !already_live { let local = callee_arg.as_local().unwrap(); let meta = caller_arg_copy.meta(); @@ -613,7 +616,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if let Some(fallback) = M::call_intrinsic( self, instance, - &Self::copy_fn_args(args), + &self.copy_fn_args(args), destination, target, unwind, @@ -700,7 +703,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // An `InPlace` does nothing here, we keep the original receiver intact. We can't // really pass the argument in-place anyway, and we are constructing a new // `Immediate` receiver. - let mut receiver = args[0].copy_fn_arg(); + let mut receiver = self.copy_fn_arg(&args[0]); let receiver_place = loop { match receiver.layout.ty.kind() { ty::Ref(..) | ty::RawPtr(..) => { @@ -821,50 +824,41 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { with_caller_location: bool, ) -> InterpResult<'tcx> { trace!("init_fn_tail_call: {:#?}", fn_val); + // This is the "canonical" implementation of tails calls, // a pop of the current stack frame, followed by a normal call // which pushes a new stack frame, with the return address from // the popped stack frame. // - // Note that we cannot use `return_from_current_stack_frame`, - // as that "executes" the goto to the return block, but we don't want to, + // Note that we are using `pop_stack_frame_raw` and not `return_from_current_stack_frame`, + // as the latter "executes" the goto to the return block, but we don't want to, // only the tail called function should return to the current return block. + let StackPopInfo { return_action, return_cont, return_place } = + self.pop_stack_frame_raw(false, |_this, _return_place| { + // This function's return value is just discarded, the tail-callee will fill in the return place instead. + interp_ok(()) + })?; - // The arguments need to all be copied since the current stack frame will be removed - // before the callee even starts executing. - // FIXME(explicit_tail_calls,#144855): does this match what codegen does? - let args = args.iter().map(|fn_arg| FnArg::Copy(fn_arg.copy_fn_arg())).collect::>(); - // Remove the frame from the stack. - let frame = self.pop_stack_frame_raw()?; - // Remember where this frame would have returned to. - let ReturnContinuation::Goto { ret, unwind } = frame.return_cont() else { - bug!("can't tailcall as root of the stack"); + assert_eq!(return_action, ReturnAction::Normal); + + // Take the "stack pop cleanup" info, and use that to initiate the next call. + let ReturnContinuation::Goto { ret, unwind } = return_cont else { + bug!("can't tailcall as root"); }; - // There's no return value to deal with! Instead, we forward the old return place - // to the new function. + // FIXME(explicit_tail_calls): // we should check if both caller&callee can/n't unwind, // see - // Now push the new stack frame. self.init_fn_call( fn_val, (caller_abi, caller_fn_abi), - &*args, + args, with_caller_location, - frame.return_place(), + &return_place, ret, unwind, - )?; - - // Finally, clear the local variables. Has to be done after pushing to support - // non-scalar arguments. - // FIXME(explicit_tail_calls,#144855): revisit this once codegen supports indirect - // arguments, to ensure the semantics are compatible. - let return_action = self.cleanup_stack_frame(/* unwinding */ false, frame)?; - assert_eq!(return_action, ReturnAction::Normal); - - interp_ok(()) + ) } pub(super) fn init_drop_in_place_call( @@ -959,18 +953,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // local's value out. let return_op = self.local_to_op(mir::RETURN_PLACE, None).expect("return place should always be live"); - // Remove the frame from the stack. - let frame = self.pop_stack_frame_raw()?; - // Copy the return value and remember the return continuation. - if !unwinding { - self.copy_op_allow_transmute(&return_op, frame.return_place())?; - trace!("return value: {:?}", self.dump_place(frame.return_place())); - } - let return_cont = frame.return_cont(); - // Finish popping the stack frame. - let return_action = self.cleanup_stack_frame(unwinding, frame)?; - // Jump to the next block. - match return_action { + // Do the actual pop + copy. + let stack_pop_info = self.pop_stack_frame_raw(unwinding, |this, return_place| { + this.copy_op_allow_transmute(&return_op, return_place)?; + trace!("return value: {:?}", this.dump_place(return_place)); + interp_ok(()) + })?; + + match stack_pop_info.return_action { ReturnAction::Normal => {} ReturnAction::NoJump => { // The hook already did everything. @@ -988,7 +978,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Normal return, figure out where to jump. if unwinding { // Follow the unwind edge. - match return_cont { + match stack_pop_info.return_cont { ReturnContinuation::Goto { unwind, .. } => { // This must be the very last thing that happens, since it can in fact push a new stack frame. self.unwind_to_block(unwind) @@ -999,7 +989,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } else { // Follow the normal return edge. - match return_cont { + match stack_pop_info.return_cont { ReturnContinuation::Goto { ret, .. } => self.return_to_block(ret), ReturnContinuation::Stop { .. } => { assert!( diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index c8ffc0ed208a..2f365ec77b33 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -36,7 +36,7 @@ pub use self::operand::{ImmTy, Immediate, OpTy}; pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; use self::place::{MemPlace, Place}; pub use self::projection::{OffsetMode, Projectable}; -pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation}; +pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo}; pub use self::util::EnteredTraceSpan; pub(crate) use self::util::create_static_alloc; pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking}; diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index a55bea60cd6e..1b8af1c44277 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -81,7 +81,7 @@ pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> { /// and its layout in the caller. This place is to be interpreted relative to the /// *caller's* stack frame. We use a `PlaceTy` instead of an `MPlaceTy` since this /// avoids having to move *all* return places into Miri's memory. - return_place: PlaceTy<'tcx, Prov>, + pub return_place: PlaceTy<'tcx, Prov>, /// The list of locals for this stack frame, stored in order as /// `[return_ptr, arguments..., variables..., temporaries...]`. @@ -127,6 +127,19 @@ pub enum ReturnContinuation { Stop { cleanup: bool }, } +/// Return type of [`InterpCx::pop_stack_frame_raw`]. +pub struct StackPopInfo<'tcx, Prov: Provenance> { + /// Additional information about the action to be performed when returning from the popped + /// stack frame. + pub return_action: ReturnAction, + + /// [`return_cont`](Frame::return_cont) of the popped stack frame. + pub return_cont: ReturnContinuation, + + /// [`return_place`](Frame::return_place) of the popped stack frame. + pub return_place: PlaceTy<'tcx, Prov>, +} + /// State of a local variable including a memoized layout #[derive(Clone)] pub struct LocalState<'tcx, Prov: Provenance = CtfeProvenance> { @@ -279,14 +292,6 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> { self.instance } - pub fn return_place(&self) -> &PlaceTy<'tcx, Prov> { - &self.return_place - } - - pub fn return_cont(&self) -> ReturnContinuation { - self.return_cont - } - /// Return the `SourceInfo` of the current instruction. pub fn current_source_info(&self) -> Option<&mir::SourceInfo> { self.loc.left().map(|loc| self.body.source_info(loc)) @@ -412,26 +417,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } - /// Low-level helper that pops a stack frame from the stack without any cleanup. - /// This invokes `before_stack_pop`. - /// After calling this function, you need to deal with the return value, and then - /// invoke `cleanup_stack_frame`. + /// Low-level helper that pops a stack frame from the stack and returns some information about + /// it. + /// + /// This also deallocates locals, if necessary. + /// `copy_ret_val` gets called after the frame has been taken from the stack but before the locals have been deallocated. + /// + /// [`M::before_stack_pop`] and [`M::after_stack_pop`] are called by this function + /// automatically. + /// + /// The high-level version of this is `return_from_current_stack_frame`. + /// + /// [`M::before_stack_pop`]: Machine::before_stack_pop + /// [`M::after_stack_pop`]: Machine::after_stack_pop pub(super) fn pop_stack_frame_raw( &mut self, - ) -> InterpResult<'tcx, Frame<'tcx, M::Provenance, M::FrameExtra>> { + unwinding: bool, + copy_ret_val: impl FnOnce(&mut Self, &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx>, + ) -> InterpResult<'tcx, StackPopInfo<'tcx, M::Provenance>> { M::before_stack_pop(self)?; let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); - interp_ok(frame) - } - /// Deallocate local variables in the stack frame, and invoke `after_stack_pop`. - pub(super) fn cleanup_stack_frame( - &mut self, - unwinding: bool, - frame: Frame<'tcx, M::Provenance, M::FrameExtra>, - ) -> InterpResult<'tcx, ReturnAction> { + // Copy return value (unless we are unwinding). + if !unwinding { + copy_ret_val(self, &frame.return_place)?; + } + let return_cont = frame.return_cont; + let return_place = frame.return_place.clone(); // Cleanup: deallocate locals. // Usually we want to clean up (deallocate locals), but in a few rare cases we don't. @@ -441,7 +455,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ReturnContinuation::Stop { cleanup, .. } => cleanup, }; - if cleanup { + let return_action = if cleanup { for local in &frame.locals { self.deallocate_local(local.value)?; } @@ -452,11 +466,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Call the machine hook, which determines the next steps. let return_action = M::after_stack_pop(self, frame, unwinding)?; assert_ne!(return_action, ReturnAction::NoCleanup); - interp_ok(return_action) + return_action } else { // We also skip the machine hook when there's no cleanup. This not a real "pop" anyway. - interp_ok(ReturnAction::NoCleanup) - } + ReturnAction::NoCleanup + }; + + interp_ok(StackPopInfo { return_action, return_cont, return_place }) } /// In the current stack frame, mark all locals as live that are not arguments and don't have @@ -639,7 +655,7 @@ impl<'a, 'tcx: 'a, M: Machine<'tcx>> InterpCx<'tcx, M> { let (_idx, callee_abi) = callee_abis.next().unwrap(); assert!(self.check_argument_compat(caller_abi, callee_abi)?); // FIXME: do we have to worry about in-place argument passing? - let op = fn_arg.copy_fn_arg(); + let op = self.copy_fn_arg(fn_arg); let mplace = self.allocate(op.layout, MemoryKind::Stack)?; self.copy_op(&op, &mplace)?; diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 0dd17f109be3..4aa9030cfe61 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -249,6 +249,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_immediate(*val, &dest)?; } + ShallowInitBox(ref operand, _) => { + let src = self.eval_operand(operand, None)?; + let v = self.read_immediate(&src)?; + self.write_immediate(*v, &dest)?; + } + Cast(cast_kind, ref operand, cast_ty) => { let src = self.eval_operand(operand, None)?; let cast_ty = diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 6fc8d5ef8f96..5d8ae42f5ecc 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -647,8 +647,13 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { } } else { // This is not CTFE, so it's Miri with recursive checking. - // FIXME: should we also `UnsafeCell` behind shared references? Currently that is not + // FIXME: we do *not* check behind boxes, since creating a new box first creates it uninitialized + // and then puts the value in there, so briefly we have a box with uninit contents. + // FIXME: should we also skip `UnsafeCell` behind shared references? Currently that is not // needed since validation reads bypass Stacked Borrows and data race checks. + if matches!(ptr_kind, PointerKind::Box) { + return interp_ok(()); + } } let path = &self.path; ref_tracking.track(place, || { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 476be94efd9e..5efaea44b3b9 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -2,11 +2,12 @@ use std::any::Any; use std::default::Default; use std::iter; use std::path::Component::Prefix; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::Arc; use rustc_ast::attr::MarkedAttrs; +use rustc_ast::token::MetaVarKind; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind, Safety}; @@ -21,14 +22,14 @@ use rustc_hir::limit::Limit; use rustc_hir::{Stability, find_attr}; use rustc_lint_defs::RegisteredTools; use rustc_parse::MACRO_ARGUMENTS; -use rustc_parse::parser::Parser; +use rustc_parse::parser::{AllowConstBlockItems, ForceCollect, Parser}; use rustc_session::Session; use rustc_session::parse::ParseSess; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; use rustc_span::source_map::SourceMap; -use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; +use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; @@ -1420,3 +1421,80 @@ pub fn resolve_path(sess: &Session, path: impl Into, span: Span) -> PRe } } } + +/// If this item looks like a specific enums from `rental`, emit a fatal error. +/// See #73345 and #83125 for more details. +/// FIXME(#73933): Remove this eventually. +fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) { + if let ast::ItemKind::Enum(ident, _, enum_def) = &item.kind + && ident.name == sym::ProceduralMasqueradeDummyType + && let [variant] = &*enum_def.variants + && variant.ident.name == sym::Input + && let FileName::Real(real) = psess.source_map().span_to_filename(ident.span) + && let Some(c) = real + .local_path() + .unwrap_or(Path::new("")) + .components() + .flat_map(|c| c.as_os_str().to_str()) + .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental")) + { + let crate_matches = if c.starts_with("allsorts-rental") { + true + } else { + let mut version = c.trim_start_matches("rental-").split('.'); + version.next() == Some("0") + && version.next() == Some("5") + && version.next().and_then(|c| c.parse::().ok()).is_some_and(|v| v < 6) + }; + + if crate_matches { + psess.dcx().emit_fatal(errors::ProcMacroBackCompat { + crate_name: "rental".to_string(), + fixed_version: "0.5.6".to_string(), + }); + } + } +} + +pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, psess: &ParseSess) { + let item = match ann { + Annotatable::Item(item) => item, + Annotatable::Stmt(stmt) => match &stmt.kind { + ast::StmtKind::Item(item) => item, + _ => return, + }, + _ => return, + }; + pretty_printing_compatibility_hack(item, psess) +} + +pub(crate) fn stream_pretty_printing_compatibility_hack( + kind: MetaVarKind, + stream: &TokenStream, + psess: &ParseSess, +) { + let item = match kind { + MetaVarKind::Item => { + let mut parser = Parser::new(psess, stream.clone(), None); + // No need to collect tokens for this simple check. + parser + .parse_item(ForceCollect::No, AllowConstBlockItems::No) + .expect("failed to reparse item") + .expect("an actual item") + } + MetaVarKind::Stmt => { + let mut parser = Parser::new(psess, stream.clone(), None); + // No need to collect tokens for this simple check. + let stmt = parser + .parse_stmt(ForceCollect::No) + .expect("failed to reparse") + .expect("an actual stmt"); + match &stmt.kind { + ast::StmtKind::Item(item) => item.clone(), + _ => return, + } + } + _ => return, + }; + pretty_printing_compatibility_hack(&item, psess) +} diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index c7b0e0d211a4..b6fcc13321ee 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -446,6 +446,18 @@ pub(crate) struct GlobDelegationTraitlessQpath { pub span: Span, } +// This used to be the `proc_macro_back_compat` lint (#83125). It was later +// turned into a hard error. +#[derive(Diagnostic)] +#[diag("using an old version of `{$crate_name}`")] +#[note( + "older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives" +)] +pub(crate) struct ProcMacroBackCompat { + pub crate_name: String, + pub fixed_version: String, +} + pub(crate) use metavar_exprs::*; mod metavar_exprs { use super::*; diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index a892b21d7622..e67855700813 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -105,6 +105,11 @@ impl MultiItemModifier for DeriveProcMacro { // (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`) let is_stmt = matches!(item, Annotatable::Stmt(..)); + // We used to have an alternative behaviour for crates that needed it. + // We had a lint for a long time, but now we just emit a hard error. + // Eventually we might remove the special case hard error check + // altogether. See #73345. + crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.psess); let input = item.to_tokens(); let invoc_id = ecx.current_expansion.id; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 1da14ce0155d..947b8a6e3e5e 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -103,8 +103,8 @@ impl ToInternal for LitKind { } } -impl FromInternal for Vec> { - fn from_internal(stream: TokenStream) -> Self { +impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec> { + fn from_internal((stream, rustc): (TokenStream, &mut Rustc<'_, '_>)) -> Self { use rustc_ast::token::*; // Estimate the capacity as `stream.len()` rounded up to the next power @@ -115,6 +115,22 @@ impl FromInternal for Vec> { while let Some(tree) = iter.next() { let (Token { kind, span }, joint) = match tree.clone() { tokenstream::TokenTree::Delimited(span, _, mut delim, mut stream) => { + // We used to have an alternative behaviour for crates that + // needed it: a hack used to pass AST fragments to + // attribute and derive macros as a single nonterminal + // token instead of a token stream. Such token needs to be + // "unwrapped" and not represented as a delimited group. We + // had a lint for a long time, but now we just emit a hard + // error. Eventually we might remove the special case hard + // error check altogether. See #73345. + if let Delimiter::Invisible(InvisibleOrigin::MetaVar(kind)) = delim { + crate::base::stream_pretty_printing_compatibility_hack( + kind, + &stream, + rustc.psess(), + ); + } + // In `mk_delimited` we avoid nesting invisible delimited // of the same `MetaVarKind`. Here we do the same but // ignore the `MetaVarKind` because it is discarded when we @@ -671,7 +687,7 @@ impl server::Server for Rustc<'_, '_> { &mut self, stream: Self::TokenStream, ) -> Vec> { - FromInternal::from_internal(stream) + FromInternal::from_internal((stream, self)) } fn span_debug(&mut self, span: Self::Span) -> String { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index db8f459ef045..2c2dae0fef52 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1208,7 +1208,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_intrinsic_const_stable_indirect, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail", ), - rustc_attr!( + gated!( rustc_allow_const_fn_unstable, Normal, template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 433ccbecd7dd..b810cd0db8cd 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -287,6 +287,10 @@ declare_features! ( (internal, panic_runtime, "1.10.0", Some(32837)), /// Allows using pattern types. (internal, pattern_types, "1.79.0", Some(123646)), + /// Allows using `#[rustc_allow_const_fn_unstable]`. + /// This is an attribute on `const fn` for the same + /// purpose as `#[allow_internal_unstable]`. + (internal, rustc_allow_const_fn_unstable, "1.49.0", Some(69399)), /// Allows using compiler's own crates. (unstable, rustc_private, "1.0.0", Some(27812)), /// Allows using internal rustdoc features like `doc(keyword)`. @@ -489,7 +493,7 @@ declare_features! ( /// Allows the use of `#[ffi_pure]` on foreign functions. (unstable, ffi_pure, "1.45.0", Some(58329)), /// Allows marking trait functions as `final` to prevent overriding impls - (unstable, final_associated_functions, "CURRENT_RUSTC_VERSION", Some(131179)), + (unstable, final_associated_functions, "CURRENT_RUSTC_VERSION", Some(1)), /// Controlling the behavior of fmt::Debug (unstable, fmt_debug, "1.82.0", Some(129709)), /// Allows using `#[align(...)]` on function items diff --git a/compiler/rustc_incremental/src/persist/clean.rs b/compiler/rustc_incremental/src/persist/clean.rs index 9e974e432c39..0067b38fadc7 100644 --- a/compiler/rustc_incremental/src/persist/clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs @@ -322,7 +322,7 @@ impl<'tcx> CleanVisitor<'tcx> { if let Some(def_id) = dep_node.extract_def_id(self.tcx) { format!("{:?}({})", dep_node.kind, self.tcx.def_path_str(def_id)) } else { - format!("{:?}({:?})", dep_node.kind, dep_node.key_fingerprint) + format!("{:?}({:?})", dep_node.kind, dep_node.hash) } } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 52faebcba025..578277bce593 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -1,10 +1,10 @@ //! This module defines the [`DepNode`] type which the compiler uses to represent //! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which //! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.) -//! and a "key fingerprint", a 128-bit hash value, the exact meaning of which -//! depends on the node's `DepKind`. Together, the kind and the key fingerprint +//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which +//! depends on the node's `DepKind`. Together, the kind and the fingerprint //! fully identify a dependency node, even across multiple compilation sessions. -//! In other words, the value of the key fingerprint does not depend on anything +//! In other words, the value of the fingerprint does not depend on anything //! that is specific to a given compilation session, like an unpredictable //! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a //! pointer. The concept behind this could be compared to how git commit hashes @@ -41,9 +41,17 @@ //! `DepNode`s could represent global concepts with only one value. //! * Whether it is possible, in principle, to reconstruct a query key from a //! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter, -//! in which case it is possible to map the node's key fingerprint back to the +//! in which case it is possible to map the node's fingerprint back to the //! `DefId` it was computed from. In other cases, too much information gets -//! lost when computing a key fingerprint. +//! lost during fingerprint computation. +//! +//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with +//! `DepNode::new()`, ensure that only valid `DepNode` instances can be +//! constructed. For example, the API does not allow for constructing +//! parameterless `DepNode`s with anything other than a zeroed out fingerprint. +//! More generally speaking, it relieves the user of the `DepNode` API of +//! having to know how to compute the expected fingerprint for a given set of +//! node parameters. //! //! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html @@ -57,7 +65,7 @@ use rustc_hir::definitions::DefPathHash; use rustc_macros::{Decodable, Encodable}; use rustc_span::Symbol; -use super::{KeyFingerprintStyle, SerializedDepNodeIndex}; +use super::{FingerprintStyle, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; use crate::mir::mono::MonoItem; use crate::ty::{TyCtxt, tls}; @@ -117,20 +125,10 @@ impl fmt::Debug for DepKind { } } -/// Combination of a [`DepKind`] and a key fingerprint that uniquely identifies -/// a node in the dep graph. #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct DepNode { pub kind: DepKind, - - /// This is _typically_ a hash of the query key, but sometimes not. - /// - /// For example, `anon` nodes have a fingerprint that is derived from their - /// dependencies instead of a key. - /// - /// In some cases the key value can be reconstructed from this fingerprint; - /// see [`KeyFingerprintStyle`]. - pub key_fingerprint: PackedFingerprint, + pub hash: PackedFingerprint, } impl DepNode { @@ -138,23 +136,24 @@ impl DepNode { /// that the DepNode corresponding to the given DepKind actually /// does not require any parameters. pub fn new_no_params<'tcx>(tcx: TyCtxt<'tcx>, kind: DepKind) -> DepNode { - debug_assert_eq!(tcx.key_fingerprint_style(kind), KeyFingerprintStyle::Unit); - DepNode { kind, key_fingerprint: Fingerprint::ZERO.into() } + debug_assert_eq!(tcx.fingerprint_style(kind), FingerprintStyle::Unit); + DepNode { kind, hash: Fingerprint::ZERO.into() } } - pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, key: &Key) -> DepNode + pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, arg: &Key) -> DepNode where Key: DepNodeKey<'tcx>, { - let dep_node = DepNode { kind, key_fingerprint: key.to_fingerprint(tcx).into() }; + let hash = arg.to_fingerprint(tcx); + let dep_node = DepNode { kind, hash: hash.into() }; #[cfg(debug_assertions)] { - if !tcx.key_fingerprint_style(kind).reconstructible() + if !tcx.fingerprint_style(kind).reconstructible() && (tcx.sess.opts.unstable_opts.incremental_info || tcx.sess.opts.unstable_opts.query_dep_graph) { - tcx.dep_graph.register_dep_node_debug_str(dep_node, || key.to_debug_str(tcx)); + tcx.dep_graph.register_dep_node_debug_str(dep_node, || arg.to_debug_str(tcx)); } } @@ -169,8 +168,8 @@ impl DepNode { def_path_hash: DefPathHash, kind: DepKind, ) -> Self { - debug_assert!(tcx.key_fingerprint_style(kind) == KeyFingerprintStyle::DefPathHash); - DepNode { kind, key_fingerprint: def_path_hash.0.into() } + debug_assert!(tcx.fingerprint_style(kind) == FingerprintStyle::DefPathHash); + DepNode { kind, hash: def_path_hash.0.into() } } } @@ -185,10 +184,10 @@ impl fmt::Debug for DepNode { } else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) { write!(f, "{s}")?; } else { - write!(f, "{}", self.key_fingerprint)?; + write!(f, "{}", self.hash)?; } } else { - write!(f, "{}", self.key_fingerprint)?; + write!(f, "{}", self.hash)?; } Ok(()) })?; @@ -199,7 +198,7 @@ impl fmt::Debug for DepNode { /// Trait for query keys as seen by dependency-node tracking. pub trait DepNodeKey<'tcx>: fmt::Debug + Sized { - fn key_fingerprint_style() -> KeyFingerprintStyle; + fn fingerprint_style() -> FingerprintStyle; /// This method turns a query key into an opaque `Fingerprint` to be used /// in `DepNode`. @@ -213,7 +212,7 @@ pub trait DepNodeKey<'tcx>: fmt::Debug + Sized { /// `fingerprint_style()` is not `FingerprintStyle::Opaque`. /// It is always valid to return `None` here, in which case incremental /// compilation will treat the query as having changed instead of forcing it. - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option; + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option; } // Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere. @@ -222,8 +221,8 @@ where T: for<'a> HashStable> + fmt::Debug, { #[inline(always)] - default fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::Opaque + default fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Opaque } #[inline(always)] @@ -244,7 +243,7 @@ where } #[inline(always)] - default fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option { + default fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option { None } } @@ -265,11 +264,10 @@ pub struct DepKindVTable<'tcx> { /// cached within one compiler invocation. pub is_eval_always: bool, - /// Indicates whether and how a query key can be reconstructed from the - /// key fingerprint of a dep node with this [`DepKind`]. + /// Indicates whether and how the query key can be recovered from its hashed fingerprint. /// /// The [`DepNodeKey`] trait determines the fingerprint style for each key type. - pub key_fingerprint_style: KeyFingerprintStyle, + pub fingerprint_style: FingerprintStyle, /// The red/green evaluation system will try to mark a specific DepNode in the /// dependency graph as green by recursively trying to mark the dependencies of @@ -281,7 +279,7 @@ pub struct DepKindVTable<'tcx> { /// `force_from_dep_node()` implements. /// /// In the general case, a `DepNode` consists of a `DepKind` and an opaque - /// "key fingerprint" that will uniquely identify the node. This key fingerprint + /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint /// is usually constructed by computing a stable hash of the query-key that the /// `DepNode` corresponds to. Consequently, it is not in general possible to go /// back from hash to query-key (since hash functions are not reversible). For @@ -295,7 +293,7 @@ pub struct DepKindVTable<'tcx> { /// Now, if `force_from_dep_node()` would always fail, it would be pretty useless. /// Fortunately, we can use some contextual information that will allow us to /// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we - /// enforce by construction that the key fingerprint of certain `DepNode`s is a + /// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a /// valid `DefPathHash`. Since we also always build a huge table that maps every /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have /// everything we need to re-run the query. @@ -303,7 +301,7 @@ pub struct DepKindVTable<'tcx> { /// Take the `mir_promoted` query as an example. Like many other queries, it /// just has a single parameter: the `DefId` of the item it will compute the /// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode` - /// with kind `mir_promoted`, we know that the key fingerprint of the `DepNode` + /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` /// is actually a `DefPathHash`, and can therefore just look up the corresponding /// `DefId` in `tcx.def_path_hash_to_def_id`. pub force_from_dep_node: Option< @@ -474,8 +472,8 @@ impl DepNode { /// refers to something from the previous compilation session that /// has been removed. pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option { - if tcx.key_fingerprint_style(self.kind) == KeyFingerprintStyle::DefPathHash { - tcx.def_path_hash_to_def_id(DefPathHash(self.key_fingerprint.into())) + if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash { + tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into())) } else { None } @@ -488,10 +486,10 @@ impl DepNode { ) -> Result { let kind = dep_kind_from_label_string(label)?; - match tcx.key_fingerprint_style(kind) { - KeyFingerprintStyle::Opaque | KeyFingerprintStyle::HirId => Err(()), - KeyFingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)), - KeyFingerprintStyle::DefPathHash => { + match tcx.fingerprint_style(kind) { + FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()), + FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)), + FingerprintStyle::DefPathHash => { Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind)) } } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs index c488a9471237..92c135a6e7fd 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs @@ -3,13 +3,13 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, use rustc_hir::definitions::DefPathHash; use rustc_hir::{HirId, ItemLocalId, OwnerId}; -use crate::dep_graph::{DepNode, DepNodeKey, KeyFingerprintStyle}; +use crate::dep_graph::{DepNode, DepNodeKey, FingerprintStyle}; use crate::ty::TyCtxt; impl<'tcx> DepNodeKey<'tcx> for () { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::Unit + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Unit } #[inline(always)] @@ -18,15 +18,15 @@ impl<'tcx> DepNodeKey<'tcx> for () { } #[inline(always)] - fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option { + fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option { Some(()) } } impl<'tcx> DepNodeKey<'tcx> for DefId { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::DefPathHash + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } #[inline(always)] @@ -40,15 +40,15 @@ impl<'tcx> DepNodeKey<'tcx> for DefId { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { dep_node.extract_def_id(tcx) } } impl<'tcx> DepNodeKey<'tcx> for LocalDefId { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::DefPathHash + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } #[inline(always)] @@ -62,15 +62,15 @@ impl<'tcx> DepNodeKey<'tcx> for LocalDefId { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { dep_node.extract_def_id(tcx).map(|id| id.expect_local()) } } impl<'tcx> DepNodeKey<'tcx> for OwnerId { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::DefPathHash + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } #[inline(always)] @@ -84,15 +84,15 @@ impl<'tcx> DepNodeKey<'tcx> for OwnerId { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() }) } } impl<'tcx> DepNodeKey<'tcx> for CrateNum { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::DefPathHash + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } #[inline(always)] @@ -107,15 +107,15 @@ impl<'tcx> DepNodeKey<'tcx> for CrateNum { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { dep_node.extract_def_id(tcx).map(|id| id.krate) } } impl<'tcx> DepNodeKey<'tcx> for (DefId, DefId) { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::Opaque + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Opaque } // We actually would not need to specialize the implementation of this @@ -141,8 +141,8 @@ impl<'tcx> DepNodeKey<'tcx> for (DefId, DefId) { impl<'tcx> DepNodeKey<'tcx> for HirId { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::HirId + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::HirId } // We actually would not need to specialize the implementation of this @@ -166,9 +166,9 @@ impl<'tcx> DepNodeKey<'tcx> for HirId { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - if tcx.key_fingerprint_style(dep_node.kind) == KeyFingerprintStyle::HirId { - let (local_hash, local_id) = Fingerprint::from(dep_node.key_fingerprint).split(); + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId { + let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split(); let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash); let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local(); let local_id = local_id @@ -184,8 +184,8 @@ impl<'tcx> DepNodeKey<'tcx> for HirId { impl<'tcx> DepNodeKey<'tcx> for ModDefId { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::DefPathHash + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } #[inline(always)] @@ -199,15 +199,15 @@ impl<'tcx> DepNodeKey<'tcx> for ModDefId { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - DefId::try_recover_key(tcx, dep_node).map(ModDefId::new_unchecked) + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked) } } impl<'tcx> DepNodeKey<'tcx> for LocalModDefId { #[inline(always)] - fn key_fingerprint_style() -> KeyFingerprintStyle { - KeyFingerprintStyle::DefPathHash + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } #[inline(always)] @@ -221,7 +221,7 @@ impl<'tcx> DepNodeKey<'tcx> for LocalModDefId { } #[inline(always)] - fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - LocalDefId::try_recover_key(tcx, dep_node).map(LocalModDefId::new_unchecked) + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked) } } diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index f5787716a94e..5257ec4abef2 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -142,17 +142,15 @@ impl DepGraph { // Instantiate a node with zero dependencies only once for anonymous queries. let _green_node_index = current.alloc_new_node( - DepNode { kind: DepKind::ANON_ZERO_DEPS, key_fingerprint: current.anon_id_seed.into() }, + DepNode { kind: DepKind::ANON_ZERO_DEPS, hash: current.anon_id_seed.into() }, EdgesVec::new(), Fingerprint::ZERO, ); assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_ZERO_DEPS_ANON_NODE); - // Create a single always-red node, with no dependencies of its own. - // Other nodes can use the always-red node as a fake dependency, to - // ensure that their dependency list will never be all-green. + // Instantiate a dependy-less red node only once for anonymous queries. let red_node_index = current.alloc_new_node( - DepNode { kind: DepKind::RED, key_fingerprint: Fingerprint::ZERO.into() }, + DepNode { kind: DepKind::RED, hash: Fingerprint::ZERO.into() }, EdgesVec::new(), Fingerprint::ZERO, ); @@ -420,7 +418,7 @@ impl DepGraphData { // Fingerprint::combine() is faster than sending Fingerprint // through the StableHasher (at least as long as StableHasher // is so slow). - key_fingerprint: self.current.anon_id_seed.combine(hasher.finish()).into(), + hash: self.current.anon_id_seed.combine(hasher.finish()).into(), }; // The DepNodes generated by the process above are not unique. 2 queries could @@ -587,7 +585,7 @@ impl DepGraph { data.current.record_edge( dep_node_index, node, - data.prev_value_fingerprint_of(prev_index), + data.prev_fingerprint_of(prev_index), ); } @@ -660,8 +658,8 @@ impl DepGraphData { } #[inline] - pub fn prev_value_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint { - self.previous.value_fingerprint_for_index(prev_index) + pub fn prev_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint { + self.previous.fingerprint_by_index(prev_index) } #[inline] @@ -681,7 +679,7 @@ impl DepGraphData { let dep_node_index = self.current.encoder.send_new( DepNode { kind: DepKind::SIDE_EFFECT, - key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO), + hash: PackedFingerprint::from(Fingerprint::ZERO), }, Fingerprint::ZERO, // We want the side effect node to always be red so it will be forced and emit the @@ -714,7 +712,7 @@ impl DepGraphData { &self.colors, DepNode { kind: DepKind::SIDE_EFFECT, - key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO), + hash: PackedFingerprint::from(Fingerprint::ZERO), }, Fingerprint::ZERO, std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(), @@ -729,12 +727,12 @@ impl DepGraphData { &self, key: DepNode, edges: EdgesVec, - value_fingerprint: Option, + fingerprint: Option, ) -> DepNodeIndex { if let Some(prev_index) = self.previous.node_to_index_opt(&key) { // Determine the color and index of the new `DepNode`. - let is_green = if let Some(value_fingerprint) = value_fingerprint { - if value_fingerprint == self.previous.value_fingerprint_for_index(prev_index) { + let is_green = if let Some(fingerprint) = fingerprint { + if fingerprint == self.previous.fingerprint_by_index(prev_index) { // This is a green node: it existed in the previous compilation, // its query was re-executed, and it has the same result as before. true @@ -751,22 +749,22 @@ impl DepGraphData { false }; - let value_fingerprint = value_fingerprint.unwrap_or(Fingerprint::ZERO); + let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO); let dep_node_index = self.current.encoder.send_and_color( prev_index, &self.colors, key, - value_fingerprint, + fingerprint, edges, is_green, ); - self.current.record_node(dep_node_index, key, value_fingerprint); + self.current.record_node(dep_node_index, key, fingerprint); dep_node_index } else { - self.current.alloc_new_node(key, edges, value_fingerprint.unwrap_or(Fingerprint::ZERO)) + self.current.alloc_new_node(key, edges, fingerprint.unwrap_or(Fingerprint::ZERO)) } } @@ -783,7 +781,7 @@ impl DepGraphData { self.current.record_edge( dep_node_index, *self.previous.index_to_node(prev_index), - self.previous.value_fingerprint_for_index(prev_index), + self.previous.fingerprint_by_index(prev_index), ); } @@ -927,7 +925,7 @@ impl DepGraphData { if !tcx.is_eval_always(dep_dep_node.kind) { debug!( "state of dependency {:?} ({}) is unknown, trying to mark it green", - dep_dep_node, dep_dep_node.key_fingerprint, + dep_dep_node, dep_dep_node.hash, ); let node_index = self.try_mark_previous_green(tcx, parent_dep_node_index, Some(frame)); @@ -1156,10 +1154,10 @@ pub(super) struct CurrentDepGraph { encoder: GraphEncoder, anon_node_to_index: ShardedHashMap, - /// This is used to verify that value fingerprints do not change between the - /// creation of a node and its recomputation. + /// This is used to verify that fingerprints do not change between the creation of a node + /// and its recomputation. #[cfg(debug_assertions)] - value_fingerprints: Lock>>, + fingerprints: Lock>>, /// Used to trap when a specific edge is added to the graph. /// This is used for debug purposes and is only active with `debug_assertions`. @@ -1226,7 +1224,7 @@ impl CurrentDepGraph { #[cfg(debug_assertions)] forbidden_edge, #[cfg(debug_assertions)] - value_fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)), + fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)), nodes_in_current_session: new_node_dbg.then(|| { Lock::new(FxHashMap::with_capacity_and_hasher( new_node_count_estimate, @@ -1239,20 +1237,12 @@ impl CurrentDepGraph { } #[cfg(debug_assertions)] - fn record_edge( - &self, - dep_node_index: DepNodeIndex, - key: DepNode, - value_fingerprint: Fingerprint, - ) { + fn record_edge(&self, dep_node_index: DepNodeIndex, key: DepNode, fingerprint: Fingerprint) { if let Some(forbidden_edge) = &self.forbidden_edge { forbidden_edge.index_to_node.lock().insert(dep_node_index, key); } - let prior_value_fingerprint = *self - .value_fingerprints - .lock() - .get_or_insert_with(dep_node_index, || value_fingerprint); - assert_eq!(prior_value_fingerprint, value_fingerprint, "Unstable fingerprints for {key:?}"); + let previous = *self.fingerprints.lock().get_or_insert_with(dep_node_index, || fingerprint); + assert_eq!(previous, fingerprint, "Unstable fingerprints for {:?}", key); } #[inline(always)] @@ -1260,10 +1250,10 @@ impl CurrentDepGraph { &self, dep_node_index: DepNodeIndex, key: DepNode, - _value_fingerprint: Fingerprint, + _current_fingerprint: Fingerprint, ) { #[cfg(debug_assertions)] - self.record_edge(dep_node_index, key, _value_fingerprint); + self.record_edge(dep_node_index, key, _current_fingerprint); if let Some(ref nodes_in_current_session) = self.nodes_in_current_session { outline(|| { @@ -1281,11 +1271,11 @@ impl CurrentDepGraph { &self, key: DepNode, edges: EdgesVec, - value_fingerprint: Fingerprint, + current_fingerprint: Fingerprint, ) -> DepNodeIndex { - let dep_node_index = self.encoder.send_new(key, value_fingerprint, edges); + let dep_node_index = self.encoder.send_new(key, current_fingerprint, edges); - self.record_node(dep_node_index, key, value_fingerprint); + self.record_node(dep_node_index, key, current_fingerprint); dep_node_index } diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index dda336fcd0b0..4b1faeb7d209 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -30,7 +30,7 @@ mod serialized; /// This is mainly for determining whether and how we can reconstruct a key /// from the fingerprint. #[derive(Debug, PartialEq, Eq, Copy, Clone)] -pub enum KeyFingerprintStyle { +pub enum FingerprintStyle { /// The fingerprint is actually a DefPathHash. DefPathHash, /// The fingerprint is actually a HirId. @@ -41,14 +41,14 @@ pub enum KeyFingerprintStyle { Opaque, } -impl KeyFingerprintStyle { +impl FingerprintStyle { #[inline] pub const fn reconstructible(self) -> bool { match self { - KeyFingerprintStyle::DefPathHash - | KeyFingerprintStyle::Unit - | KeyFingerprintStyle::HirId => true, - KeyFingerprintStyle::Opaque => false, + FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => { + true + } + FingerprintStyle::Opaque => false, } } } @@ -86,8 +86,8 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline(always)] - pub fn key_fingerprint_style(self, kind: DepKind) -> KeyFingerprintStyle { - self.dep_kind_vtable(kind).key_fingerprint_style + pub fn fingerprint_style(self, kind: DepKind) -> FingerprintStyle { + self.dep_kind_vtable(kind).fingerprint_style } /// Try to force a dep node to execute and see if it's green. diff --git a/compiler/rustc_middle/src/dep_graph/serialized.rs b/compiler/rustc_middle/src/dep_graph/serialized.rs index 4da96c5c9933..dbcd5ea07088 100644 --- a/compiler/rustc_middle/src/dep_graph/serialized.rs +++ b/compiler/rustc_middle/src/dep_graph/serialized.rs @@ -90,13 +90,9 @@ const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2; pub struct SerializedDepGraph { /// The set of all DepNodes in the graph nodes: IndexVec, - /// A value fingerprint associated with each [`DepNode`] in [`Self::nodes`], - /// typically a hash of the value returned by the node's query in the - /// previous incremental-compilation session. - /// - /// Some nodes don't have a meaningful value hash (e.g. queries with `no_hash`), - /// so they store a dummy value here instead (e.g. [`Fingerprint::ZERO`]). - value_fingerprints: IndexVec, + /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to + /// the DepNode at the same index in the nodes vector. + fingerprints: IndexVec, /// For each DepNode, stores the list of edges originating from that /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data, /// which holds the actual DepNodeIndices of the target nodes. @@ -104,8 +100,8 @@ pub struct SerializedDepGraph { /// A flattened list of all edge targets in the graph, stored in the same /// varint encoding that we use on disk. Edge sources are implicit in edge_list_indices. edge_list_data: Vec, - /// For each dep kind, stores a map from key fingerprints back to the index - /// of the corresponding node. This is the inverse of `nodes`. + /// Stores a map from fingerprints to nodes per dep node kind. + /// This is the reciprocal of `nodes`. index: Vec>, /// The number of previous compilation sessions. This is used to generate /// unique anon dep nodes per session. @@ -142,15 +138,12 @@ impl SerializedDepGraph { #[inline] pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { - self.index.get(dep_node.kind.as_usize())?.get(&dep_node.key_fingerprint).copied() + self.index.get(dep_node.kind.as_usize())?.get(&dep_node.hash).cloned() } #[inline] - pub fn value_fingerprint_for_index( - &self, - dep_node_index: SerializedDepNodeIndex, - ) -> Fingerprint { - self.value_fingerprints[dep_node_index] + pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { + self.fingerprints[dep_node_index] } #[inline] @@ -219,13 +212,10 @@ impl SerializedDepGraph { let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position(); let mut nodes = IndexVec::from_elem_n( - DepNode { - kind: DepKind::NULL, - key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO), - }, + DepNode { kind: DepKind::NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) }, node_max, ); - let mut value_fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max); + let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max); let mut edge_list_indices = IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max); @@ -253,7 +243,7 @@ impl SerializedDepGraph { assert!(node_header.node().kind != DepKind::NULL && node.kind == DepKind::NULL); *node = node_header.node(); - value_fingerprints[index] = node_header.value_fingerprint(); + fingerprints[index] = node_header.fingerprint(); // If the length of this node's edge list is small, the length is stored in the header. // If it is not, we fall back to another decoder call. @@ -285,7 +275,7 @@ impl SerializedDepGraph { let session_count = d.read_u64(); for (idx, node) in nodes.iter_enumerated() { - if index[node.kind.as_usize()].insert(node.key_fingerprint, idx).is_some() { + if index[node.kind.as_usize()].insert(node.hash, idx).is_some() { // Empty nodes and side effect nodes can have duplicates if node.kind != DepKind::NULL && node.kind != DepKind::SIDE_EFFECT { let name = node.kind.name(); @@ -301,7 +291,7 @@ impl SerializedDepGraph { Arc::new(SerializedDepGraph { nodes, - value_fingerprints, + fingerprints, edge_list_indices, edge_list_data, index, @@ -313,8 +303,8 @@ impl SerializedDepGraph { /// A packed representation of all the fixed-size fields in a `NodeInfo`. /// /// This stores in one byte array: -/// * The value `Fingerprint` in the `NodeInfo` -/// * The key `Fingerprint` in `DepNode` that is in this `NodeInfo` +/// * The `Fingerprint` in the `NodeInfo` +/// * The `Fingerprint` in `DepNode` that is in this `NodeInfo` /// * The `DepKind`'s discriminant (a u16, but not all bits are used...) /// * The byte width of the encoded edges for this node /// * In whatever bits remain, the length of the edge list for this node, if it fits @@ -333,8 +323,8 @@ struct Unpacked { bytes_per_index: usize, kind: DepKind, index: SerializedDepNodeIndex, - key_fingerprint: PackedFingerprint, - value_fingerprint: Fingerprint, + hash: PackedFingerprint, + fingerprint: Fingerprint, } // Bit fields, where @@ -355,7 +345,7 @@ impl SerializedNodeHeader { fn new( node: &DepNode, index: DepNodeIndex, - value_fingerprint: Fingerprint, + fingerprint: Fingerprint, edge_max_index: u32, edge_count: usize, ) -> Self { @@ -373,19 +363,19 @@ impl SerializedNodeHeader { head |= (edge_count as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS); } - let hash: Fingerprint = node.key_fingerprint.into(); + let hash: Fingerprint = node.hash.into(); // Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong. let mut bytes = [0u8; 38]; bytes[..2].copy_from_slice(&head.to_le_bytes()); bytes[2..6].copy_from_slice(&index.as_u32().to_le_bytes()); bytes[6..22].copy_from_slice(&hash.to_le_bytes()); - bytes[22..].copy_from_slice(&value_fingerprint.to_le_bytes()); + bytes[22..].copy_from_slice(&fingerprint.to_le_bytes()); #[cfg(debug_assertions)] { let res = Self { bytes }; - assert_eq!(value_fingerprint, res.value_fingerprint()); + assert_eq!(fingerprint, res.fingerprint()); assert_eq!(*node, res.node()); if let Some(len) = res.len() { assert_eq!(edge_count, len as usize); @@ -398,8 +388,8 @@ impl SerializedNodeHeader { fn unpack(&self) -> Unpacked { let head = u16::from_le_bytes(self.bytes[..2].try_into().unwrap()); let index = u32::from_le_bytes(self.bytes[2..6].try_into().unwrap()); - let key_fingerprint = self.bytes[6..22].try_into().unwrap(); - let value_fingerprint = self.bytes[22..].try_into().unwrap(); + let hash = self.bytes[6..22].try_into().unwrap(); + let fingerprint = self.bytes[22..].try_into().unwrap(); let kind = head & mask(Self::KIND_BITS) as u16; let bytes_per_index = (head >> Self::KIND_BITS) & mask(Self::WIDTH_BITS) as u16; @@ -410,8 +400,8 @@ impl SerializedNodeHeader { bytes_per_index: bytes_per_index as usize + 1, kind: DepKind::new(kind), index: SerializedDepNodeIndex::from_u32(index), - key_fingerprint: Fingerprint::from_le_bytes(key_fingerprint).into(), - value_fingerprint: Fingerprint::from_le_bytes(value_fingerprint), + hash: Fingerprint::from_le_bytes(hash).into(), + fingerprint: Fingerprint::from_le_bytes(fingerprint), } } @@ -431,14 +421,14 @@ impl SerializedNodeHeader { } #[inline] - fn value_fingerprint(&self) -> Fingerprint { - self.unpack().value_fingerprint + fn fingerprint(&self) -> Fingerprint { + self.unpack().fingerprint } #[inline] fn node(&self) -> DepNode { - let Unpacked { kind, key_fingerprint, .. } = self.unpack(); - DepNode { kind, key_fingerprint } + let Unpacked { kind, hash, .. } = self.unpack(); + DepNode { kind, hash } } #[inline] @@ -453,20 +443,15 @@ impl SerializedNodeHeader { #[derive(Debug)] struct NodeInfo { node: DepNode, - value_fingerprint: Fingerprint, + fingerprint: Fingerprint, edges: EdgesVec, } impl NodeInfo { fn encode(&self, e: &mut MemEncoder, index: DepNodeIndex) { - let NodeInfo { ref node, value_fingerprint, ref edges } = *self; - let header = SerializedNodeHeader::new( - node, - index, - value_fingerprint, - edges.max_index(), - edges.len(), - ); + let NodeInfo { ref node, fingerprint, ref edges } = *self; + let header = + SerializedNodeHeader::new(node, index, fingerprint, edges.max_index(), edges.len()); e.write_array(header.bytes); if header.len().is_none() { @@ -491,7 +476,7 @@ impl NodeInfo { e: &mut MemEncoder, node: &DepNode, index: DepNodeIndex, - value_fingerprint: Fingerprint, + fingerprint: Fingerprint, prev_index: SerializedDepNodeIndex, colors: &DepNodeColorMap, previous: &SerializedDepGraph, @@ -503,8 +488,7 @@ impl NodeInfo { let edge_max = edges.clone().map(|i| colors.current(i).unwrap().as_u32()).max().unwrap_or(0); - let header = - SerializedNodeHeader::new(node, index, value_fingerprint, edge_max, edge_count); + let header = SerializedNodeHeader::new(node, index, fingerprint, edge_max, edge_count); e.write_array(header.bytes); if header.len().is_none() { @@ -692,12 +676,12 @@ impl EncoderState { local: &mut LocalEncoderState, ) { let node = self.previous.index_to_node(prev_index); - let value_fingerprint = self.previous.value_fingerprint_for_index(prev_index); + let fingerprint = self.previous.fingerprint_by_index(prev_index); let edge_count = NodeInfo::encode_promoted( &mut local.encoder, node, index, - value_fingerprint, + fingerprint, prev_index, colors, &self.previous, @@ -873,11 +857,11 @@ impl GraphEncoder { pub(crate) fn send_new( &self, node: DepNode, - value_fingerprint: Fingerprint, + fingerprint: Fingerprint, edges: EdgesVec, ) -> DepNodeIndex { let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph"); - let node = NodeInfo { node, value_fingerprint, edges }; + let node = NodeInfo { node, fingerprint, edges }; let mut local = self.status.local.borrow_mut(); let index = self.status.next_index(&mut *local); self.status.bump_index(&mut *local); @@ -893,12 +877,12 @@ impl GraphEncoder { prev_index: SerializedDepNodeIndex, colors: &DepNodeColorMap, node: DepNode, - value_fingerprint: Fingerprint, + fingerprint: Fingerprint, edges: EdgesVec, is_green: bool, ) -> DepNodeIndex { let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph"); - let node = NodeInfo { node, value_fingerprint, edges }; + let node = NodeInfo { node, fingerprint, edges }; let mut local = self.status.local.borrow_mut(); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index e5fe01781e96..2e6e96b4d8a8 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1237,6 +1237,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { } } + ShallowInitBox(ref place, ref ty) => { + with_no_trimmed_paths!(write!(fmt, "ShallowInitBox({place:?}, {ty})")) + } + WrapUnsafeBinder(ref op, ty) => { with_no_trimmed_paths!(write!(fmt, "wrap_binder!({op:?}; {ty})")) } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 48dcef298d66..b1cb89bd3713 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -747,6 +747,11 @@ impl<'tcx> ConstOperand<'tcx> { /////////////////////////////////////////////////////////////////////////// // Rvalues +pub enum RvalueInitializationState { + Shallow, + Deep, +} + impl<'tcx> Rvalue<'tcx> { /// Returns true if rvalue can be safely removed when the result is unused. #[inline] @@ -781,6 +786,7 @@ impl<'tcx> Rvalue<'tcx> { | Rvalue::UnaryOp(_, _) | Rvalue::Discriminant(_) | Rvalue::Aggregate(_, _) + | Rvalue::ShallowInitBox(_, _) | Rvalue::WrapUnsafeBinder(_, _) => true, } } @@ -827,10 +833,21 @@ impl<'tcx> Rvalue<'tcx> { } AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability), }, + Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty), Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty, Rvalue::WrapUnsafeBinder(_, ty) => ty, } } + + #[inline] + /// Returns `true` if this rvalue is deeply initialized (most rvalues) or + /// whether its only shallowly initialized (`Rvalue::Box`). + pub fn initialization_state(&self) -> RvalueInitializationState { + match *self { + Rvalue::ShallowInitBox(_, _) => RvalueInitializationState::Shallow, + _ => RvalueInitializationState::Deep, + } + } } impl BorrowKind { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 35f67460f51c..6ec874fb15f7 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1458,6 +1458,13 @@ pub enum Rvalue<'tcx> { /// coroutine lowering, `Coroutine` aggregate kinds are disallowed too. Aggregate(Box>, IndexVec>), + /// Transmutes a `*mut u8` into shallow-initialized `Box`. + /// + /// This is different from a normal transmute because dataflow analysis will treat the box as + /// initialized but its content as uninitialized. Like other pointer casts, this in general + /// affects alias analysis. + ShallowInitBox(Operand<'tcx>, Ty<'tcx>), + /// A CopyForDeref is equivalent to a read from a place at the /// codegen level, but is treated specially by drop elaboration. When such a read happens, it /// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 16a8743a6d67..07a36aef4320 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -810,6 +810,11 @@ macro_rules! make_mir_visitor { } } + Rvalue::ShallowInitBox(operand, ty) => { + self.visit_operand(operand, location); + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } + Rvalue::WrapUnsafeBinder(op, ty) => { self.visit_operand(op, location); self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); diff --git a/compiler/rustc_middle/src/query/caches.rs b/compiler/rustc_middle/src/query/caches.rs index 2adcecc5aaef..c1f5e5b67085 100644 --- a/compiler/rustc_middle/src/query/caches.rs +++ b/compiler/rustc_middle/src/query/caches.rs @@ -67,7 +67,7 @@ where #[inline] fn complete(&self, key: K, value: V, index: DepNodeIndex) { // We may be overwriting another value. This is all right, since the dep-graph - // will check that the value fingerprint matches. + // will check that the fingerprint matches. self.cache.insert(key, (value, index)); } diff --git a/compiler/rustc_middle/src/verify_ich.rs b/compiler/rustc_middle/src/verify_ich.rs index a1ab4d8cc4d0..ff3c5bb5a9d6 100644 --- a/compiler/rustc_middle/src/verify_ich.rs +++ b/compiler/rustc_middle/src/verify_ich.rs @@ -25,7 +25,7 @@ pub fn incremental_verify_ich<'tcx, V>( tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) }); - let old_hash = dep_graph_data.prev_value_fingerprint_of(prev_index); + let old_hash = dep_graph_data.prev_fingerprint_of(prev_index); if new_hash != old_hash { incremental_verify_ich_failed(tcx, prev_index, &|| format_value(result)); diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index d5548266aa01..4b2c52ad7999 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -86,6 +86,7 @@ where Rvalue::Cast(..) | Rvalue::Ref(_, BorrowKind::Fake(_), _) + | Rvalue::ShallowInitBox(..) | Rvalue::Use(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Repeat(..) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 224abf6901b3..ced9bd735ba2 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -391,7 +391,15 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { } StatementKind::Assign(box (place, rval)) => { self.create_move_path(*place); - self.gather_init(place.as_ref(), InitKind::Deep); + if let RvalueInitializationState::Shallow = rval.initialization_state() { + // Box starts out uninitialized - need to create a separate + // move-path for the interior so it will be separate from + // the exterior. + self.create_move_path(self.tcx.mk_place_deref(*place)); + self.gather_init(place.as_ref(), InitKind::Shallow); + } else { + self.gather_init(place.as_ref(), InitKind::Deep); + } self.gather_rvalue(rval); } StatementKind::FakeRead(box (_, place)) => { @@ -427,6 +435,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { Rvalue::Use(ref operand) | Rvalue::Repeat(ref operand, _) | Rvalue::Cast(_, ref operand, _) + | Rvalue::ShallowInitBox(ref operand, _) | Rvalue::UnaryOp(_, ref operand) | Rvalue::WrapUnsafeBinder(ref operand, _) => self.gather_operand(operand), Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs)) => { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 93da4f3a0a81..604f1da1a3ab 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -467,6 +467,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { Rvalue::Discriminant(place) => state.get_discr(place.as_ref(), &self.map), Rvalue::Use(operand) => return self.handle_operand(operand, state), Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), + Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in runtime MIR"), Rvalue::Ref(..) | Rvalue::RawPtr(..) => { // We don't track such places. return ValueOrPlace::TOP; diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 68c47ec4c192..808be19cbd81 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -1,8 +1,12 @@ //! This pass transforms derefs of Box into a deref of the pointer inside Box. //! //! Box is not actually a pointer so it is incorrect to dereference it directly. +//! +//! `ShallowInitBox` being a device for drop elaboration to understand deferred assignment to box +//! contents, we do not need this any more on runtime MIR. -use rustc_abi::FieldIdx; +use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_index::{IndexVec, indexvec}; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; use rustc_middle::span_bug; @@ -85,6 +89,68 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> { self.super_place(place, context, location); } + + fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) { + self.super_statement(stmt, location); + + let tcx = self.tcx; + let source_info = stmt.source_info; + + if let StatementKind::Assign(box (_, ref mut rvalue)) = stmt.kind + && let Rvalue::ShallowInitBox(ref mut mutptr_to_u8, pointee) = *rvalue + && let ty::Adt(box_adt, box_args) = Ty::new_box(tcx, pointee).kind() + { + let args = tcx.mk_args(&[pointee.into()]); + let (unique_ty, nonnull_ty, ptr_ty) = + build_ptr_tys(tcx, pointee, self.unique_def, self.nonnull_def); + let adt_kind = |def: ty::AdtDef<'tcx>, args| { + Box::new(AggregateKind::Adt(def.did(), VariantIdx::ZERO, args, None, None)) + }; + let zst = |ty| { + Operand::Constant(Box::new(ConstOperand { + span: source_info.span, + user_ty: None, + const_: Const::zero_sized(ty), + })) + }; + + let constptr = self.patch.new_temp(ptr_ty, source_info.span); + self.patch.add_assign( + location, + constptr.into(), + Rvalue::Cast(CastKind::Transmute, mutptr_to_u8.clone(), ptr_ty), + ); + + let nonnull = self.patch.new_temp(nonnull_ty, source_info.span); + self.patch.add_assign( + location, + nonnull.into(), + Rvalue::Aggregate( + adt_kind(self.nonnull_def, args), + indexvec![Operand::Move(constptr.into())], + ), + ); + + let unique = self.patch.new_temp(unique_ty, source_info.span); + let phantomdata_ty = + self.unique_def.non_enum_variant().fields[FieldIdx::ONE].ty(tcx, args); + self.patch.add_assign( + location, + unique.into(), + Rvalue::Aggregate( + adt_kind(self.unique_def, args), + indexvec![Operand::Move(nonnull.into()), zst(phantomdata_ty)], + ), + ); + + let global_alloc_ty = + box_adt.non_enum_variant().fields[FieldIdx::ONE].ty(tcx, box_args); + *rvalue = Rvalue::Aggregate( + adt_kind(*box_adt, box_args), + indexvec![Operand::Move(unique.into()), zst(global_alloc_ty)], + ); + } + } } pub(super) struct ElaborateBoxDerefs; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 4e38b9dd6534..6507a5194add 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1069,7 +1069,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { // Unsupported values. Rvalue::ThreadLocalRef(..) => return None, - Rvalue::CopyForDeref(_) => { + Rvalue::CopyForDeref(_) | Rvalue::ShallowInitBox(..) => { bug!("forbidden in runtime MIR: {rvalue:?}") } }; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 873f6a01ec36..caaf300a88d6 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -443,6 +443,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { | Rvalue::CopyForDeref(..) | Rvalue::Repeat(..) | Rvalue::Cast(..) + | Rvalue::ShallowInitBox(..) | Rvalue::Discriminant(..) | Rvalue::WrapUnsafeBinder(..) => {} } @@ -604,6 +605,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Ref(..) | RawPtr(..) => return None, + ShallowInitBox(..) => return None, + Cast(ref kind, ref value, to) => match kind { CastKind::IntToInt | CastKind::IntToFloat => { let value = self.eval_operand(value)?; diff --git a/compiler/rustc_mir_transform/src/lint.rs b/compiler/rustc_mir_transform/src/lint.rs index b8b1b930bc41..88297a4efef7 100644 --- a/compiler/rustc_mir_transform/src/lint.rs +++ b/compiler/rustc_mir_transform/src/lint.rs @@ -85,6 +85,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> { | Rvalue::Repeat(..) | Rvalue::Aggregate(..) | Rvalue::Cast(..) + | Rvalue::ShallowInitBox(..) | Rvalue::WrapUnsafeBinder(..) => true, Rvalue::ThreadLocalRef(..) | Rvalue::UnaryOp(..) diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index a08136416543..e225c31881f8 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; use std::collections::hash_map::Entry; -use std::sync::atomic::Ordering; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_middle::mir::{Body, MirDumper, MirPhase, RuntimePhase}; @@ -286,19 +285,6 @@ fn run_passes_inner<'tcx>( continue; }; - if is_optimization_stage(body, phase_change, optimizations) - && let Some(limit) = &tcx.sess.opts.unstable_opts.mir_opt_bisect_limit - { - if limited_by_opt_bisect( - tcx, - tcx.def_path_debug_str(body.source.def_id()), - *limit, - *pass, - ) { - continue; - } - } - let dumper = if pass.is_mir_dump_enabled() && let Some(dumper) = MirDumper::new(tcx, pass_name, body) { @@ -370,46 +356,3 @@ pub(super) fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tc dumper.set_show_pass_num().set_disambiguator(&"after").dump_mir(body) } } - -fn is_optimization_stage( - body: &Body<'_>, - phase_change: Option, - optimizations: Optimizations, -) -> bool { - optimizations == Optimizations::Allowed - && body.phase == MirPhase::Runtime(RuntimePhase::PostCleanup) - && phase_change == Some(MirPhase::Runtime(RuntimePhase::Optimized)) -} - -fn limited_by_opt_bisect<'tcx, P>( - tcx: TyCtxt<'tcx>, - def_path: String, - limit: usize, - pass: &P, -) -> bool -where - P: MirPass<'tcx> + ?Sized, -{ - let current_opt_bisect_count = - tcx.sess.mir_opt_bisect_eval_count.fetch_add(1, Ordering::Relaxed); - - let can_run = current_opt_bisect_count < limit; - - if can_run { - eprintln!( - "BISECT: running pass ({}) {} on {}", - current_opt_bisect_count + 1, - pass.name(), - def_path - ); - } else { - eprintln!( - "BISECT: NOT running pass ({}) {} on {}", - current_opt_bisect_count + 1, - pass.name(), - def_path - ); - } - - !can_run -} diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index fb880caf876e..3d1537b95efa 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -449,6 +449,8 @@ impl<'tcx> Validator<'_, 'tcx> { self.validate_operand(operand)?; } + Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable), + Rvalue::UnaryOp(op, operand) => { match op { // These operations can never fail. diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs index 6d33736d64ec..02caa92ad3fc 100644 --- a/compiler/rustc_mir_transform/src/single_use_consts.rs +++ b/compiler/rustc_mir_transform/src/single_use_consts.rs @@ -85,7 +85,7 @@ impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts { } fn is_required(&self) -> bool { - false + true } } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 78c161ebd58c..1afdb4639a0c 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1259,6 +1259,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + Rvalue::ShallowInitBox(operand, _) => { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { + self.fail(location, format!("ShallowInitBox after ElaborateBoxDerefs")) + } + + let a = operand.ty(&self.body.local_decls, self.tcx); + check_kinds!(a, "Cannot shallow init type {:?}", ty::RawPtr(..)); + } Rvalue::Cast(kind, operand, target_type) => { let op_ty = operand.ty(self.body, self.tcx); match kind { diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs index 51757c582722..e81b32ec9acf 100644 --- a/compiler/rustc_public/src/mir/body.rs +++ b/compiler/rustc_public/src/mir/body.rs @@ -567,6 +567,13 @@ pub enum Rvalue { /// [#74836]: https://github.com/rust-lang/rust/issues/74836 Repeat(Operand, TyConst), + /// Transmutes a `*mut u8` into shallow-initialized `Box`. + /// + /// This is different from a normal transmute because dataflow analysis will treat the box as + /// initialized but its content as uninitialized. Like other pointer casts, this in general + /// affects alias analysis. + ShallowInitBox(Operand, Ty), + /// Creates a pointer/reference to the given thread local. /// /// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a @@ -644,6 +651,7 @@ impl Rvalue { } AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)), }, + Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)), Rvalue::CopyForDeref(place) => place.ty(locals), } } diff --git a/compiler/rustc_public/src/mir/pretty.rs b/compiler/rustc_public/src/mir/pretty.rs index bf2655e9a789..5ba72965cb29 100644 --- a/compiler/rustc_public/src/mir/pretty.rs +++ b/compiler/rustc_public/src/mir/pretty.rs @@ -383,6 +383,7 @@ fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { Rvalue::Repeat(op, cnst) => { write!(writer, "[{}; {}]", pretty_operand(op), pretty_ty_const(cnst)) } + Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::ThreadLocalRef(item) => { write!(writer, "thread_local_ref{item:?}") } diff --git a/compiler/rustc_public/src/mir/visit.rs b/compiler/rustc_public/src/mir/visit.rs index e1d9cf31036e..678205171ecf 100644 --- a/compiler/rustc_public/src/mir/visit.rs +++ b/compiler/rustc_public/src/mir/visit.rs @@ -277,6 +277,10 @@ macro_rules! make_mir_visitor { self.visit_operand(op, location); self.visit_ty_const(constant, location); } + Rvalue::ShallowInitBox(op, ty) => { + self.visit_ty(ty, location); + self.visit_operand(op, location) + } Rvalue::ThreadLocalRef(_) => {} Rvalue::UnaryOp(_, op) | Rvalue::Use(op) => { self.visit_operand(op, location); diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index d25751c81f3f..a77808cfb275 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -240,6 +240,9 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { let operands = operands.iter().map(|op| op.stable(tables, cx)).collect(); crate::mir::Rvalue::Aggregate(agg_kind.stable(tables, cx), operands) } + ShallowInitBox(op, ty) => { + crate::mir::Rvalue::ShallowInitBox(op.stable(tables, cx), ty.stable(tables, cx)) + } CopyForDeref(place) => crate::mir::Rvalue::CopyForDeref(place.stable(tables, cx)), WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"), } diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index 39bd2569ef46..60d9fdc47ed6 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -1,5 +1,5 @@ use rustc_middle::bug; -use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, KeyFingerprintStyle}; +use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, FingerprintStyle}; use rustc_middle::query::QueryCache; use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner}; @@ -15,7 +15,7 @@ mod non_query { DepKindVTable { is_anon: false, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Unit, + fingerprint_style: FingerprintStyle::Unit, force_from_dep_node: Some(|_, dep_node, _| { bug!("force_from_dep_node: encountered {dep_node:?}") }), @@ -29,7 +29,7 @@ mod non_query { DepKindVTable { is_anon: false, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Unit, + fingerprint_style: FingerprintStyle::Unit, force_from_dep_node: Some(|_, dep_node, _| { bug!("force_from_dep_node: encountered {dep_node:?}") }), @@ -42,7 +42,7 @@ mod non_query { DepKindVTable { is_anon: false, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Unit, + fingerprint_style: FingerprintStyle::Unit, force_from_dep_node: Some(|tcx, _, prev_index| { tcx.dep_graph.force_diagnostic_node(tcx, prev_index); true @@ -56,7 +56,7 @@ mod non_query { DepKindVTable { is_anon: true, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Opaque, + fingerprint_style: FingerprintStyle::Opaque, force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")), try_load_from_on_disk_cache: None, name: &"AnonZeroDeps", @@ -67,7 +67,7 @@ mod non_query { DepKindVTable { is_anon: true, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Unit, + fingerprint_style: FingerprintStyle::Unit, force_from_dep_node: None, try_load_from_on_disk_cache: None, name: &"TraitSelect", @@ -78,7 +78,7 @@ mod non_query { DepKindVTable { is_anon: false, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Opaque, + fingerprint_style: FingerprintStyle::Opaque, force_from_dep_node: None, try_load_from_on_disk_cache: None, name: &"CompileCodegenUnit", @@ -89,7 +89,7 @@ mod non_query { DepKindVTable { is_anon: false, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Opaque, + fingerprint_style: FingerprintStyle::Opaque, force_from_dep_node: None, try_load_from_on_disk_cache: None, name: &"CompileMonoItem", @@ -100,7 +100,7 @@ mod non_query { DepKindVTable { is_anon: false, is_eval_always: false, - key_fingerprint_style: KeyFingerprintStyle::Unit, + fingerprint_style: FingerprintStyle::Unit, force_from_dep_node: None, try_load_from_on_disk_cache: None, name: &"Metadata", @@ -118,17 +118,17 @@ where Cache: QueryCache + 'tcx, { let is_anon = FLAGS.is_anon; - let key_fingerprint_style = if is_anon { - KeyFingerprintStyle::Opaque + let fingerprint_style = if is_anon { + FingerprintStyle::Opaque } else { - >::key_fingerprint_style() + >::fingerprint_style() }; - if is_anon || !key_fingerprint_style.reconstructible() { + if is_anon || !fingerprint_style.reconstructible() { return DepKindVTable { is_anon, is_eval_always, - key_fingerprint_style, + fingerprint_style, force_from_dep_node: None, try_load_from_on_disk_cache: None, name: Q::NAME, @@ -138,7 +138,7 @@ where DepKindVTable { is_anon, is_eval_always, - key_fingerprint_style, + fingerprint_style, force_from_dep_node: Some(|tcx, dep_node, _| { force_from_dep_node_inner(Q::query_dispatcher(tcx), tcx, dep_node) }), diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 1f064599332c..80bdc5626ec8 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -509,7 +509,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer dep_graph_data.mark_debug_loaded_from_disk(*dep_node) } - let prev_fingerprint = dep_graph_data.prev_value_fingerprint_of(prev_dep_node_index); + let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index); // If `-Zincremental-verify-ich` is specified, re-hash results from // the cache and make sure that they have the expected fingerprint. // @@ -538,7 +538,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer // can be forced from `DepNode`. debug_assert!( !query.will_cache_on_disk_for_key(tcx, key) - || !tcx.key_fingerprint_style(dep_node.kind).reconstructible(), + || !tcx.fingerprint_style(dep_node.kind).reconstructible(), "missing on-disk cache entry for {dep_node:?}" ); diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 5981e7e0f526..00f6a7fcf916 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -396,11 +396,8 @@ pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache, const FLAGS ) { debug_assert!(tcx.dep_graph.is_green(&dep_node)); - let key = C::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| { - panic!( - "Failed to recover key for {dep_node:?} with key fingerprint {}", - dep_node.key_fingerprint - ) + let key = C::Key::recover(tcx, &dep_node).unwrap_or_else(|| { + panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); if query.will_cache_on_disk_for_key(tcx, &key) { // Call `tcx.$query(key)` for its side-effect of loading the disk-cached @@ -465,7 +462,7 @@ pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache, const FLAGS: QueryF "calling force_from_dep_node() on dep_kinds::codegen_unit" ); - if let Some(key) = C::Key::try_recover_key(tcx, &dep_node) { + if let Some(key) = C::Key::recover(tcx, &dep_node) { force_query(query, tcx, key, dep_node); true } else { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d9f9d1ff5a47..6fa0e6fdbb3b 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -371,8 +371,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // - A glob decl is overwritten by its clone after setting ambiguity in it. // FIXME: avoid this by removing `warn_ambiguity`, or by triggering glob re-fetch // with the same decl in some way. - // - A glob decl is overwritten by a glob decl with larger visibility. - // FIXME: avoid this by updating this visibility in place. // - A glob decl is overwritten by a glob decl re-fetching an // overwritten decl from other module (the recursive case). // Here we are detecting all such re-fetches and overwrite old decls @@ -386,8 +384,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // FIXME: reenable the asserts when `warn_ambiguity` is removed (#149195). // assert_ne!(old_deep_decl, deep_decl); // assert!(old_deep_decl.is_glob_import()); - // FIXME: reenable the assert when visibility is updated in place. - // assert!(!deep_decl.is_glob_import()); + assert!(!deep_decl.is_glob_import()); if old_glob_decl.ambiguity.get().is_some() && glob_decl.ambiguity.get().is_none() { // Do not lose glob ambiguities when re-fetching the glob. glob_decl.ambiguity.set_unchecked(old_glob_decl.ambiguity.get()); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 5a6982b8c29d..94f8444db142 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -4060,32 +4060,25 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { "instead, you are more likely to want" }; let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand; - let mut sugg_is_str_to_string = false; let mut sugg = vec![(lt.span, String::new())]; if let Some((kind, _span)) = self.diag_metadata.current_function && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind + && let ast::FnRetTy::Ty(ty) = &sig.decl.output { let mut lt_finder = LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] }; - for param in &sig.decl.inputs { - lt_finder.visit_ty(¶m.ty); - } - if let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output { - lt_finder.visit_ty(ret_ty); - let mut ret_lt_finder = - LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] }; - ret_lt_finder.visit_ty(ret_ty); - if let [Ty { span, kind: TyKind::Ref(_, mut_ty), .. }] = - &ret_lt_finder.seen[..] - { - // We might have a situation like - // fn g(mut x: impl Iterator) -> Option<&'_ ()> - // but `lt.span` only points at `'_`, so to suggest `-> Option<()>` - // we need to find a more accurate span to end up with - // fn g<'a>(mut x: impl Iterator) -> Option<()> - sugg = vec![(span.with_hi(mut_ty.ty.span.lo()), String::new())]; - owned_sugg = true; - } + lt_finder.visit_ty(&ty); + + if let [Ty { span, kind: TyKind::Ref(_, mut_ty), .. }] = + <_finder.seen[..] + { + // We might have a situation like + // fn g(mut x: impl Iterator) -> Option<&'_ ()> + // but `lt.span` only points at `'_`, so to suggest `-> Option<()>` + // we need to find a more accurate span to end up with + // fn g<'a>(mut x: impl Iterator) -> Option<()> + sugg = vec![(span.with_hi(mut_ty.ty.span.lo()), String::new())]; + owned_sugg = true; } if let Some(ty) = lt_finder.found { if let TyKind::Path(None, path) = &ty.kind { @@ -4105,7 +4098,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { lt.span.with_hi(ty.span.hi()), "String".to_string(), )]; - sugg_is_str_to_string = true; } Some(Res::PrimTy(..)) => {} Some(Res::Def( @@ -4132,7 +4124,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { lt.span.with_hi(ty.span.hi()), "String".to_string(), )]; - sugg_is_str_to_string = true; } Res::PrimTy(..) => {} Res::Def( @@ -4167,12 +4158,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } if owned_sugg { - if let Some(span) = - self.find_ref_prefix_span_for_owned_suggestion(lt.span) - && !sugg_is_str_to_string - { - sugg = vec![(span, String::new())]; - } err.multipart_suggestion_verbose( format!("{pre} to return an owned value"), sugg, @@ -4199,23 +4184,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } } - - fn find_ref_prefix_span_for_owned_suggestion(&self, lifetime: Span) -> Option { - let mut finder = RefPrefixSpanFinder { lifetime, span: None }; - if let Some(item) = self.diag_metadata.current_item { - finder.visit_item(item); - } else if let Some((kind, _span)) = self.diag_metadata.current_function - && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind - { - for param in &sig.decl.inputs { - finder.visit_ty(¶m.ty); - } - if let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output { - finder.visit_ty(ret_ty); - } - } - finder.span - } } fn mk_where_bound_predicate( @@ -4317,26 +4285,6 @@ impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> { } } -struct RefPrefixSpanFinder { - lifetime: Span, - span: Option, -} - -impl<'ast> Visitor<'ast> for RefPrefixSpanFinder { - fn visit_ty(&mut self, t: &'ast Ty) { - if self.span.is_some() { - return; - } - if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind - && t.span.lo() == self.lifetime.lo() - { - self.span = Some(t.span.with_hi(mut_ty.ty.span.lo())); - return; - } - walk_ty(self, t); - } -} - /// Shadowing involving a label is only a warning for historical reasons. //FIXME: make this a proper lint. pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident) { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 69f9ad9aa361..9219b5a7e8ac 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2481,9 +2481,6 @@ options! { mir_include_spans: MirIncludeSpans = (MirIncludeSpans::default(), parse_mir_include_spans, [UNTRACKED], "include extra comments in mir pretty printing, like line numbers and statement indices, \ details about types, etc. (boolean for all passes, 'nll' to enable in NLL MIR only, default: 'nll')"), - mir_opt_bisect_limit: Option = (None, parse_opt_number, [TRACKED], - "limit the number of MIR optimization pass executions (global across all bodies). \ - Pass executions after this limit are skipped and reported. (default: no limit)"), #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] mir_opt_level: Option = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 427f3e7fa508..bb22e4a8db04 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -2,7 +2,7 @@ use std::any::Any; use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; -use std::sync::atomic::{AtomicBool, AtomicUsize}; +use std::sync::atomic::AtomicBool; use std::{env, io}; use rand::{RngCore, rng}; @@ -161,12 +161,6 @@ pub struct Session { /// Does the codegen backend support ThinLTO? pub thin_lto_supported: bool, - - /// Global per-session counter for MIR optimization pass applications. - /// - /// Used by `-Zmir-opt-bisect-limit` to assign an index to each - /// optimization-pass execution candidate during this compilation. - pub mir_opt_bisect_eval_count: AtomicUsize, } #[derive(Clone, Copy)] @@ -1107,7 +1101,6 @@ pub fn build_session( invocation_temp, replaced_intrinsics: FxHashSet::default(), // filled by `run_compiler` thin_lto_supported: true, // filled by `run_compiler` - mir_opt_bisect_eval_count: AtomicUsize::new(0), }; validate_commandline_args_with_session_available(&sess); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1d38b41c25df..5623b984b242 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -327,6 +327,7 @@ symbols! { Pointer, Poll, ProcMacro, + ProceduralMasqueradeDummyType, Range, RangeBounds, RangeCopy, 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 fdb2e7d838d5..6003461f35e8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -300,9 +300,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let rebased_args = alias.args.rebase_onto(tcx, trait_def_id, impl_substs); let impl_item_def_id = leaf_def.item.def_id; - if !tcx.check_args_compatible(impl_item_def_id, rebased_args) { - return false; - } let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args); self.infcx.can_eq(param_env, impl_assoc_ty, concrete) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs index 7e6f566e242a..5a8dd0364bee 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs @@ -11,7 +11,7 @@ use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; -use rustc_span::{Ident, Span}; +use rustc_span::Span; use tracing::debug; use crate::error_reporting::infer::nice_region_error::NiceRegionError; @@ -99,8 +99,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Get the span of all the used type parameters in the method. let assoc_item = self.tcx().associated_item(trait_item_def_id); - let mut visitor = - TypeParamSpanVisitor { tcx: self.tcx(), types: vec![], elided_lifetime_paths: vec![] }; + let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] }; match assoc_item.kind { ty::AssocKind::Fn { .. } => { if let Some(hir_id) = @@ -123,49 +122,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { found, }; - let mut diag = self.tcx().dcx().create_err(diag); - // A limit not to make diag verbose. - const ELIDED_LIFETIME_NOTE_LIMIT: usize = 5; - let elided_lifetime_paths = visitor.elided_lifetime_paths; - let total_elided_lifetime_paths = elided_lifetime_paths.len(); - let shown_elided_lifetime_paths = if tcx.sess.opts.verbose { - total_elided_lifetime_paths - } else { - ELIDED_LIFETIME_NOTE_LIMIT - }; - - for elided in elided_lifetime_paths.into_iter().take(shown_elided_lifetime_paths) { - diag.span_note( - elided.span, - format!("`{}` here is elided as `{}`", elided.ident, elided.shorthand), - ); - } - if total_elided_lifetime_paths > shown_elided_lifetime_paths { - diag.note(format!( - "and {} more elided lifetime{} in type paths", - total_elided_lifetime_paths - shown_elided_lifetime_paths, - if total_elided_lifetime_paths - shown_elided_lifetime_paths == 1 { - "" - } else { - "s" - }, - )); - } - diag.emit() + self.tcx().dcx().emit_err(diag) } } -#[derive(Clone)] -struct ElidedLifetimeInPath { - span: Span, - ident: Ident, - shorthand: String, -} - struct TypeParamSpanVisitor<'tcx> { tcx: TyCtxt<'tcx>, types: Vec, - elided_lifetime_paths: Vec, } impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> { @@ -175,83 +138,6 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> { self.tcx } - fn visit_qpath(&mut self, qpath: &'tcx hir::QPath<'tcx>, id: hir::HirId, _span: Span) { - fn record_elided_lifetimes( - tcx: TyCtxt<'_>, - elided_lifetime_paths: &mut Vec, - segment: &hir::PathSegment<'_>, - ) { - let Some(args) = segment.args else { return }; - if args.parenthesized != hir::GenericArgsParentheses::No { - // Our diagnostic rendering below uses `<...>` syntax; skip cases like `Fn(..) -> ..`. - return; - } - let elided_count = args - .args - .iter() - .filter(|arg| { - let hir::GenericArg::Lifetime(l) = arg else { return false }; - l.syntax == hir::LifetimeSyntax::Implicit - && matches!(l.source, hir::LifetimeSource::Path { .. }) - }) - .count(); - if elided_count == 0 - || elided_lifetime_paths.iter().any(|p| p.span == segment.ident.span) - { - return; - } - - let sm = tcx.sess.source_map(); - let mut parts = args - .args - .iter() - .map(|arg| match arg { - hir::GenericArg::Lifetime(l) => { - if l.syntax == hir::LifetimeSyntax::Implicit - && matches!(l.source, hir::LifetimeSource::Path { .. }) - { - "'_".to_string() - } else { - sm.span_to_snippet(l.ident.span) - .unwrap_or_else(|_| format!("'{}", l.ident.name)) - } - } - hir::GenericArg::Type(ty) => { - sm.span_to_snippet(ty.span).unwrap_or_else(|_| "..".to_string()) - } - hir::GenericArg::Const(ct) => { - sm.span_to_snippet(ct.span).unwrap_or_else(|_| "..".to_string()) - } - hir::GenericArg::Infer(_) => "_".to_string(), - }) - .collect::>(); - parts.extend(args.constraints.iter().map(|constraint| { - sm.span_to_snippet(constraint.span) - .unwrap_or_else(|_| format!("{} = ..", constraint.ident)) - })); - let shorthand = format!("{}<{}>", segment.ident, parts.join(", ")); - - elided_lifetime_paths.push(ElidedLifetimeInPath { - span: segment.ident.span, - ident: segment.ident, - shorthand, - }); - } - - match qpath { - hir::QPath::Resolved(_, path) => { - for segment in path.segments { - record_elided_lifetimes(self.tcx, &mut self.elided_lifetime_paths, segment); - } - } - hir::QPath::TypeRelative(_, segment) => { - record_elided_lifetimes(self.tcx, &mut self.elided_lifetime_paths, segment); - } - } - - hir::intravisit::walk_qpath(self, qpath, id); - } - fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx, AmbigArg>) { match arg.kind { hir::TyKind::Ref(_, ref mut_ty) => { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 73e93657b02f..04ca6403fe83 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -182,6 +182,7 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(optimize_attribute)] +#![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(slice_internals)] #![feature(staged_api)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 7158fda49a8d..d650239a44c6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -159,6 +159,7 @@ #![feature(pattern_types)] #![feature(prelude_import)] #![feature(repr_simd)] +#![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(simd_ffi)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index d1d5790c694d..b21865a9ae54 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2481,8 +2481,7 @@ macro_rules! int_impl { /// /// Returns a tuple of the addition along with a boolean indicating /// whether an arithmetic overflow would occur. If an overflow would have - /// occurred then the wrapped value is returned (negative if overflowed - /// above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)). + /// occurred then the wrapped value is returned. /// /// # Examples /// @@ -2517,9 +2516,6 @@ macro_rules! int_impl { /// The output boolean returned by this method is *not* a carry flag, /// and should *not* be added to a more significant word. /// - /// If overflow occurred, the wrapped value is returned (negative if overflowed - /// above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)). - /// /// If the input carry is false, this method is equivalent to /// [`overflowing_add`](Self::overflowing_add). /// @@ -2587,8 +2583,7 @@ macro_rules! int_impl { /// Calculates `self` - `rhs`. /// /// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow - /// would occur. If an overflow would have occurred then the wrapped value is returned - /// (negative if overflowed above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)). + /// would occur. If an overflow would have occurred then the wrapped value is returned. /// /// # Examples /// @@ -2624,9 +2619,6 @@ macro_rules! int_impl { /// The output boolean returned by this method is *not* a borrow flag, /// and should *not* be subtracted from a more significant word. /// - /// If overflow occurred, the wrapped value is returned (negative if overflowed - /// above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)). - /// /// If the input borrow is false, this method is equivalent to /// [`overflowing_sub`](Self::overflowing_sub). /// diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 94396752ac6d..cf79635dcd87 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -487,8 +487,8 @@ macro_rules! uint_impl { /// Performs a carry-less multiplication, returning the lower bits. /// - /// This operation is similar to long multiplication in base 2, except that exclusive or is - /// used instead of addition. The implementation is equivalent to: + /// This operation is similar to long multiplication, except that exclusive or is used + /// instead of addition. The implementation is equivalent to: /// /// ```no_run #[doc = concat!("pub fn carryless_mul(lhs: ", stringify!($SelfT), ", rhs: ", stringify!($SelfT), ") -> ", stringify!($SelfT), "{")] diff --git a/library/std/src/sys/args/unix.rs b/library/std/src/sys/args/unix.rs index 7a592c2b079d..0dfbd5f03eba 100644 --- a/library/std/src/sys/args/unix.rs +++ b/library/std/src/sys/args/unix.rs @@ -164,7 +164,7 @@ mod imp { // of this used `[[NSProcessInfo processInfo] arguments]`. #[cfg(target_vendor = "apple")] mod imp { - use crate::ffi::c_char; + use crate::ffi::{c_char, c_int}; pub unsafe fn init(_argc: isize, _argv: *const *const u8) { // No need to initialize anything in here, `libdyld.dylib` has already @@ -172,6 +172,12 @@ mod imp { } pub fn argc_argv() -> (isize, *const *const c_char) { + unsafe extern "C" { + // These functions are in crt_externs.h. + fn _NSGetArgc() -> *mut c_int; + fn _NSGetArgv() -> *mut *mut *mut c_char; + } + // SAFETY: The returned pointer points to a static initialized early // in the program lifetime by `libdyld.dylib`, and as such is always // valid. @@ -181,9 +187,9 @@ mod imp { // doesn't exist a lock that we can take. Instead, it is generally // expected that it's only modified in `main` / before other code // runs, so reading this here should be fine. - let argc = unsafe { libc::_NSGetArgc().read() }; + let argc = unsafe { _NSGetArgc().read() }; // SAFETY: Same as above. - let argv = unsafe { libc::_NSGetArgv().read() }; + let argv = unsafe { _NSGetArgv().read() }; // Cast from `*mut *mut c_char` to `*const *const c_char` (argc as isize, argv.cast()) diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 5b23ac9e09c1..09b55da741d6 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -393,7 +393,7 @@ Here’s how these different lint controls interact: warning: 1 warning emitted ``` -3. [CLI level flags](#via-compiler-flag) override the default level of a lint. They essentially behave like crate-level attributes. Attributes within the source code take precedence over CLI flags, except for `-F`/`--forbid`, which cannot be overridden. +3. [CLI level flags](#via-compiler-flag) take precedence over attributes. The order of the flags matter; flags on the right take precedence over earlier flags. diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 1484b8c8bcc4..06220f91c745 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -194,6 +194,7 @@ fn check_rvalue<'tcx>( )) } }, + Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, cx.tcx); if ty.is_integral() || ty.is_bool() { diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 9d829bf69e5e..1c404d419ef8 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -343,8 +343,8 @@ impl VisitProvenance for Thread<'_> { impl VisitProvenance for Frame<'_, Provenance, FrameExtra<'_>> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { - let return_place = self.return_place(); let Frame { + return_place, locals, extra, // There are some private fields we cannot access; they contain no tags. diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 71ec9723de8e..64c7096fc5c2 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -493,7 +493,7 @@ pub fn report_result<'tcx>( for (i, frame) in ecx.active_thread_stack().iter().enumerate() { trace!("-------------------"); trace!("Frame {}", i); - trace!(" return: {:?}", frame.return_place()); + trace!(" return: {:?}", frame.return_place); for (i, local) in frame.locals.iter().enumerate() { trace!(" local {}: {:?}", i, local); } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 7883673cdd6a..d50475c74874 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1235,7 +1235,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { // to run extra MIR), and Ok(Some(body)) if we found MIR to run for the // foreign function // Any needed call to `goto_block` will be performed by `emulate_foreign_item`. - let args = MiriInterpCx::copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit? + let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit? let link_name = Symbol::intern(ecx.tcx.symbol_name(instance).name); return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind); } @@ -1262,7 +1262,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ret: Option, unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { - let args = MiriInterpCx::copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit? + let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit? ecx.emulate_dyn_sym(fn_val, abi, &args, dest, ret, unwind) } diff --git a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr index 7b0efec7be5a..1577cceae594 100644 --- a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr +++ b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr @@ -14,8 +14,8 @@ LL | let local = 0; help: ALLOC was deallocated here: --> tests/fail/tail_calls/dangling-local-var.rs:LL:CC | -LL | let _val = unsafe { *x }; - | ^^^^ +LL | f(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^ = note: stack backtrace: 0: g at tests/fail/tail_calls/dangling-local-var.rs:LL:CC diff --git a/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.rs b/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.rs deleted file mode 100644 index dee2c9aad2c7..000000000000 --- a/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@compile-flags: -Zmiri-recursive-validation - -fn main() { - let x = 3u8; - let xref = &x; - let xref_wrong_type: Box = unsafe { std::mem::transmute(xref) }; //~ERROR: encountered 0x03, but expected a boolean - let _val = *xref_wrong_type; -} diff --git a/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr b/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr deleted file mode 100644 index d658909efd93..000000000000 --- a/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: Undefined Behavior: constructing invalid value at .: encountered 0x03, but expected a boolean - --> tests/fail/validity/recursive-validity-box-bool.rs:LL:CC - | -LL | let xref_wrong_type: Box = unsafe { std::mem::transmute(xref) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/pass/function_calls/tail_call.rs b/src/tools/miri/tests/pass/tail_call.rs similarity index 84% rename from src/tools/miri/tests/pass/function_calls/tail_call.rs rename to src/tools/miri/tests/pass/tail_call.rs index f9cf86bb898f..f62007063980 100644 --- a/src/tools/miri/tests/pass/function_calls/tail_call.rs +++ b/src/tools/miri/tests/pass/tail_call.rs @@ -4,7 +4,6 @@ fn main() { assert_eq!(factorial(10), 3_628_800); assert_eq!(mutually_recursive_identity(1000), 1000); - non_scalar(); } fn factorial(n: u32) -> u32 { @@ -38,14 +37,3 @@ fn mutually_recursive_identity(x: u32) -> u32 { switch(x, 0) } - -fn non_scalar() { - fn f(x: [usize; 2], i: u32) { - if i == 0 { - return; - } - become f(x, i - 1); - } - - f([5, 5], 2); -} diff --git a/tests/codegen-llvm/intrinsics/likely_assert.rs b/tests/codegen-llvm/intrinsics/likely_assert.rs index e7e2cfdff052..59a40c750eab 100644 --- a/tests/codegen-llvm/intrinsics/likely_assert.rs +++ b/tests/codegen-llvm/intrinsics/likely_assert.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Copt-level=3 -#![feature(panic_internals, const_eval_select, rustc_attrs, core_intrinsics)] +#![feature(panic_internals, const_eval_select, rustc_allow_const_fn_unstable, core_intrinsics)] #![crate_type = "lib"] // check that assert! and const_assert! emit branch weights diff --git a/tests/mir-opt/optimize_none.rs b/tests/mir-opt/optimize_none.rs index 99efcc35e595..a5b541bd2b62 100644 --- a/tests/mir-opt/optimize_none.rs +++ b/tests/mir-opt/optimize_none.rs @@ -15,14 +15,13 @@ pub fn add_noopt() -> i32 { #[optimize(none)] pub fn const_branch() -> i32 { // CHECK-LABEL: fn const_branch( - // CHECK: [[BOOL:_[0-9]+]] = const true; - // CHECK: switchInt(move [[BOOL]]) -> [0: [[BB_FALSE:bb[0-9]+]], otherwise: [[BB_TRUE:bb[0-9]+]]]; + // CHECK: switchInt(const true) -> [0: [[FALSE:bb[0-9]+]], otherwise: [[TRUE:bb[0-9]+]]]; // CHECK-NEXT: } - // CHECK: [[BB_FALSE]]: { + // CHECK: [[FALSE]]: { // CHECK-NEXT: _0 = const 0 // CHECK-NEXT: goto // CHECK-NEXT: } - // CHECK: [[BB_TRUE]]: { + // CHECK: [[TRUE]]: { // CHECK-NEXT: _0 = const 1 // CHECK-NEXT: goto // CHECK-NEXT: } diff --git a/tests/run-make/mir-opt-bisect-limit/main.rs b/tests/run-make/mir-opt-bisect-limit/main.rs deleted file mode 100644 index 674275b10fcd..000000000000 --- a/tests/run-make/mir-opt-bisect-limit/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![crate_type = "lib"] -#![no_std] - -#[inline(never)] -pub fn callee(x: u64) -> u64 { - x.wrapping_mul(3).wrapping_add(7) -} - -pub fn caller(a: u64, b: u64) -> u64 { - callee(a) + callee(b) -} diff --git a/tests/run-make/mir-opt-bisect-limit/rmake.rs b/tests/run-make/mir-opt-bisect-limit/rmake.rs deleted file mode 100644 index fa77cb7d8c35..000000000000 --- a/tests/run-make/mir-opt-bisect-limit/rmake.rs +++ /dev/null @@ -1,119 +0,0 @@ -use std::path::Path; - -use run_make_support::{CompletedProcess, rfs, rustc}; - -struct Case { - name: &'static str, - flags: &'static [&'static str], - expect_inline_dump: bool, - expect_running: ExpectedCount, - expect_not_running: ExpectedCount, -} - -enum ExpectedCount { - Exactly(usize), - AtLeastOne, - Zero, -} - -fn main() { - let cases = [ - Case { - name: "limit0", - flags: &["-Zmir-opt-bisect-limit=0"], - expect_inline_dump: false, - expect_running: ExpectedCount::Exactly(0), - expect_not_running: ExpectedCount::AtLeastOne, - }, - Case { - name: "limit1", - flags: &["-Zmir-opt-bisect-limit=1"], - expect_inline_dump: false, - expect_running: ExpectedCount::Exactly(1), - expect_not_running: ExpectedCount::AtLeastOne, - }, - Case { - name: "huge_limit", - flags: &["-Zmir-opt-bisect-limit=1000000000"], - expect_inline_dump: true, - expect_running: ExpectedCount::AtLeastOne, - expect_not_running: ExpectedCount::Zero, - }, - Case { - name: "limit0_with_force_enable_inline", - flags: &["-Zmir-opt-bisect-limit=0", "-Zmir-enable-passes=+Inline"], - expect_inline_dump: false, - expect_running: ExpectedCount::Exactly(0), - expect_not_running: ExpectedCount::AtLeastOne, - }, - ]; - - for case in cases { - let (inline_dumped, running_count, not_running_count, output) = - compile_case(case.name, case.flags); - - assert_eq!( - inline_dumped, case.expect_inline_dump, - "{}: unexpected Inline dump presence", - case.name - ); - - assert_expected_count( - running_count, - case.expect_running, - &format!("{}: running count", case.name), - ); - assert_expected_count( - not_running_count, - case.expect_not_running, - &format!("{}: NOT running count", case.name), - ); - } -} - -fn compile_case(dump_dir: &str, extra_flags: &[&str]) -> (bool, usize, usize, CompletedProcess) { - if Path::new(dump_dir).exists() { - rfs::remove_dir_all(dump_dir); - } - rfs::create_dir_all(dump_dir); - - let mut cmd = rustc(); - cmd.input("main.rs") - .arg("--emit=mir") - .arg("-Zmir-opt-level=2") - .arg("-Copt-level=2") - .arg("-Zthreads=1") - .arg("-Zdump-mir=Inline") - .arg(format!("-Zdump-mir-dir={dump_dir}")); - - for &flag in extra_flags { - cmd.arg(flag); - } - - let output = cmd.run(); - let (running_count, not_running_count) = bisect_line_counts(&output); - (has_inline_dump_file(dump_dir), running_count, not_running_count, output) -} - -fn assert_expected_count(actual: usize, expected: ExpectedCount, context: &str) { - match expected { - ExpectedCount::Exactly(n) => assert_eq!(actual, n, "{context}"), - ExpectedCount::AtLeastOne => assert!(actual > 0, "{context}"), - ExpectedCount::Zero => assert_eq!(actual, 0, "{context}"), - } -} - -fn has_inline_dump_file(dir: &str) -> bool { - rfs::read_dir(dir) - .flatten() - .any(|entry| entry.file_name().to_string_lossy().contains(".Inline.")) -} - -fn bisect_line_counts(output: &CompletedProcess) -> (usize, usize) { - let stderr = output.stderr_utf8(); - let running_count = - stderr.lines().filter(|line| line.starts_with("BISECT: running pass (")).count(); - let not_running_count = - stderr.lines().filter(|line| line.starts_with("BISECT: NOT running pass (")).count(); - (running_count, not_running_count) -} diff --git a/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.rs b/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.rs deleted file mode 100644 index 4a3ccc287f7f..000000000000 --- a/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ compile-flags: -Znext-solver=globally - -// Regression test for https://github.com/rust-lang/rust/issues/152684. - -#![feature(associated_type_defaults)] - -trait Foo { - type Assoc = T; - //~^ ERROR defaults for generic parameters are not allowed here - fn foo() -> Self::Assoc; -} -impl Foo for () { - fn foo() -> Self::Assoc { - [] //~ ERROR mismatched types - } -} - -fn main() {} diff --git a/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.stderr b/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.stderr deleted file mode 100644 index c40123324248..000000000000 --- a/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: defaults for generic parameters are not allowed here - --> $DIR/suggest-param-env-shadowing-incompatible-args.rs:8:16 - | -LL | type Assoc = T; - | ^^^^^^ - -error[E0308]: mismatched types - --> $DIR/suggest-param-env-shadowing-incompatible-args.rs:14:9 - | -LL | fn foo() -> Self::Assoc { - | ----------- expected `<() as Foo>::Assoc` because of return type -LL | [] - | ^^ expected `u8`, found `[_; 0]` - | - = note: expected type `u8` - found array `[_; 0]` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 6193a101918b..489c8bf9f495 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -2,6 +2,7 @@ // We enable a bunch of features to not get feature-gate errs in this test. #![deny(invalid_doc_attributes)] #![feature(rustc_attrs)] +#![feature(rustc_allow_const_fn_unstable)] #![feature(allow_internal_unstable)] // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity #![feature(fn_align)] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 01e70adf4ee9..009da1d12a16 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `cfg` attribute input - --> $DIR/malformed-attrs.rs:106:1 + --> $DIR/malformed-attrs.rs:107:1 | LL | #[cfg] | ^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg] = note: for more information, visit error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:108:1 + --> $DIR/malformed-attrs.rs:109:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -21,13 +21,13 @@ LL | #[cfg_attr] = note: for more information, visit error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:214:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:180:1 + --> $DIR/malformed-attrs.rs:181:1 | LL | #[allow] | ^^^^^^^^ @@ -43,7 +43,7 @@ LL | #[allow(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:182:1 + --> $DIR/malformed-attrs.rs:183:1 | LL | #[expect] | ^^^^^^^^^ @@ -59,7 +59,7 @@ LL | #[expect(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:184:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[warn] | ^^^^^^^ @@ -75,7 +75,7 @@ LL | #[warn(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:186:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[deny] | ^^^^^^^ @@ -91,7 +91,7 @@ LL | #[deny(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:188:1 + --> $DIR/malformed-attrs.rs:189:1 | LL | #[forbid] | ^^^^^^^^^ @@ -107,25 +107,25 @@ LL | #[forbid(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:103:1 + --> $DIR/malformed-attrs.rs:104:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:120:1 + --> $DIR/malformed-attrs.rs:121:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:128:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:219:1 + --> $DIR/malformed-attrs.rs:220:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | #[allow_internal_unsafe = 1] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0539]: malformed `windows_subsystem` attribute input - --> $DIR/malformed-attrs.rs:26:1 + --> $DIR/malformed-attrs.rs:27:1 | LL | #![windows_subsystem] | ^^^-----------------^ @@ -150,25 +150,25 @@ LL | #![windows_subsystem = "windows"] | +++++++++++ error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:29:1 + --> $DIR/malformed-attrs.rs:30:1 | LL | #[unsafe(export_name)] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error: `rustc_allow_const_fn_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:31:1 + --> $DIR/malformed-attrs.rs:32:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow_internal_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:34:1 + --> $DIR/malformed-attrs.rs:35:1 | LL | #[allow_internal_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `rustc_confusables` attribute input - --> $DIR/malformed-attrs.rs:36:1 + --> $DIR/malformed-attrs.rs:37:1 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | #[rustc_confusables] | help: must be of the form: `#[rustc_confusables("name1", "name2", ...)]` error: `#[rustc_confusables]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:36:1 + --> $DIR/malformed-attrs.rs:37:1 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | #[rustc_confusables] = help: `#[rustc_confusables]` can only be applied to inherent methods error[E0539]: malformed `deprecated` attribute input - --> $DIR/malformed-attrs.rs:39:1 + --> $DIR/malformed-attrs.rs:40:1 | LL | #[deprecated = 5] | ^^^^^^^^^^^^^^^-^ @@ -193,7 +193,7 @@ LL | #[deprecated = 5] | expected a string literal here error[E0539]: malformed `rustc_macro_transparency` attribute input - --> $DIR/malformed-attrs.rs:43:1 + --> $DIR/malformed-attrs.rs:44:1 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -208,7 +208,7 @@ LL | #[rustc_macro_transparency = "transparent"] | +++++++++++++++ error: `#[rustc_macro_transparency]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:43:1 + --> $DIR/malformed-attrs.rs:44:1 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -216,7 +216,7 @@ LL | #[rustc_macro_transparency] = help: `#[rustc_macro_transparency]` can only be applied to macro defs error[E0539]: malformed `repr` attribute input - --> $DIR/malformed-attrs.rs:46:1 + --> $DIR/malformed-attrs.rs:47:1 | LL | #[repr] | ^^^^^^^ expected this to be a list @@ -224,7 +224,7 @@ LL | #[repr] = note: for more information, visit error[E0565]: malformed `rustc_as_ptr` attribute input - --> $DIR/malformed-attrs.rs:49:1 + --> $DIR/malformed-attrs.rs:50:1 | LL | #[rustc_as_ptr = 5] | ^^^^^^^^^^^^^^^---^ @@ -233,7 +233,7 @@ LL | #[rustc_as_ptr = 5] | help: must be of the form: `#[rustc_as_ptr]` error[E0539]: malformed `rustc_align` attribute input - --> $DIR/malformed-attrs.rs:54:1 + --> $DIR/malformed-attrs.rs:55:1 | LL | #[rustc_align] | ^^^^^^^^^^^^^^ @@ -242,7 +242,7 @@ LL | #[rustc_align] | help: must be of the form: `#[rustc_align()]` error[E0539]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:56:1 + --> $DIR/malformed-attrs.rs:57:1 | LL | #[optimize] | ^^^^^^^^^^^ expected this to be a list @@ -257,7 +257,7 @@ LL | #[optimize(speed)] | +++++++ error[E0565]: malformed `cold` attribute input - --> $DIR/malformed-attrs.rs:58:1 + --> $DIR/malformed-attrs.rs:59:1 | LL | #[cold = 1] | ^^^^^^^---^ @@ -266,7 +266,7 @@ LL | #[cold = 1] | help: must be of the form: `#[cold]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:60:1 + --> $DIR/malformed-attrs.rs:61:1 | LL | #[must_use()] | ^^^^^^^^^^--^ @@ -284,7 +284,7 @@ LL + #[must_use] | error[E0565]: malformed `no_mangle` attribute input - --> $DIR/malformed-attrs.rs:62:1 + --> $DIR/malformed-attrs.rs:63:1 | LL | #[no_mangle = 1] | ^^^^^^^^^^^^---^ @@ -293,7 +293,7 @@ LL | #[no_mangle = 1] | help: must be of the form: `#[no_mangle]` error[E0565]: malformed `naked` attribute input - --> $DIR/malformed-attrs.rs:64:1 + --> $DIR/malformed-attrs.rs:65:1 | LL | #[unsafe(naked())] | ^^^^^^^^^^^^^^--^^ @@ -302,7 +302,7 @@ LL | #[unsafe(naked())] | help: must be of the form: `#[naked]` error[E0565]: malformed `track_caller` attribute input - --> $DIR/malformed-attrs.rs:66:1 + --> $DIR/malformed-attrs.rs:67:1 | LL | #[track_caller()] | ^^^^^^^^^^^^^^--^ @@ -311,13 +311,13 @@ LL | #[track_caller()] | help: must be of the form: `#[track_caller]` error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:68:1 + --> $DIR/malformed-attrs.rs:69:1 | LL | #[export_name()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error[E0805]: malformed `used` attribute input - --> $DIR/malformed-attrs.rs:70:1 + --> $DIR/malformed-attrs.rs:71:1 | LL | #[used()] | ^^^^^^--^ @@ -335,7 +335,7 @@ LL + #[used] | error: `#[used]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:70:1 + --> $DIR/malformed-attrs.rs:71:1 | LL | #[used()] | ^^^^^^^^^ @@ -343,13 +343,13 @@ LL | #[used()] = help: `#[used]` can only be applied to statics error[E0539]: malformed `crate_name` attribute input - --> $DIR/malformed-attrs.rs:73:1 + --> $DIR/malformed-attrs.rs:74:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error[E0539]: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:78:1 + --> $DIR/malformed-attrs.rs:79:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ @@ -358,7 +358,7 @@ LL | #[target_feature] | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0565]: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:80:1 + --> $DIR/malformed-attrs.rs:81:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^---^ @@ -367,7 +367,7 @@ LL | #[export_stable = 1] | help: must be of the form: `#[export_stable]` error[E0539]: malformed `link` attribute input - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:83:1 | LL | #[link] | ^^^^^^^ expected this to be a list @@ -375,7 +375,7 @@ LL | #[link] = note: for more information, visit error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:86:1 + --> $DIR/malformed-attrs.rs:87:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` @@ -383,7 +383,7 @@ LL | #[link_name] = note: for more information, visit error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:90:1 + --> $DIR/malformed-attrs.rs:91:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` @@ -391,7 +391,7 @@ LL | #[link_section] = note: for more information, visit error[E0539]: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:92:1 + --> $DIR/malformed-attrs.rs:93:1 | LL | #[coverage] | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument @@ -404,13 +404,13 @@ LL | #[coverage(on)] | ++++ error[E0539]: malformed `sanitize` attribute input - --> $DIR/malformed-attrs.rs:94:1 + --> $DIR/malformed-attrs.rs:95:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:99:1 + --> $DIR/malformed-attrs.rs:100:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^----^ @@ -419,7 +419,7 @@ LL | #[no_implicit_prelude = 23] | help: must be of the form: `#[no_implicit_prelude]` error[E0565]: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:103:1 + --> $DIR/malformed-attrs.rs:104:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^----^ @@ -428,7 +428,7 @@ LL | #[proc_macro = 18] | help: must be of the form: `#[proc_macro]` error[E0539]: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:110:1 + --> $DIR/malformed-attrs.rs:111:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | #[instruction_set] = note: for more information, visit error[E0539]: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:112:1 + --> $DIR/malformed-attrs.rs:113:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -448,7 +448,7 @@ LL | #[patchable_function_entry] | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error[E0565]: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:115:5 + --> $DIR/malformed-attrs.rs:116:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^----^ @@ -457,7 +457,7 @@ LL | #[coroutine = 63] || {} | help: must be of the form: `#[coroutine]` error[E0565]: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:120:1 + --> $DIR/malformed-attrs.rs:121:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -466,7 +466,7 @@ LL | #[proc_macro_attribute = 19] | help: must be of the form: `#[proc_macro_attribute]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:123:1 + --> $DIR/malformed-attrs.rs:124:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -484,7 +484,7 @@ LL + #[must_use] | error[E0539]: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:128:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -498,7 +498,7 @@ LL | #[proc_macro_derive(TraitName, attributes(name1, name2, ...))] | ++++++++++++++++++++++++++++++++++++++++++ error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:132:1 + --> $DIR/malformed-attrs.rs:133:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -507,7 +507,7 @@ LL | #[rustc_layout_scalar_valid_range_start] | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:134:1 + --> $DIR/malformed-attrs.rs:135:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -516,7 +516,7 @@ LL | #[rustc_layout_scalar_valid_range_end] | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` error[E0539]: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:136:1 + --> $DIR/malformed-attrs.rs:137:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^--^ @@ -532,7 +532,7 @@ LL + #[must_not_suspend] | error[E0539]: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:138:1 + --> $DIR/malformed-attrs.rs:139:1 | LL | #[cfi_encoding = ""] | ^^^^^^^^^^^^^^^^^--^ @@ -541,7 +541,7 @@ LL | #[cfi_encoding = ""] | help: must be of the form: `#[cfi_encoding = "encoding"]` error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:157:1 + --> $DIR/malformed-attrs.rs:158:1 | LL | #[marker = 3] | ^^^^^^^^^---^ @@ -550,7 +550,7 @@ LL | #[marker = 3] | help: must be of the form: `#[marker]` error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:159:1 + --> $DIR/malformed-attrs.rs:160:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^--^ @@ -559,7 +559,7 @@ LL | #[fundamental()] | help: must be of the form: `#[fundamental]` error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:167:5 + --> $DIR/malformed-attrs.rs:168:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^---^^ @@ -568,7 +568,7 @@ LL | #[unsafe(ffi_pure = 1)] | help: must be of the form: `#[ffi_pure]` error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:169:5 + --> $DIR/malformed-attrs.rs:170:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ LL | #[link_ordinal] = note: for more information, visit error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:173:5 + --> $DIR/malformed-attrs.rs:174:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^---^^ @@ -588,13 +588,13 @@ LL | #[unsafe(ffi_const = 1)] | help: must be of the form: `#[ffi_const]` error[E0539]: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:175:5 + --> $DIR/malformed-attrs.rs:176:5 | LL | #[linkage] | ^^^^^^^^^^ expected this to be of the form `linkage = "..."` error[E0539]: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:191:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -605,7 +605,7 @@ LL | #[debugger_visualizer] = note: for more information, visit error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:192:1 + --> $DIR/malformed-attrs.rs:193:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -614,7 +614,7 @@ LL | #[automatically_derived = 18] | help: must be of the form: `#[automatically_derived]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:200:1 + --> $DIR/malformed-attrs.rs:201:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -623,7 +623,7 @@ LL | #[non_exhaustive = 1] | help: must be of the form: `#[non_exhaustive]` error[E0565]: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:206:1 + --> $DIR/malformed-attrs.rs:207:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^--^ @@ -632,7 +632,7 @@ LL | #[thread_local()] | help: must be of the form: `#[thread_local]` error[E0565]: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:210:1 + --> $DIR/malformed-attrs.rs:211:1 | LL | #[no_link()] | ^^^^^^^^^--^ @@ -641,7 +641,7 @@ LL | #[no_link()] | help: must be of the form: `#[no_link]` error[E0539]: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:212:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^---^ @@ -659,7 +659,7 @@ LL + #[macro_use] | error[E0539]: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:217:1 + --> $DIR/malformed-attrs.rs:218:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^----^ @@ -676,7 +676,7 @@ LL + #[macro_export] | error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:219:1 + --> $DIR/malformed-attrs.rs:220:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^---^ @@ -685,7 +685,7 @@ LL | #[allow_internal_unsafe = 1] | help: must be of the form: `#[allow_internal_unsafe]` error: attribute should be applied to `const fn` - --> $DIR/malformed-attrs.rs:31:1 + --> $DIR/malformed-attrs.rs:32:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -697,7 +697,7 @@ LL | | } | |_- not a `const fn` warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:83:1 | LL | #[link] | ^^^^^^^ @@ -712,19 +712,19 @@ LL | | } = note: requested on the command line with `-W unused-attributes` error: `#[repr(align(...))]` is not supported on functions - --> $DIR/malformed-attrs.rs:46:1 + --> $DIR/malformed-attrs.rs:47:1 | LL | #[repr] | ^^^^^^^ | help: use `#[rustc_align(...)]` instead - --> $DIR/malformed-attrs.rs:46:1 + --> $DIR/malformed-attrs.rs:47:1 | LL | #[repr] | ^^^^^^^ warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:142:1 + --> $DIR/malformed-attrs.rs:143:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -733,7 +733,7 @@ LL | #[diagnostic::on_unimplemented] = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:144:1 + --> $DIR/malformed-attrs.rs:145:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -741,7 +741,7 @@ LL | #[diagnostic::on_unimplemented = 1] = help: only `message`, `note` and `label` are allowed as options error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-attrs.rs:41:1 + --> $DIR/malformed-attrs.rs:42:1 | LL | #[doc] | ^^^^^^ @@ -753,7 +753,7 @@ LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-attrs.rs:51:1 + --> $DIR/malformed-attrs.rs:52:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ @@ -763,13 +763,13 @@ LL | #[inline = 5] = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/malformed-attrs.rs:73:1 + --> $DIR/malformed-attrs.rs:74:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ | note: this attribute does not have an `!`, which means it is applied to this function - --> $DIR/malformed-attrs.rs:114:1 + --> $DIR/malformed-attrs.rs:115:1 | LL | / fn test() { LL | | #[coroutine = 63] || {} @@ -778,13 +778,13 @@ LL | | } | |_^ error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-attrs.rs:76:1 + --> $DIR/malformed-attrs.rs:77:1 | LL | #[doc] | ^^^^^^ warning: `#[link_name]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:86:1 + --> $DIR/malformed-attrs.rs:87:1 | LL | #[link_name] | ^^^^^^^^^^^^ @@ -793,7 +793,7 @@ LL | #[link_name] = help: `#[link_name]` can be applied to foreign functions and foreign statics error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -802,7 +802,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 warning: `#[no_implicit_prelude]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:99:1 + --> $DIR/malformed-attrs.rs:100:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -811,13 +811,13 @@ LL | #[no_implicit_prelude = 23] = help: `#[no_implicit_prelude]` can be applied to crates and modules warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:151:1 + --> $DIR/malformed-attrs.rs:152:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[automatically_derived]` attribute cannot be used on modules - --> $DIR/malformed-attrs.rs:192:1 + --> $DIR/malformed-attrs.rs:193:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -826,7 +826,7 @@ LL | #[automatically_derived = 18] = help: `#[automatically_derived]` can only be applied to trait impl blocks error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:226:1 + --> $DIR/malformed-attrs.rs:227:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -835,7 +835,7 @@ LL | #[ignore = 1] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:115:23 + --> $DIR/malformed-attrs.rs:116:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -843,7 +843,7 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:115:23: 115:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:116:23: 116:25}` error: aborting due to 75 previous errors; 8 warnings emitted @@ -851,7 +851,7 @@ Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805 For more information about an error, try `rustc --explain E0308`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-attrs.rs:51:1 + --> $DIR/malformed-attrs.rs:52:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ @@ -862,7 +862,7 @@ LL | #[inline = 5] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -873,7 +873,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:226:1 + --> $DIR/malformed-attrs.rs:227:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs index 4bd5f746f502..56155e519dca 100644 --- a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs +++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs @@ -2,7 +2,7 @@ //@ compile-flags: --crate-type=lib -Cinstrument-coverage -Zno-profiler-runtime //@[allow] check-pass -#![feature(staged_api, rustc_attrs)] +#![feature(staged_api, rustc_allow_const_fn_unstable)] #![stable(feature = "rust_test", since = "1.0.0")] #[stable(feature = "rust_test", since = "1.0.0")] diff --git a/tests/ui/feature-gates/feature-gate-final-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-final-associated-functions.stderr index cd21aa1c0bf3..b3731acd1d90 100644 --- a/tests/ui/feature-gates/feature-gate-final-associated-functions.stderr +++ b/tests/ui/feature-gates/feature-gate-final-associated-functions.stderr @@ -4,7 +4,7 @@ error[E0658]: `final` on trait functions is experimental LL | final fn bar() {} | ^^^^^ | - = note: see issue #131179 for more information + = note: see issue #1 for more information = help: add `#![feature(final_associated_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs b/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs index 0c0e0c362936..19d8fa87f553 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs +++ b/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs @@ -1,6 +1,6 @@ #![allow(unused_macros)] -#[rustc_allow_const_fn_unstable()] //~ ERROR use of an internal attribute +#[rustc_allow_const_fn_unstable()] //~ ERROR rustc_allow_const_fn_unstable side-steps const fn foo() { } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.stderr b/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.stderr index 42424abcc3cb..44f7a4bb0e68 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.stderr @@ -1,12 +1,12 @@ -error[E0658]: use of an internal attribute +error[E0658]: rustc_allow_const_fn_unstable side-steps feature gating and stability checks --> $DIR/feature-gate-rustc-allow-const-fn-unstable.rs:3:1 | LL | #[rustc_allow_const_fn_unstable()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable - = note: the `#[rustc_allow_const_fn_unstable]` attribute is an internal implementation detail that will never be stable - = note: rustc_allow_const_fn_unstable side-steps feature gating and stability checks + = note: see issue #69399 for more information + = help: add `#![feature(rustc_allow_const_fn_unstable)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 1 previous error diff --git a/tests/ui/imports/overwrite-different-vis-3.rs b/tests/ui/imports/overwrite-different-vis-3.rs deleted file mode 100644 index f45c5cdfb3ab..000000000000 --- a/tests/ui/imports/overwrite-different-vis-3.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Regression test for issue #152606. - -//@ check-pass - -mod outer { - mod inner { - use super::*; // should go before the ambiguous glob imports - } - - use crate::*; - pub use crate::*; -} - -fn main() {} diff --git a/tests/ui/lifetimes/mut-ref-owned-suggestion.rs b/tests/ui/lifetimes/mut-ref-owned-suggestion.rs deleted file mode 100644 index ae5e8f6658b6..000000000000 --- a/tests/ui/lifetimes/mut-ref-owned-suggestion.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Regression test for -//! Tests that `&mut T` suggests `T`, not `mut T`, `&mut str` suggests `String`, not `str`, -//! when recommending an owned value. -fn with_fn(_f: impl Fn() -> &mut ()) {} -//~^ ERROR: missing lifetime specifier - -fn with_ref_mut_str(_f: impl Fn() -> &mut str) {} -//~^ ERROR: missing lifetime specifier - -fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { - //~^ ERROR: missing lifetime specifier - 2 -} - -fn with_dyn(_f: Box &mut i32>) {} -//~^ ERROR: missing lifetime specifier - -fn trait_bound &mut i32>(_f: F) {} -//~^ ERROR: missing lifetime specifier - -fn nested_result(_f: impl Fn() -> Result<&mut i32, ()>) {} -//~^ ERROR: missing lifetime specifier - -struct Holder &mut i32> { - //~^ ERROR: missing lifetime specifier - f: F, -} - -fn main() {} diff --git a/tests/ui/lifetimes/mut-ref-owned-suggestion.stderr b/tests/ui/lifetimes/mut-ref-owned-suggestion.stderr deleted file mode 100644 index a3e58331342a..000000000000 --- a/tests/ui/lifetimes/mut-ref-owned-suggestion.stderr +++ /dev/null @@ -1,137 +0,0 @@ -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:4:29 - | -LL | fn with_fn(_f: impl Fn() -> &mut ()) {} - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | fn with_fn(_f: impl Fn() -> &'static mut ()) {} - | +++++++ -help: instead, you are more likely to want to return an owned value - | -LL - fn with_fn(_f: impl Fn() -> &mut ()) {} -LL + fn with_fn(_f: impl Fn() -> ()) {} - | - -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:7:38 - | -LL | fn with_ref_mut_str(_f: impl Fn() -> &mut str) {} - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | fn with_ref_mut_str(_f: impl Fn() -> &'static mut str) {} - | +++++++ -help: instead, you are more likely to want to return an owned value - | -LL - fn with_ref_mut_str(_f: impl Fn() -> &mut str) {} -LL + fn with_ref_mut_str(_f: impl Fn() -> String) {} - | - -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:10:40 - | -LL | fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from - = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | fn with_fn_has_return(_f: impl Fn() -> &'static mut ()) -> i32 { - | +++++++ -help: consider making the bound lifetime-generic with a new `'a` lifetime - | -LL - fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { -LL + fn with_fn_has_return(_f: impl for<'a> Fn() -> &'a ()) -> i32 { - | -help: consider introducing a named lifetime parameter - | -LL - fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { -LL + fn with_fn_has_return<'a>(_f: impl Fn() -> &'a ()) -> i32 { - | -help: alternatively, you might want to return an owned value - | -LL - fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { -LL + fn with_fn_has_return(_f: impl Fn() -> ()) -> i32 { - | - -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:15:33 - | -LL | fn with_dyn(_f: Box &mut i32>) {} - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | fn with_dyn(_f: Box &'static mut i32>) {} - | +++++++ -help: instead, you are more likely to want to return an owned value - | -LL - fn with_dyn(_f: Box &mut i32>) {} -LL + fn with_dyn(_f: Box i32>) {} - | - -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:18:27 - | -LL | fn trait_bound &mut i32>(_f: F) {} - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | fn trait_bound &'static mut i32>(_f: F) {} - | +++++++ -help: instead, you are more likely to want to change the argument to be borrowed... - | -LL | fn trait_bound &mut i32>(_f: &F) {} - | + -help: ...or alternatively, you might want to return an owned value - | -LL - fn trait_bound &mut i32>(_f: F) {} -LL + fn trait_bound i32>(_f: F) {} - | - -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:21:42 - | -LL | fn nested_result(_f: impl Fn() -> Result<&mut i32, ()>) {} - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | fn nested_result(_f: impl Fn() -> Result<&'static mut i32, ()>) {} - | +++++++ -help: instead, you are more likely to want to return an owned value - | -LL - fn nested_result(_f: impl Fn() -> Result<&mut i32, ()>) {} -LL + fn nested_result(_f: impl Fn() -> Result) {} - | - -error[E0106]: missing lifetime specifier - --> $DIR/mut-ref-owned-suggestion.rs:24:26 - | -LL | struct Holder &mut i32> { - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -LL | struct Holder &'static mut i32> { - | +++++++ -help: instead, you are more likely to want to return an owned value - | -LL - struct Holder &mut i32> { -LL + struct Holder i32> { - | - -error: aborting due to 7 previous errors - -For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.rs b/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.rs deleted file mode 100644 index 4bf92a2c1c18..000000000000 --- a/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Regression test for https://github.com/rust-lang/rust/issues/65866. - -mod plain { - struct Foo; - - struct Re<'a> { - _data: &'a u16, - } - - trait Bar { - fn bar(&self, r: &mut Re); - //~^ NOTE expected - //~| NOTE `Re` here is elided as `Re<'_>` - } - - impl Bar for Foo { - fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a>) {} - //~^ ERROR `impl` item signature doesn't match `trait` item signature - //~| NOTE expected signature - //~| NOTE found - //~| HELP the lifetime requirements - //~| HELP verify the lifetime relationships - } -} - -mod with_type_args { - struct Foo; - - struct Re<'a, T> { - _data: (&'a u16, T), - } - - trait Bar { - fn bar(&self, r: &mut Re); - //~^ NOTE expected - //~| NOTE `Re` here is elided as `Re<'_, u8>` - } - - impl Bar for Foo { - fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a, u8>) {} - //~^ ERROR `impl` item signature doesn't match `trait` item signature - //~| NOTE expected signature - //~| NOTE found - //~| HELP the lifetime requirements - //~| HELP verify the lifetime relationships - } -} - -fn main() {} diff --git a/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.stderr b/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.stderr deleted file mode 100644 index db69b4f3656e..000000000000 --- a/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.stderr +++ /dev/null @@ -1,40 +0,0 @@ -error: `impl` item signature doesn't match `trait` item signature - --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:17:9 - | -LL | fn bar(&self, r: &mut Re); - | -------------------------- expected `fn(&'1 plain::Foo, &'2 mut plain::Re<'3>)` -... -LL | fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 plain::Foo, &'2 mut plain::Re<'1>)` - | - = note: expected signature `fn(&'1 plain::Foo, &'2 mut plain::Re<'3>)` - found signature `fn(&'1 plain::Foo, &'2 mut plain::Re<'1>)` - = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` - = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output -note: `Re` here is elided as `Re<'_>` - --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:11:31 - | -LL | fn bar(&self, r: &mut Re); - | ^^ - -error: `impl` item signature doesn't match `trait` item signature - --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:40:9 - | -LL | fn bar(&self, r: &mut Re); - | ------------------------------ expected `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'3, u8>)` -... -LL | fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a, u8>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'1, u8>)` - | - = note: expected signature `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'3, u8>)` - found signature `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'1, u8>)` - = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` - = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output -note: `Re` here is elided as `Re<'_, u8>` - --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:34:31 - | -LL | fn bar(&self, r: &mut Re); - | ^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/proc-macro/pretty-print-hack-hide.rs b/tests/ui/proc-macro/pretty-print-hack-hide.rs new file mode 100644 index 000000000000..fd98f16a780e --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack-hide.rs @@ -0,0 +1,12 @@ +//@ proc-macro: test-macros.rs +//@ compile-flags: -Z span-debug +//@ check-pass + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] extern crate test_macros; + +include!("pretty-print-hack/rental-0.5.6/src/lib.rs"); + +fn main() {} diff --git a/tests/ui/proc-macro/pretty-print-hack-hide.stdout b/tests/ui/proc-macro/pretty-print-hack-hide.stdout new file mode 100644 index 000000000000..ea796bb26976 --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack-hide.stdout @@ -0,0 +1,21 @@ +PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input } +PRINT-DERIVE INPUT (DEBUG): TokenStream [ + Ident { + ident: "enum", + span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:1: 4:5 (#0), + }, + Ident { + ident: "ProceduralMasqueradeDummyType", + span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:6: 4:35 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Ident { + ident: "Input", + span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:13:5: 13:10 (#0), + }, + ], + span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:36: 14:2 (#0), + }, +] diff --git a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr new file mode 100644 index 000000000000..889cd0c90ebb --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr @@ -0,0 +1,6 @@ +error: using an old version of `rental` + | + = note: older versions of the `rental` crate no longer compile; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + +error: aborting due to 1 previous error + diff --git a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr new file mode 100644 index 000000000000..889cd0c90ebb --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr @@ -0,0 +1,6 @@ +error: using an old version of `rental` + | + = note: older versions of the `rental` crate no longer compile; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + +error: aborting due to 1 previous error + diff --git a/tests/ui/proc-macro/pretty-print-hack-show.rs b/tests/ui/proc-macro/pretty-print-hack-show.rs new file mode 100644 index 000000000000..08e26c811427 --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack-show.rs @@ -0,0 +1,21 @@ +//@ proc-macro: test-macros.rs +//@ compile-flags: -Z span-debug +//@ revisions: local remapped +//@ [remapped] remap-src-base + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] extern crate test_macros; + +mod first { + include!("pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs"); +} + +mod second { + include!("pretty-print-hack/rental-0.5.5/src/lib.rs"); +} + +fn main() {} + +//~? ERROR using an old version of `rental` diff --git a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs new file mode 100644 index 000000000000..a27176a38e22 --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs @@ -0,0 +1,14 @@ +//@ ignore-auxiliary (used by `../../../pretty-print-hack-show.rs`) + +#[derive(Print)] +enum ProceduralMasqueradeDummyType { +//~^ ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously + Input +} diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs new file mode 100644 index 000000000000..a27176a38e22 --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs @@ -0,0 +1,14 @@ +//@ ignore-auxiliary (used by `../../../pretty-print-hack-show.rs`) + +#[derive(Print)] +enum ProceduralMasqueradeDummyType { +//~^ ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously + Input +} diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs new file mode 100644 index 000000000000..765ee4be656e --- /dev/null +++ b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs @@ -0,0 +1,14 @@ +//@ ignore-auxiliary (used by `../../../pretty-print-hack/hide.rs`) + +#[derive(Print)] +enum ProceduralMasqueradeDummyType { +//~^ ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously +//~| ERROR using +//~| WARN this was previously + Input +} diff --git a/tests/ui/resolve/exported-macro-in-mod-147958.rs b/tests/ui/resolve/exported-macro-in-mod-147958.rs deleted file mode 100644 index 5003c410b692..000000000000 --- a/tests/ui/resolve/exported-macro-in-mod-147958.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Regression test for - -//@ check-pass - -#![feature(decl_macro)] - -macro_rules! exported { - () => { - #[macro_export] - macro_rules! exported { - () => {}; - } - }; -} -use inner1::*; -exported!(); -mod inner1 { - pub macro exported() {} -} - -fn main() {} diff --git a/tests/ui/test-attrs/issue-109816.rs b/tests/ui/test-attrs/issue-109816.rs index f40f99946da1..c7caae67fefa 100644 --- a/tests/ui/test-attrs/issue-109816.rs +++ b/tests/ui/test-attrs/issue-109816.rs @@ -1,5 +1,4 @@ //@ compile-flags: --test -//@ reference: attributes.testing.test.allowed-positions fn align_offset_weird_strides() { #[test] diff --git a/tests/ui/test-attrs/issue-109816.stderr b/tests/ui/test-attrs/issue-109816.stderr index 118c8d878290..270f4e0a6668 100644 --- a/tests/ui/test-attrs/issue-109816.stderr +++ b/tests/ui/test-attrs/issue-109816.stderr @@ -1,5 +1,5 @@ error: the `#[test]` attribute may only be used on a free function - --> $DIR/issue-109816.rs:5:5 + --> $DIR/issue-109816.rs:4:5 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions diff --git a/tests/ui/test-attrs/test-attr-non-associated-functions.rs b/tests/ui/test-attrs/test-attr-non-associated-functions.rs index 9d28f59888a0..4bf337d0f1b3 100644 --- a/tests/ui/test-attrs/test-attr-non-associated-functions.rs +++ b/tests/ui/test-attrs/test-attr-non-associated-functions.rs @@ -1,5 +1,4 @@ //@ compile-flags:--test -//@ reference: attributes.testing.test.allowed-positions struct A {} diff --git a/tests/ui/test-attrs/test-attr-non-associated-functions.stderr b/tests/ui/test-attrs/test-attr-non-associated-functions.stderr index fda28ee28a07..13914971b558 100644 --- a/tests/ui/test-attrs/test-attr-non-associated-functions.stderr +++ b/tests/ui/test-attrs/test-attr-non-associated-functions.stderr @@ -1,5 +1,5 @@ error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-attr-non-associated-functions.rs:7:5 + --> $DIR/test-attr-non-associated-functions.rs:6:5 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -11,7 +11,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-attr-non-associated-functions.rs:12:5 + --> $DIR/test-attr-non-associated-functions.rs:11:5 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions diff --git a/tests/ui/test-attrs/test-function-signature.rs b/tests/ui/test-attrs/test-function-signature.rs index 4a6c0e8450ce..0f43245be6f6 100644 --- a/tests/ui/test-attrs/test-function-signature.rs +++ b/tests/ui/test-attrs/test-function-signature.rs @@ -1,5 +1,4 @@ //@ compile-flags: --test -//@ reference: attributes.testing.test.allowed-positions #[test] fn foo() -> Result<(), ()> { diff --git a/tests/ui/test-attrs/test-function-signature.stderr b/tests/ui/test-attrs/test-function-signature.stderr index 7fdaaed1aebc..55d09970b320 100644 --- a/tests/ui/test-attrs/test-function-signature.stderr +++ b/tests/ui/test-attrs/test-function-signature.stderr @@ -1,29 +1,29 @@ error: functions used as tests can not have any arguments - --> $DIR/test-function-signature.rs:15:1 + --> $DIR/test-function-signature.rs:14:1 | LL | fn baz(val: i32) {} | ^^^^^^^^^^^^^^^^^^^ error: functions used as tests can not have any non-lifetime generic parameters - --> $DIR/test-function-signature.rs:23:1 + --> $DIR/test-function-signature.rs:22:1 | LL | fn type_generic() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions used as tests can not have any non-lifetime generic parameters - --> $DIR/test-function-signature.rs:26:1 + --> $DIR/test-function-signature.rs:25:1 | LL | fn const_generic() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions used as tests can not have any arguments - --> $DIR/test-function-signature.rs:31:5 + --> $DIR/test-function-signature.rs:30:5 | LL | fn foo(arg: ()) {} | ^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `i32: Termination` is not satisfied - --> $DIR/test-function-signature.rs:10:13 + --> $DIR/test-function-signature.rs:9:13 | LL | #[test] | ------- in this attribute macro expansion diff --git a/tests/ui/test-attrs/test-on-not-fn.rs b/tests/ui/test-attrs/test-on-not-fn.rs index 57ae2b19cf5f..16e9cd8d5b8d 100644 --- a/tests/ui/test-attrs/test-on-not-fn.rs +++ b/tests/ui/test-attrs/test-on-not-fn.rs @@ -1,5 +1,4 @@ //@ compile-flags: --test -//@ reference: attributes.testing.test.allowed-positions #[test] //~ ERROR: the `#[test]` attribute may only be used on a free function mod test {} diff --git a/tests/ui/test-attrs/test-on-not-fn.stderr b/tests/ui/test-attrs/test-on-not-fn.stderr index 22e479268856..db8bed100a63 100644 --- a/tests/ui/test-attrs/test-on-not-fn.stderr +++ b/tests/ui/test-attrs/test-on-not-fn.stderr @@ -1,5 +1,5 @@ error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:4:1 + --> $DIR/test-on-not-fn.rs:3:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -13,7 +13,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:7:1 + --> $DIR/test-on-not-fn.rs:6:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -33,7 +33,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:21:1 + --> $DIR/test-on-not-fn.rs:20:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -47,7 +47,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:24:1 + --> $DIR/test-on-not-fn.rs:23:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -61,7 +61,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:27:1 + --> $DIR/test-on-not-fn.rs:26:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -75,7 +75,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:30:1 + --> $DIR/test-on-not-fn.rs:29:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -89,7 +89,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:33:1 + --> $DIR/test-on-not-fn.rs:32:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -103,7 +103,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:36:1 + --> $DIR/test-on-not-fn.rs:35:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -119,7 +119,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:41:1 + --> $DIR/test-on-not-fn.rs:40:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -133,7 +133,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:44:1 + --> $DIR/test-on-not-fn.rs:43:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -150,7 +150,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:51:1 + --> $DIR/test-on-not-fn.rs:50:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -168,7 +168,7 @@ LL + #[cfg(test)] | warning: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:62:1 + --> $DIR/test-on-not-fn.rs:61:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions diff --git a/tests/ui/test-attrs/test-passed.rs b/tests/ui/test-attrs/test-passed.rs index 034051e4eb6d..959470adcc42 100644 --- a/tests/ui/test-attrs/test-passed.rs +++ b/tests/ui/test-attrs/test-passed.rs @@ -4,7 +4,6 @@ //@ run-pass //@ check-run-results //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ reference: attributes.testing.test.success // Tests the output of the test harness with only passed tests. diff --git a/tests/ui/test-attrs/test-should-panic-attr.rs b/tests/ui/test-attrs/test-should-panic-attr.rs index b095099daad0..e6de07d00941 100644 --- a/tests/ui/test-attrs/test-should-panic-attr.rs +++ b/tests/ui/test-attrs/test-should-panic-attr.rs @@ -1,5 +1,4 @@ //@ compile-flags: --test -//@ reference: attributes.testing.should_panic.syntax #[test] #[should_panic = "foo"] diff --git a/tests/ui/test-attrs/test-should-panic-attr.stderr b/tests/ui/test-attrs/test-should-panic-attr.stderr index 48f6b0d37cb1..475a55ad0cbc 100644 --- a/tests/ui/test-attrs/test-should-panic-attr.stderr +++ b/tests/ui/test-attrs/test-should-panic-attr.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:11:1 + --> $DIR/test-should-panic-attr.rs:10:1 | LL | #[should_panic(expected)] | ^^^^^^^^^^^^^^^--------^^ @@ -19,7 +19,7 @@ LL + #[should_panic] | error[E0539]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:20:1 + --> $DIR/test-should-panic-attr.rs:19:1 | LL | #[should_panic(expect)] | ^^^^^^^^^^^^^^--------^ @@ -39,7 +39,7 @@ LL + #[should_panic] | error[E0539]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:29:1 + --> $DIR/test-should-panic-attr.rs:28:1 | LL | #[should_panic(expected(foo, bar))] | ^^^^^^^^^^^^^^^------------------^^ @@ -60,7 +60,7 @@ LL + #[should_panic] | error[E0805]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:38:1 + --> $DIR/test-should-panic-attr.rs:37:1 | LL | #[should_panic(expected = "foo", bar)] | ^^^^^^^^^^^^^^-----------------------^ diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.rs b/tests/ui/test-attrs/test-should-panic-failed-show-span.rs index f8c1840ab79f..22a6f4a835e2 100644 --- a/tests/ui/test-attrs/test-should-panic-failed-show-span.rs +++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.rs @@ -8,7 +8,6 @@ //@ normalize-stdout: "TypeId\(0x[0-9a-f]+\)" -> "TypeId($$HEX)" //@ needs-threads //@ needs-unwind (panic) -//@ reference: attributes.testing.should_panic.expected #[test] #[should_panic] diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr index 398479f15fa2..ab36bc2beb9e 100644 --- a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr +++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr @@ -1,13 +1,13 @@ -thread 'should_panic_with_any_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:16:5: +thread 'should_panic_with_any_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:15:5: Panic! note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread 'should_panic_with_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:22:5: +thread 'should_panic_with_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:21:5: message -thread 'should_panic_with_substring_panics_with_incorrect_string' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:40:5: +thread 'should_panic_with_substring_panics_with_incorrect_string' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:39:5: ZOMGWTFBBQ -thread 'should_panic_with_substring_panics_with_non_string_value' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:47:5: +thread 'should_panic_with_substring_panics_with_non_string_value' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:46:5: Box diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout index c28403a11e8e..492f54debc82 100644 --- a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout +++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout @@ -10,9 +10,9 @@ test should_panic_with_substring_panics_with_non_string_value - should panic ... failures: ---- should_panic_with_any_message_does_not_panic stdout ---- -note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:27:4 +note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:26:4 ---- should_panic_with_message_does_not_panic stdout ---- -note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:33:4 +note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:32:4 ---- should_panic_with_substring_panics_with_incorrect_string stdout ---- note: panic did not contain expected string panic message: "ZOMGWTFBBQ" diff --git a/tests/ui/test-attrs/test-vs-cfg-test.rs b/tests/ui/test-attrs/test-vs-cfg-test.rs index 634511fdff39..d7d9e61103c9 100644 --- a/tests/ui/test-attrs/test-vs-cfg-test.rs +++ b/tests/ui/test-attrs/test-vs-cfg-test.rs @@ -1,6 +1,5 @@ //@ run-pass //@ compile-flags: --cfg test -//@ reference: cfg.test // Make sure `--cfg test` does not inject test harness diff --git a/tests/ui/traits/const-traits/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs index cd74bb45f651..6d0a84797ea2 100644 --- a/tests/ui/traits/const-traits/staged-api.rs +++ b/tests/ui/traits/const-traits/staged-api.rs @@ -5,7 +5,7 @@ #![feature(local_feature)] #![feature(const_trait_impl)] #![feature(staged_api)] -#![feature(rustc_attrs)] +#![feature(rustc_allow_const_fn_unstable)] #![stable(feature = "rust1", since = "1.0.0")] //@ aux-build: staged-api.rs diff --git a/tests/ui/traits/final/final-kw.gated.stderr b/tests/ui/traits/final/final-kw.gated.stderr index 62a39d7ca202..a7967ebf08e2 100644 --- a/tests/ui/traits/final/final-kw.gated.stderr +++ b/tests/ui/traits/final/final-kw.gated.stderr @@ -4,7 +4,7 @@ error[E0658]: `final` on trait functions is experimental LL | final fn foo() {} | ^^^^^ | - = note: see issue #131179 for more information + = note: see issue #1 for more information = help: add `#![feature(final_associated_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/traits/final/final-kw.ungated.stderr b/tests/ui/traits/final/final-kw.ungated.stderr index 62a39d7ca202..a7967ebf08e2 100644 --- a/tests/ui/traits/final/final-kw.ungated.stderr +++ b/tests/ui/traits/final/final-kw.ungated.stderr @@ -4,7 +4,7 @@ error[E0658]: `final` on trait functions is experimental LL | final fn foo() {} | ^^^^^ | - = note: see issue #131179 for more information + = note: see issue #1 for more information = help: add `#![feature(final_associated_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/typos.toml b/typos.toml index 3c95a45d572d..e486a7c1722c 100644 --- a/typos.toml +++ b/typos.toml @@ -46,7 +46,6 @@ unstalled = "unstalled" # short for un-stalled # # tidy-alphabetical-start definitinon = "definition" -dependy = "" similarlty = "similarity" # tidy-alphabetical-end