diff options
122 files changed, 971 insertions, 719 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 9874809ea2b..146f55f95c2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -1,4 +1,5 @@ use std::collections::hash_map::Entry; +use std::marker::PhantomData; use std::ops::Range; use rustc_data_structures::fx::FxHashMap; @@ -14,7 +15,7 @@ use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx}; use super::operand::{OperandRef, OperandValue}; use super::place::{PlaceRef, PlaceValue}; -use super::{FunctionCx, LocalRef}; +use super::{FunctionCx, LocalRef, PerLocalVarDebugInfoIndexVec}; use crate::traits::*; pub struct FunctionDebugContext<'tcx, S, L> { @@ -48,6 +49,17 @@ pub struct PerLocalVarDebugInfo<'tcx, D> { pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>, } +/// Information needed to emit a constant. +pub struct ConstDebugInfo<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { + pub name: String, + pub source_info: mir::SourceInfo, + pub operand: OperandRef<'tcx, Bx::Value>, + pub dbg_var: Bx::DIVariable, + pub dbg_loc: Bx::DILocation, + pub fragment: Option<Range<Size>>, + pub _phantom: PhantomData<&'a ()>, +} + #[derive(Clone, Copy, Debug)] pub struct DebugScope<S, L> { pub dbg_scope: S, @@ -427,11 +439,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub(crate) fn debug_introduce_locals(&self, bx: &mut Bx) { + pub(crate) fn debug_introduce_locals( + &self, + bx: &mut Bx, + consts: Vec<ConstDebugInfo<'a, 'tcx, Bx>>, + ) { if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() { for local in self.locals.indices() { self.debug_introduce_local(bx, local); } + + for ConstDebugInfo { name, source_info, operand, dbg_var, dbg_loc, fragment, .. } in + consts.into_iter() + { + self.set_debug_loc(bx, source_info); + let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx); + bx.clear_dbg_loc(); + + bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], fragment); + } } } @@ -439,7 +465,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub(crate) fn compute_per_local_var_debug_info( &self, bx: &mut Bx, - ) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> { + ) -> Option<( + PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>, + Vec<ConstDebugInfo<'a, 'tcx, Bx>>, + )> { let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full; let target_is_msvc = self.cx.sess().target.is_like_msvc; @@ -449,6 +478,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } let mut per_local = IndexVec::from_elem(vec![], &self.mir.local_decls); + let mut constants = vec![]; let mut params_seen: FxHashMap<_, Bx::DIVariable> = Default::default(); for var in &self.mir.var_debug_info { let dbg_scope_and_span = if full_debug_info { @@ -545,23 +575,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; let operand = self.eval_mir_constant_to_operand(bx, &c); - self.set_debug_loc(bx, var.source_info); - let base = - Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx); - bx.clear_dbg_loc(); - - bx.dbg_var_addr( + constants.push(ConstDebugInfo { + name: var.name.to_string(), + source_info: var.source_info, + operand, dbg_var, dbg_loc, - base.val.llval, - Size::ZERO, - &[], fragment, - ); + _phantom: PhantomData, + }); } } } } - Some(per_local) + Some((per_local, constants)) } } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 202baddec72..c4fb24aa625 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -41,6 +41,9 @@ enum CachedLlbb<T> { Skip, } +type PerLocalVarDebugInfoIndexVec<'tcx, V> = + IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, V>>>; + /// Master context for codegenning from MIR. pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { instance: Instance<'tcx>, @@ -107,8 +110,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// All `VarDebugInfo` from the MIR body, partitioned by `Local`. /// This is `None` if no variable debuginfo/names are needed. - per_local_var_debug_info: - Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>>, + per_local_var_debug_info: Option<PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>>, /// Caller location propagated if this function has `#[track_caller]`. caller_location: Option<OperandRef<'tcx, Bx::Value>>, @@ -216,7 +218,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // monomorphization, and if there is an error during collection then codegen never starts -- so // we don't have to do it again. - fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx); + let (per_local_var_debug_info, consts_debug_info) = + fx.compute_per_local_var_debug_info(&mut start_bx).unzip(); + fx.per_local_var_debug_info = per_local_var_debug_info; let traversal_order = traversal::mono_reachable_reverse_postorder(mir, cx.tcx(), instance); let memory_locals = analyze::non_ssa_locals(&fx, &traversal_order); @@ -268,7 +272,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx.initialize_locals(local_values); // Apply debuginfo to the newly allocated locals. - fx.debug_introduce_locals(&mut start_bx); + fx.debug_introduce_locals(&mut start_bx, consts_debug_info.unwrap_or_default()); // If the backend supports coverage, and coverage is enabled for this function, // do any necessary start-of-function codegen (e.g. locals for MC/DC bitmaps). diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index e1b60597997..2cbf242fcf2 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -317,7 +317,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { { self.error_emitted = Some(guar); } - self.check_op_spanned(ops::StaticAccess, span) } /// Returns whether this place can possibly escape the evaluation of the current const/static diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index df8313d0e70..6eb33c29e1d 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -16,7 +16,6 @@ use rustc_middle::ty::{ suggest_constraining_type_param, }; use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind}; -use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::{BytePos, Pos, Span, Symbol}; use rustc_trait_selection::traits::SelectionContext; @@ -477,33 +476,6 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast { } } -/// An access to a (non-thread-local) `static`. -#[derive(Debug)] -pub(crate) struct StaticAccess; -impl<'tcx> NonConstOp<'tcx> for StaticAccess { - fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status { - if let hir::ConstContext::Static(_) = ccx.const_kind() { - Status::Allowed - } else { - Status::Unstable(sym::const_refs_to_static) - } - } - - #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - let mut err = feature_err( - &ccx.tcx.sess, - sym::const_refs_to_static, - span, - format!("referencing statics in {}s is unstable", ccx.const_kind(),), - ); - err - .note("`static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.") - .help("to fix this, the value can be extracted to a `const` and then used."); - err - } -} - /// An access to a thread-local `static`. #[derive(Debug)] pub(crate) struct ThreadLocalAccess; diff --git a/compiler/rustc_error_codes/src/error_codes/E0013.md b/compiler/rustc_error_codes/src/error_codes/E0013.md index 9f4848343ff..c4d65225ece 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0013.md +++ b/compiler/rustc_error_codes/src/error_codes/E0013.md @@ -5,7 +5,7 @@ variable cannot refer to a static variable. Erroneous code example: -```compile_fail,E0658 +``` static X: i32 = 42; const Y: i32 = X; ``` diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 70e92f545c6..5ff002dd7d2 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -151,6 +151,8 @@ declare_features! ( (accepted, const_raw_ptr_deref, "1.58.0", Some(51911)), /// Allows references to types with interior mutability within constants (accepted, const_refs_to_cell, "CURRENT_RUSTC_VERSION", Some(80384)), + /// Allows creating pointers and references to `static` items in constants. + (accepted, const_refs_to_static, "CURRENT_RUSTC_VERSION", Some(119618)), /// Allows implementing `Copy` for closures where possible (RFC 2132). (accepted, copy_closures, "1.26.0", Some(44490)), /// Allows `crate` in paths. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 63b4b272f76..91b072b56db 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -407,8 +407,6 @@ declare_features! ( (unstable, const_for, "1.56.0", Some(87575)), /// Be more precise when looking for live drops in a const context. (unstable, const_precise_live_drops, "1.46.0", Some(73255)), - /// Allows creating pointers and references to `static` items in constants. - (unstable, const_refs_to_static, "1.78.0", Some(119618)), /// Allows `impl const Trait for T` syntax. (unstable, const_trait_impl, "1.42.0", Some(67792)), /// Allows the `?` operator in const contexts. diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index c64741625a4..7557219aaa6 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -1,8 +1,9 @@ -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_hir as hir; use rustc_infer::traits::util; +use rustc_middle::ty::fold::shift_vars; use rustc_middle::ty::{ - self, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + self, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_middle::{bug, span_bug}; use rustc_span::Span; @@ -42,14 +43,18 @@ fn associated_type_bounds<'tcx>( let trait_def_id = tcx.local_parent(assoc_item_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id); - let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { - match pred.kind().skip_binder() { - ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty, - ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty() == item_ty, - ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty, - _ => false, - } - }); + let item_trait_ref = ty::TraitRef::identity(tcx, tcx.parent(assoc_item_def_id.to_def_id())); + let bounds_from_parent = + trait_predicates.predicates.iter().copied().filter_map(|(clause, span)| { + remap_gat_vars_and_recurse_into_nested_projections( + tcx, + filter, + item_trait_ref, + assoc_item_def_id, + span, + clause, + ) + }); let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses(tcx).chain(bounds_from_parent)); debug!( @@ -63,6 +68,226 @@ fn associated_type_bounds<'tcx>( all_bounds } +/// The code below is quite involved, so let me explain. +/// +/// We loop here, because we also want to collect vars for nested associated items as +/// well. For example, given a clause like `Self::A::B`, we want to add that to the +/// item bounds for `A`, so that we may use that bound in the case that `Self::A::B` is +/// rigid. +/// +/// Secondly, regarding bound vars, when we see a where clause that mentions a GAT +/// like `for<'a, ...> Self::Assoc<'a, ...>: Bound<'b, ...>`, we want to turn that into +/// an item bound on the GAT, where all of the GAT args are substituted with the GAT's +/// param regions, and then keep all of the other late-bound vars in the bound around. +/// We need to "compress" the binder so that it doesn't mention any of those vars that +/// were mapped to params. +fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( + tcx: TyCtxt<'tcx>, + filter: PredicateFilter, + item_trait_ref: ty::TraitRef<'tcx>, + assoc_item_def_id: LocalDefId, + span: Span, + clause: ty::Clause<'tcx>, +) -> Option<(ty::Clause<'tcx>, Span)> { + let mut clause_ty = match clause.kind().skip_binder() { + ty::ClauseKind::Trait(tr) => tr.self_ty(), + ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty(), + ty::ClauseKind::TypeOutlives(outlives) => outlives.0, + _ => return None, + }; + + let gat_vars = loop { + if let ty::Alias(ty::Projection, alias_ty) = *clause_ty.kind() { + if alias_ty.trait_ref(tcx) == item_trait_ref + && alias_ty.def_id == assoc_item_def_id.to_def_id() + { + // We have found the GAT in question... + // Return the vars, since we may need to remap them. + break &alias_ty.args[item_trait_ref.args.len()..]; + } else { + // Only collect *self* type bounds if the filter is for self. + match filter { + PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { + return None; + } + PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {} + } + + clause_ty = alias_ty.self_ty(); + continue; + } + } + + return None; + }; + + // Special-case: No GAT vars, no mapping needed. + if gat_vars.is_empty() { + return Some((clause, span)); + } + + // First, check that all of the GAT args are substituted with a unique late-bound arg. + // If we find a duplicate, then it can't be mapped to the definition's params. + let mut mapping = FxIndexMap::default(); + let generics = tcx.generics_of(assoc_item_def_id); + for (param, var) in std::iter::zip(&generics.own_params, gat_vars) { + let existing = match var.unpack() { + ty::GenericArgKind::Lifetime(re) => { + if let ty::RegionKind::ReBound(ty::INNERMOST, bv) = re.kind() { + mapping.insert(bv.var, tcx.mk_param_from_def(param)) + } else { + return None; + } + } + ty::GenericArgKind::Type(ty) => { + if let ty::Bound(ty::INNERMOST, bv) = *ty.kind() { + mapping.insert(bv.var, tcx.mk_param_from_def(param)) + } else { + return None; + } + } + ty::GenericArgKind::Const(ct) => { + if let ty::ConstKind::Bound(ty::INNERMOST, bv) = ct.kind() { + mapping.insert(bv, tcx.mk_param_from_def(param)) + } else { + return None; + } + } + }; + + if existing.is_some() { + return None; + } + } + + // Finally, map all of the args in the GAT to the params we expect, and compress + // the remaining late-bound vars so that they count up from var 0. + let mut folder = + MapAndCompressBoundVars { tcx, binder: ty::INNERMOST, still_bound_vars: vec![], mapping }; + let pred = clause.kind().skip_binder().fold_with(&mut folder); + + Some(( + ty::Binder::bind_with_vars(pred, tcx.mk_bound_variable_kinds(&folder.still_bound_vars)) + .upcast(tcx), + span, + )) +} + +/// Given some where clause like `for<'b, 'c> <Self as Trait<'a_identity>>::Gat<'b>: Bound<'c>`, +/// the mapping will map `'b` back to the GAT's `'b_identity`. Then we need to compress the +/// remaining bound var `'c` to index 0. +/// +/// This folder gives us: `for<'c> <Self as Trait<'a_identity>>::Gat<'b_identity>: Bound<'c>`, +/// which is sufficient for an item bound for `Gat`, since all of the GAT's args are identity. +struct MapAndCompressBoundVars<'tcx> { + tcx: TyCtxt<'tcx>, + /// How deep are we? Makes sure we don't touch the vars of nested binders. + binder: ty::DebruijnIndex, + /// List of bound vars that remain unsubstituted because they were not + /// mentioned in the GAT's args. + still_bound_vars: Vec<ty::BoundVariableKind>, + /// Subtle invariant: If the `GenericArg` is bound, then it should be + /// stored with the debruijn index of `INNERMOST` so it can be shifted + /// correctly during substitution. + mapping: FxIndexMap<ty::BoundVar, ty::GenericArg<'tcx>>, +} + +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> + where + ty::Binder<'tcx, T>: TypeSuperFoldable<TyCtxt<'tcx>>, + { + self.binder.shift_in(1); + let out = t.super_fold_with(self); + self.binder.shift_out(1); + out + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.has_bound_vars() { + return ty; + } + + if let ty::Bound(binder, old_bound) = *ty.kind() + && self.binder == binder + { + let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) { + mapped.expect_ty() + } else { + // If we didn't find a mapped generic, then make a new one. + // Allocate a new var idx, and insert a new bound ty. + let var = ty::BoundVar::from_usize(self.still_bound_vars.len()); + self.still_bound_vars.push(ty::BoundVariableKind::Ty(old_bound.kind)); + let mapped = Ty::new_bound(self.tcx, ty::INNERMOST, ty::BoundTy { + var, + kind: old_bound.kind, + }); + self.mapping.insert(old_bound.var, mapped.into()); + mapped + }; + + shift_vars(self.tcx, mapped, self.binder.as_u32()) + } else { + ty.super_fold_with(self) + } + } + + fn fold_region(&mut self, re: ty::Region<'tcx>) -> ty::Region<'tcx> { + if let ty::ReBound(binder, old_bound) = re.kind() + && self.binder == binder + { + let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) { + mapped.expect_region() + } else { + let var = ty::BoundVar::from_usize(self.still_bound_vars.len()); + self.still_bound_vars.push(ty::BoundVariableKind::Region(old_bound.kind)); + let mapped = ty::Region::new_bound(self.tcx, ty::INNERMOST, ty::BoundRegion { + var, + kind: old_bound.kind, + }); + self.mapping.insert(old_bound.var, mapped.into()); + mapped + }; + + shift_vars(self.tcx, mapped, self.binder.as_u32()) + } else { + re + } + } + + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + if !ct.has_bound_vars() { + return ct; + } + + if let ty::ConstKind::Bound(binder, old_var) = ct.kind() + && self.binder == binder + { + let mapped = if let Some(mapped) = self.mapping.get(&old_var) { + mapped.expect_const() + } else { + let var = ty::BoundVar::from_usize(self.still_bound_vars.len()); + self.still_bound_vars.push(ty::BoundVariableKind::Const); + let mapped = ty::Const::new_bound(self.tcx, ty::INNERMOST, var); + self.mapping.insert(old_var, mapped.into()); + mapped + }; + + shift_vars(self.tcx, mapped, self.binder.as_u32()) + } else { + ct.super_fold_with(self) + } + } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if !p.has_bound_vars() { p } else { p.super_fold_with(self) } + } +} + /// Opaque types don't inherit bounds from their parent: for return position /// impl trait it isn't possible to write a suitable predicate on the /// containing function and for type-alias impl trait we don't have a backwards diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 375cfccbe9f..a286ccb22c7 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -531,7 +531,7 @@ lint_non_binding_let_multi_suggestion = consider immediately dropping the value lint_non_binding_let_on_drop_type = - non-binding let on a type that implements `Drop` + non-binding let on a type that has a destructor lint_non_binding_let_on_sync_lock = non-binding let on a synchronization lock .label = this lock is not assigned to a binding and is immediately dropped diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index a12a97ee573..abee9ee7869 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -51,7 +51,7 @@ declare_lint! { /// intent. pub LET_UNDERSCORE_DROP, Allow, - "non-binding let on a type that implements `Drop`" + "non-binding let on a type that has a destructor" } declare_lint! { diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 165fb7aa6c3..8f0b1b81276 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -732,12 +732,7 @@ extern "C" LLVMRustResult LLVMRustOptimize( PTO.SLPVectorization = SLPVectorize; PTO.MergeFunctions = MergeFunctions; - // FIXME: We may want to expose this as an option. - bool DebugPassManager = false; - PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(TheModule->getContext(), DebugPassManager); - SI.registerCallbacks(PIC); if (LlvmSelfProfiler) { LLVMSelfProfileInitializeCallbacks(PIC, LlvmSelfProfiler, @@ -784,6 +779,12 @@ extern "C" LLVMRustResult LLVMRustOptimize( CGSCCAnalysisManager CGAM; ModuleAnalysisManager MAM; + // FIXME: We may want to expose this as an option. + bool DebugPassManager = false; + + StandardInstrumentations SI(TheModule->getContext(), DebugPassManager); + SI.registerCallbacks(PIC, &MAM); + if (LLVMPluginsLen) { auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen); SmallVector<StringRef> Plugins; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 19e2679ae4d..969f2528836 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2635,49 +2635,47 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // This shouldn't be common unless manually implementing one of the // traits manually, but don't make it more confusing when it does // happen. - Ok( - if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() - && not_tupled - { - self.report_and_explain_type_error( - TypeTrace::trait_refs( - &obligation.cause, - true, - expected_trait_ref, - found_trait_ref, - ), - ty::error::TypeError::Mismatch, - ) - } else if found.len() == expected.len() { - self.report_closure_arg_mismatch( - span, - found_span, - found_trait_ref, - expected_trait_ref, - obligation.cause.code(), - found_node, - obligation.param_env, - ) - } else { - let (closure_span, closure_arg_span, found) = found_did - .and_then(|did| { - let node = self.tcx.hir().get_if_local(did)?; - let (found_span, closure_arg_span, found) = - self.get_fn_like_arguments(node)?; - Some((Some(found_span), closure_arg_span, found)) - }) - .unwrap_or((found_span, None, found)); - - self.report_arg_count_mismatch( + if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() && not_tupled + { + return Ok(self.report_and_explain_type_error( + TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref), + ty::error::TypeError::Mismatch, + )); + } + if found.len() != expected.len() { + let (closure_span, closure_arg_span, found) = found_did + .and_then(|did| { + let node = self.tcx.hir().get_if_local(did)?; + let (found_span, closure_arg_span, found) = self.get_fn_like_arguments(node)?; + Some((Some(found_span), closure_arg_span, found)) + }) + .unwrap_or((found_span, None, found)); + + // If the coroutine take a single () as its argument, + // the trait argument would found the coroutine take 0 arguments, + // but get_fn_like_arguments would give 1 argument. + // This would result in "Expected to take 1 argument, but it takes 1 argument". + // Check again to avoid this. + if found.len() != expected.len() { + return Ok(self.report_arg_count_mismatch( span, closure_span, expected, found, found_trait_ty.is_closure(), closure_arg_span, - ) - }, - ) + )); + } + } + Ok(self.report_closure_arg_mismatch( + span, + found_span, + found_trait_ref, + expected_trait_ref, + obligation.cause.code(), + found_node, + obligation.param_env, + )) } /// Given some node representing a fn-like thing in the HIR map, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f61a484499f..6421504b896 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -199,7 +199,7 @@ use core::ops::{ DerefPure, DispatchFromDyn, Receiver, }; use core::pin::{Pin, PinCoerceUnsized}; -use core::ptr::{self, NonNull, Unique, addr_of_mut}; +use core::ptr::{self, NonNull, Unique}; use core::task::{Context, Poll}; use core::{borrow, fmt, slice}; @@ -1277,7 +1277,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { #[inline] pub fn into_raw(b: Self) -> *mut T { // Make sure Miri realizes that we transition from a noalias pointer to a raw pointer here. - unsafe { addr_of_mut!(*&mut *Self::into_raw_with_allocator(b).0) } + unsafe { &raw mut *&mut *Self::into_raw_with_allocator(b).0 } } /// Consumes the `Box`, returning a wrapped `NonNull` pointer. @@ -1396,7 +1396,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { // want *no* aliasing requirements here! // In case `A` *is* `Global`, this does not quite have the right behavior; `into_raw` // works around that. - let ptr = addr_of_mut!(**b); + let ptr = &raw mut **b; let alloc = unsafe { ptr::read(&b.1) }; (ptr, alloc) } @@ -1506,7 +1506,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { pub fn as_mut_ptr(b: &mut Self) -> *mut T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing // any references. - ptr::addr_of_mut!(**b) + &raw mut **b } /// Returns a raw pointer to the `Box`'s contents. @@ -1554,7 +1554,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { pub fn as_ptr(b: &Self) -> *const T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing // any references. - ptr::addr_of!(**b) + &raw const **b } /// Returns a reference to the underlying allocator. diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 9baded3a521..78e5aec09b1 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -186,7 +186,7 @@ impl<T: ?Sized> ThinBox<T> { fn with_header(&self) -> &WithHeader<<T as Pointee>::Metadata> { // SAFETY: both types are transparent to `NonNull<u8>` - unsafe { &*(core::ptr::addr_of!(self.ptr) as *const WithHeader<_>) } + unsafe { &*((&raw const self.ptr) as *const WithHeader<_>) } } } diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 78ccb3af66d..5c513d34fc9 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -72,8 +72,8 @@ impl<K, V> LeafNode<K, V> { // be both slightly faster and easier to track in Valgrind. unsafe { // parent_idx, keys, and vals are all MaybeUninit - ptr::addr_of_mut!((*this).parent).write(None); - ptr::addr_of_mut!((*this).len).write(0); + (&raw mut (*this).parent).write(None); + (&raw mut (*this).len).write(0); } } @@ -114,7 +114,7 @@ impl<K, V> InternalNode<K, V> { unsafe { let mut node = Box::<Self, _>::new_uninit_in(alloc); // We only need to initialize the data; the edges are MaybeUninit. - LeafNode::init(ptr::addr_of_mut!((*node.as_mut_ptr()).data)); + LeafNode::init(&raw mut (*node.as_mut_ptr()).data); node.assume_init() } } @@ -525,8 +525,8 @@ impl<'a, K, V, Type> NodeRef<marker::ValMut<'a>, K, V, Type> { // to avoid aliasing with outstanding references to other elements, // in particular, those returned to the caller in earlier iterations. let leaf = Self::as_leaf_ptr(&mut self); - let keys = unsafe { ptr::addr_of!((*leaf).keys) }; - let vals = unsafe { ptr::addr_of_mut!((*leaf).vals) }; + let keys = unsafe { &raw const (*leaf).keys }; + let vals = unsafe { &raw mut (*leaf).vals }; // We must coerce to unsized array pointers because of Rust issue #74679. let keys: *const [_] = keys; let vals: *mut [_] = vals; diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 54669bd310a..0e2c35845e8 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -787,7 +787,7 @@ impl<T, A: Allocator> Rc<T, A> { let strong = unsafe { let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).value), data); + ptr::write(&raw mut (*inner).value, data); let prev_value = (*inner).strong.get(); debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); @@ -1442,7 +1442,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { // SAFETY: This cannot go through Deref::deref or Rc::inner because // this is required to retain raw/mut provenance such that e.g. `get_mut` can // write through the pointer after the Rc is recovered through `from_raw`. - unsafe { ptr::addr_of_mut!((*ptr).value) } + unsafe { &raw mut (*ptr).value } } /// Constructs an `Rc<T, A>` from a raw pointer in the provided allocator. @@ -2042,8 +2042,8 @@ impl<T: ?Sized> Rc<T> { unsafe { debug_assert_eq!(Layout::for_value_raw(inner), layout); - ptr::addr_of_mut!((*inner).strong).write(Cell::new(1)); - ptr::addr_of_mut!((*inner).weak).write(Cell::new(1)); + (&raw mut (*inner).strong).write(Cell::new(1)); + (&raw mut (*inner).weak).write(Cell::new(1)); } Ok(inner) @@ -2072,8 +2072,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { // Copy value as bytes ptr::copy_nonoverlapping( - core::ptr::addr_of!(*src) as *const u8, - ptr::addr_of_mut!((*ptr).value) as *mut u8, + (&raw const *src) as *const u8, + (&raw mut (*ptr).value) as *mut u8, value_size, ); @@ -2107,11 +2107,7 @@ impl<T> Rc<[T]> { unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { unsafe { let ptr = Self::allocate_for_slice(v.len()); - ptr::copy_nonoverlapping( - v.as_ptr(), - ptr::addr_of_mut!((*ptr).value) as *mut T, - v.len(), - ); + ptr::copy_nonoverlapping(v.as_ptr(), (&raw mut (*ptr).value) as *mut T, v.len()); Self::from_ptr(ptr) } } @@ -2149,7 +2145,7 @@ impl<T> Rc<[T]> { let layout = Layout::for_value_raw(ptr); // Pointer to first element - let elems = ptr::addr_of_mut!((*ptr).value) as *mut T; + let elems = (&raw mut (*ptr).value) as *mut T; let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; @@ -2577,7 +2573,7 @@ impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for Rc<T, A> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized, A: Allocator> fmt::Pointer for Rc<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&core::ptr::addr_of!(**self), f) + fmt::Pointer::fmt(&(&raw const **self), f) } } @@ -2718,7 +2714,7 @@ impl<T, A: Allocator> From<Vec<T, A>> for Rc<[T], A> { let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); let rc_ptr = Self::allocate_for_slice_in(len, &alloc); - ptr::copy_nonoverlapping(vec_ptr, ptr::addr_of_mut!((*rc_ptr).value) as *mut T, len); + ptr::copy_nonoverlapping(vec_ptr, (&raw mut (*rc_ptr).value) as *mut T, len); // Create a `Vec<T, &A>` with length 0, to deallocate the buffer // without dropping its contents or the allocator @@ -3084,7 +3080,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> { // SAFETY: if is_dangling returns false, then the pointer is dereferenceable. // The payload may be dropped at this point, and we have to maintain provenance, // so use raw pointer manipulation. - unsafe { ptr::addr_of_mut!((*ptr).value) } + unsafe { &raw mut (*ptr).value } } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 50886244d58..ced789c4f92 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -797,7 +797,7 @@ impl<T, A: Allocator> Arc<T, A> { // reference into a strong reference. let strong = unsafe { let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).data), data); + ptr::write(&raw mut (*inner).data, data); // The above write to the data field must be visible to any threads which // observe a non-zero strong count. Therefore we need at least "Release" ordering @@ -1583,7 +1583,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { // SAFETY: This cannot go through Deref::deref or RcBoxPtr::inner because // this is required to retain raw/mut provenance such that e.g. `get_mut` can // write through the pointer after the Rc is recovered through `from_raw`. - unsafe { ptr::addr_of_mut!((*ptr).data) } + unsafe { &raw mut (*ptr).data } } /// Constructs an `Arc<T, A>` from a raw pointer. @@ -1955,8 +1955,8 @@ impl<T: ?Sized> Arc<T> { debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); unsafe { - ptr::addr_of_mut!((*inner).strong).write(atomic::AtomicUsize::new(1)); - ptr::addr_of_mut!((*inner).weak).write(atomic::AtomicUsize::new(1)); + (&raw mut (*inner).strong).write(atomic::AtomicUsize::new(1)); + (&raw mut (*inner).weak).write(atomic::AtomicUsize::new(1)); } inner @@ -1986,8 +1986,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { // Copy value as bytes ptr::copy_nonoverlapping( - core::ptr::addr_of!(*src) as *const u8, - ptr::addr_of_mut!((*ptr).data) as *mut u8, + (&raw const *src) as *const u8, + (&raw mut (*ptr).data) as *mut u8, value_size, ); @@ -2022,7 +2022,7 @@ impl<T> Arc<[T]> { unsafe { let ptr = Self::allocate_for_slice(v.len()); - ptr::copy_nonoverlapping(v.as_ptr(), ptr::addr_of_mut!((*ptr).data) as *mut T, v.len()); + ptr::copy_nonoverlapping(v.as_ptr(), (&raw mut (*ptr).data) as *mut T, v.len()); Self::from_ptr(ptr) } @@ -2061,7 +2061,7 @@ impl<T> Arc<[T]> { let layout = Layout::for_value_raw(ptr); // Pointer to first element - let elems = ptr::addr_of_mut!((*ptr).data) as *mut T; + let elems = (&raw mut (*ptr).data) as *mut T; let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; @@ -2805,7 +2805,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> { // SAFETY: if is_dangling returns false, then the pointer is dereferenceable. // The payload may be dropped at this point, and we have to maintain provenance, // so use raw pointer manipulation. - unsafe { ptr::addr_of_mut!((*ptr).data) } + unsafe { &raw mut (*ptr).data } } } @@ -3428,7 +3428,7 @@ impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for Arc<T, A> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized, A: Allocator> fmt::Pointer for Arc<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&core::ptr::addr_of!(**self), f) + fmt::Pointer::fmt(&(&raw const **self), f) } } @@ -3678,7 +3678,7 @@ impl<T, A: Allocator + Clone> From<Vec<T, A>> for Arc<[T], A> { let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); let rc_ptr = Self::allocate_for_slice_in(len, &alloc); - ptr::copy_nonoverlapping(vec_ptr, ptr::addr_of_mut!((*rc_ptr).data) as *mut T, len); + ptr::copy_nonoverlapping(vec_ptr, (&raw mut (*rc_ptr).data) as *mut T, len); // Create a `Vec<T, &A>` with length 0, to deallocate the buffer // without dropping its contents or the allocator diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index f7aad56695d..9a6745fdbc0 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -21,11 +21,11 @@ use crate::raw_vec::RawVec; macro non_null { (mut $place:expr, $t:ident) => {{ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block - unsafe { &mut *(ptr::addr_of_mut!($place) as *mut NonNull<$t>) } + unsafe { &mut *((&raw mut $place) as *mut NonNull<$t>) } }}, ($place:expr, $t:ident) => {{ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block - unsafe { *(ptr::addr_of!($place) as *const NonNull<$t>) } + unsafe { *((&raw const $place) as *const NonNull<$t>) } }}, } diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 930f8a76620..15b00b9aa44 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -5,7 +5,7 @@ use crate::error::Error; use crate::ffi::c_char; use crate::iter::FusedIterator; use crate::marker::PhantomData; -use crate::ptr::{NonNull, addr_of}; +use crate::ptr::NonNull; use crate::slice::memchr; use crate::{fmt, intrinsics, ops, slice, str}; @@ -623,7 +623,7 @@ impl CStr { pub const fn to_bytes_with_nul(&self) -> &[u8] { // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s // is safe on all supported targets. - unsafe { &*(addr_of!(self.inner) as *const [u8]) } + unsafe { &*((&raw const self.inner) as *const [u8]) } } /// Iterates over the bytes in this C string. diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index 914ef613177..cc64ceb13f7 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -3,7 +3,6 @@ use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused}; use crate::mem::{ManuallyDrop, MaybeUninit}; use crate::num::NonZero; use crate::ops::{ControlFlow, Try}; -use crate::ptr::addr_of; use crate::{array, fmt}; /// An iterator that uses `f` to both filter and map elements from `iter`. @@ -101,7 +100,7 @@ where unsafe { let opt_payload_at: *const MaybeUninit<B> = - addr_of!(val).byte_add(core::mem::offset_of!(Option<B>, Some.0)).cast(); + (&raw const val).byte_add(core::mem::offset_of!(Option<B>, Some.0)).cast(); let dst = guard.array.as_mut_ptr().add(idx); crate::ptr::copy_nonoverlapping(opt_payload_at, dst, 1); crate::mem::forget(val); diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 3e47785ee48..7d519384e37 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -1,22 +1,21 @@ use crate::ops::{Deref, DerefMut, DerefPure}; use crate::ptr; -/// A wrapper to inhibit the compiler from automatically calling `T`’s destructor. -/// This wrapper is 0-cost. +/// A wrapper to inhibit the compiler from automatically calling `T`’s +/// destructor. This wrapper is 0-cost. /// /// `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as -/// `T`, and is subject to the same layout optimizations as `T`. As a consequence, -/// it has *no effect* on the assumptions that the compiler makes about its -/// contents. For example, initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`] -/// is undefined behavior. If you need to handle uninitialized data, use -/// [`MaybeUninit<T>`] instead. +/// `T`, and is subject to the same layout optimizations as `T`. As a +/// consequence, it has *no effect* on the assumptions that the compiler makes +/// about its contents. For example, initializing a `ManuallyDrop<&mut T>` with +/// [`mem::zeroed`] is undefined behavior. If you need to handle uninitialized +/// data, use [`MaybeUninit<T>`] instead. /// -/// Note that accessing the value inside a `ManuallyDrop<T>` is safe. -/// This means that a `ManuallyDrop<T>` whose content has been dropped must not -/// be exposed through a public safe API. -/// Correspondingly, `ManuallyDrop::drop` is unsafe. +/// Note that accessing the value inside a `ManuallyDrop<T>` is safe. This means +/// that a `ManuallyDrop<T>` whose content has been dropped must not be exposed +/// through a public safe API. Correspondingly, `ManuallyDrop::drop` is unsafe. /// -/// # `ManuallyDrop` and drop order. +/// # `ManuallyDrop` and drop order /// /// Rust has a well-defined [drop order] of values. To make sure that fields or /// locals are dropped in a specific order, reorder the declarations such that @@ -40,9 +39,116 @@ use crate::ptr; /// } /// ``` /// +/// # Interaction with `Box` +/// +/// Currently, if you have a `ManuallyDrop<T>`, where the type `T` is a `Box` or +/// contains a `Box` inside, then dropping the `T` followed by moving the +/// `ManuallyDrop<T>` is [considered to be undefined +/// behavior](https://github.com/rust-lang/unsafe-code-guidelines/issues/245). +/// That is, the following code causes undefined behavior: +/// +/// ```no_run +/// use std::mem::ManuallyDrop; +/// +/// let mut x = ManuallyDrop::new(Box::new(42)); +/// unsafe { +/// ManuallyDrop::drop(&mut x); +/// } +/// let y = x; // Undefined behavior! +/// ``` +/// +/// This is [likely to change in the +/// future](https://rust-lang.github.io/rfcs/3336-maybe-dangling.html). In the +/// meantime, consider using [`MaybeUninit`] instead. +/// +/// # Safety hazards when storing `ManuallyDrop` in a struct or an enum. +/// +/// Special care is needed when all of the conditions below are met: +/// * A struct or enum contains a `ManuallyDrop`. +/// * The `ManuallyDrop` is not inside a `union`. +/// * The struct or enum is part of public API, or is stored in a struct or an +/// enum that is part of public API. +/// * There is code that drops the contents of the `ManuallyDrop` field, and +/// this code is outside the struct or enum's `Drop` implementation. +/// +/// In particular, the following hazards may occur: +/// +/// #### Storing generic types +/// +/// If the `ManuallyDrop` contains a client-supplied generic type, the client +/// might provide a `Box` as that type. This would cause undefined behavior when +/// the struct or enum is later moved, as mentioned in the previous section. For +/// example, the following code causes undefined behavior: +/// +/// ```no_run +/// use std::mem::ManuallyDrop; +/// +/// pub struct BadOption<T> { +/// // Invariant: Has been dropped iff `is_some` is false. +/// value: ManuallyDrop<T>, +/// is_some: bool, +/// } +/// impl<T> BadOption<T> { +/// pub fn new(value: T) -> Self { +/// Self { value: ManuallyDrop::new(value), is_some: true } +/// } +/// pub fn change_to_none(&mut self) { +/// if self.is_some { +/// self.is_some = false; +/// unsafe { +/// // SAFETY: `value` hasn't been dropped yet, as per the invariant +/// // (This is actually unsound!) +/// ManuallyDrop::drop(&mut self.value); +/// } +/// } +/// } +/// } +/// +/// // In another crate: +/// +/// let mut option = BadOption::new(Box::new(42)); +/// option.change_to_none(); +/// let option2 = option; // Undefined behavior! +/// ``` +/// +/// #### Deriving traits +/// +/// Deriving `Debug`, `Clone`, `PartialEq`, `PartialOrd`, `Ord`, or `Hash` on +/// the struct or enum could be unsound, since the derived implementations of +/// these traits would access the `ManuallyDrop` field. For example, the +/// following code causes undefined behavior: +/// +/// ```no_run +/// use std::mem::ManuallyDrop; +/// +/// // This derive is unsound in combination with the `ManuallyDrop::drop` call. +/// #[derive(Debug)] +/// pub struct Foo { +/// value: ManuallyDrop<String>, +/// } +/// impl Foo { +/// pub fn new() -> Self { +/// let mut temp = Self { +/// value: ManuallyDrop::new(String::from("Unsafe rust is hard.")) +/// }; +/// unsafe { +/// // SAFETY: `value` hasn't been dropped yet. +/// ManuallyDrop::drop(&mut temp.value); +/// } +/// temp +/// } +/// } +/// +/// // In another crate: +/// +/// let foo = Foo::new(); +/// println!("{:?}", foo); // Undefined behavior! +/// ``` +/// /// [drop order]: https://doc.rust-lang.org/reference/destructors.html /// [`mem::zeroed`]: crate::mem::zeroed /// [`MaybeUninit<T>`]: crate::mem::MaybeUninit +/// [`MaybeUninit`]: crate::mem::MaybeUninit #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index cac33a329b9..4f97048eab1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1730,7 +1730,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) { // `dst` cannot overlap `src` because the caller has mutable access // to `dst` while `src` is owned by this function. unsafe { - copy_nonoverlapping(addr_of!(src) as *const u8, dst as *mut u8, mem::size_of::<T>()); + copy_nonoverlapping((&raw const src) as *const u8, dst as *mut u8, mem::size_of::<T>()); // We are calling the intrinsic directly to avoid function calls in the generated code. intrinsics::forget(src); } @@ -2348,7 +2348,6 @@ impl<F: FnPtr> fmt::Debug for F { /// no difference whether the pointer is null or dangling.) #[stable(feature = "raw_ref_macros", since = "1.51.0")] #[rustc_macro_transparency = "semitransparent"] -#[allow_internal_unstable(raw_ref_op)] pub macro addr_of($place:expr) { &raw const $place } @@ -2439,7 +2438,6 @@ pub macro addr_of($place:expr) { /// makes no difference whether the pointer is null or dangling.) #[stable(feature = "raw_ref_macros", since = "1.51.0")] #[rustc_macro_transparency = "semitransparent"] -#[allow_internal_unstable(raw_ref_op)] pub macro addr_of_mut($place:expr) { &raw mut $place } diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 1168f36da15..c5746157d01 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -11,7 +11,7 @@ use crate::iter::{ use crate::marker::PhantomData; use crate::mem::{self, SizedTypeProperties}; use crate::num::NonZero; -use crate::ptr::{self, NonNull, without_provenance, without_provenance_mut}; +use crate::ptr::{NonNull, without_provenance, without_provenance_mut}; use crate::{cmp, fmt}; #[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index c2a38194644..830debe02ea 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -14,11 +14,11 @@ macro_rules! if_zst { if T::IS_ZST { // SAFETY: for ZSTs, the pointer is storing a provenance-free length, // so consuming and updating it as a `usize` is fine. - let $len = unsafe { &mut *ptr::addr_of_mut!($this.end_or_len).cast::<usize>() }; + let $len = unsafe { &mut *(&raw mut $this.end_or_len).cast::<usize>() }; $zst_body } else { // SAFETY: for non-ZSTs, the type invariant ensures it cannot be null - let $end = unsafe { &mut *ptr::addr_of_mut!($this.end_or_len).cast::<NonNull<T>>() }; + let $end = unsafe { &mut *(&raw mut $this.end_or_len).cast::<NonNull<T>>() }; $other_body } }}; @@ -30,7 +30,7 @@ macro_rules! if_zst { $zst_body } else { // SAFETY: for non-ZSTs, the type invariant ensures it cannot be null - let $end = unsafe { *ptr::addr_of!($this.end_or_len).cast::<NonNull<T>>() }; + let $end = unsafe { *(&raw const $this.end_or_len).cast::<NonNull<T>>() }; $other_body } }}; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 11c9f483f36..dd8fa1ae343 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -883,8 +883,8 @@ impl<T> [T] { pub const fn swap(&mut self, a: usize, b: usize) { // FIXME: use swap_unchecked here (https://github.com/rust-lang/rust/pull/88540#issuecomment-944344343) // Can't take two mutable loans from one vector, so instead use raw pointers. - let pa = ptr::addr_of_mut!(self[a]); - let pb = ptr::addr_of_mut!(self[b]); + let pa = &raw mut self[a]; + let pb = &raw mut self[b]; // SAFETY: `pa` and `pb` have been created from safe mutable references and refer // to elements in the slice and therefore are guaranteed to be valid and aligned. // Note that accessing the elements behind `a` and `b` is checked and will diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index 3f31107acf0..e7677c8317a 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -8,6 +8,8 @@ impl [u8] { /// Creates an iterator over the contiguous valid UTF-8 ranges of this /// slice, and the non-UTF-8 fragments in between. /// + /// See the [`Utf8Chunk`] type for documenation of the items yielded by this iterator. + /// /// # Examples /// /// This function formats arbitrary but mostly-UTF-8 bytes into Rust source @@ -148,6 +150,8 @@ impl fmt::Debug for Debug<'_> { /// If you want a simple conversion from UTF-8 byte slices to string slices, /// [`from_utf8`] is easier to use. /// +/// See the [`Utf8Chunk`] type for documenation of the items yielded by this iterator. +/// /// [byteslice]: slice /// [`from_utf8`]: super::from_utf8 /// diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs index a4cbb1875d5..b986fc1c2a8 100644 --- a/library/panic_unwind/src/emcc.rs +++ b/library/panic_unwind/src/emcc.rs @@ -78,7 +78,7 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> { super::__rust_foreign_exception(); } - let canary = ptr::addr_of!((*adjusted_ptr).canary).read(); + let canary = (&raw const (*adjusted_ptr).canary).read(); if !ptr::eq(canary, &EXCEPTION_TYPE_INFO) { super::__rust_foreign_exception(); } diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs index d8c1dcaaefe..89b44338d6b 100644 --- a/library/panic_unwind/src/gcc.rs +++ b/library/panic_unwind/src/gcc.rs @@ -92,7 +92,7 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> { let exception = exception.cast::<Exception>(); // Just access the canary field, avoid accessing the entire `Exception` as // it can be a foreign Rust exception. - let canary = ptr::addr_of!((*exception).canary).read(); + let canary = (&raw const (*exception).canary).read(); if !ptr::eq(canary, &CANARY) { // A foreign Rust exception, treat it slightly differently from other // foreign exceptions, because call into `_Unwind_DeleteException` will diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 9e74a45a0e2..565a2b8c573 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -50,7 +50,6 @@ use alloc::boxed::Box; use core::any::Any; use core::ffi::{c_int, c_uint, c_void}; use core::mem::{self, ManuallyDrop}; -use core::ptr::{addr_of, addr_of_mut}; // NOTE(nbdd0121): The `canary` field is part of stable ABI. #[repr(C)] @@ -131,8 +130,6 @@ mod imp { #[cfg(not(target_arch = "x86"))] mod imp { - use core::ptr::addr_of; - // On 64-bit systems, SEH represents pointers as 32-bit offsets from `__ImageBase`. #[repr(transparent)] #[derive(Copy, Clone)] @@ -157,7 +154,7 @@ mod imp { // going to be cross-lang LTOed anyway. However, using expose is shorter and // requires less unsafe. let addr: usize = ptr.expose_provenance(); - let image_base = addr_of!(__ImageBase).addr(); + let image_base = (&raw const __ImageBase).addr(); let offset: usize = addr - image_base; Self(offset as u32) } @@ -250,7 +247,7 @@ extern "C" { // This is fine since the MSVC runtime uses string comparison on the type name // to match TypeDescriptors rather than pointer equality. static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { - pVFTable: addr_of!(TYPE_INFO_VTABLE) as *const _, + pVFTable: (&raw const TYPE_INFO_VTABLE) as *const _, spare: core::ptr::null_mut(), name: TYPE_NAME, }; @@ -304,8 +301,8 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { // dropped when unwinding. Instead it will be dropped by exception_cleanup // which is invoked by the C++ runtime. let mut exception = - ManuallyDrop::new(Exception { canary: addr_of!(TYPE_DESCRIPTOR), data: Some(data) }); - let throw_ptr = addr_of_mut!(exception) as *mut _; + ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) }); + let throw_ptr = (&raw mut exception) as *mut _; // This... may seems surprising, and justifiably so. On 32-bit MSVC the // pointers between these structure are just that, pointers. On 64-bit MSVC, @@ -328,23 +325,23 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { // In any case, we basically need to do something like this until we can // express more operations in statics (and we may never be able to). atomic_store_seqcst( - addr_of_mut!(THROW_INFO.pmfnUnwind).cast(), + (&raw mut THROW_INFO.pmfnUnwind).cast(), ptr_t::new(exception_cleanup as *mut u8).raw(), ); atomic_store_seqcst( - addr_of_mut!(THROW_INFO.pCatchableTypeArray).cast(), - ptr_t::new(addr_of_mut!(CATCHABLE_TYPE_ARRAY).cast()).raw(), + (&raw mut THROW_INFO.pCatchableTypeArray).cast(), + ptr_t::new((&raw mut CATCHABLE_TYPE_ARRAY).cast()).raw(), ); atomic_store_seqcst( - addr_of_mut!(CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(), - ptr_t::new(addr_of_mut!(CATCHABLE_TYPE).cast()).raw(), + (&raw mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(), + ptr_t::new((&raw mut CATCHABLE_TYPE).cast()).raw(), ); atomic_store_seqcst( - addr_of_mut!(CATCHABLE_TYPE.pType).cast(), - ptr_t::new(addr_of_mut!(TYPE_DESCRIPTOR).cast()).raw(), + (&raw mut CATCHABLE_TYPE.pType).cast(), + ptr_t::new((&raw mut TYPE_DESCRIPTOR).cast()).raw(), ); atomic_store_seqcst( - addr_of_mut!(CATCHABLE_TYPE.copyFunction).cast(), + (&raw mut CATCHABLE_TYPE.copyFunction).cast(), ptr_t::new(exception_copy as *mut u8).raw(), ); @@ -352,7 +349,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8) -> !; } - _CxxThrowException(throw_ptr, addr_of_mut!(THROW_INFO) as *mut _); + _CxxThrowException(throw_ptr, (&raw mut THROW_INFO) as *mut _); } pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> { @@ -362,8 +359,8 @@ pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> { super::__rust_foreign_exception(); } let exception = payload as *mut Exception; - let canary = addr_of!((*exception).canary).read(); - if !core::ptr::eq(canary, addr_of!(TYPE_DESCRIPTOR)) { + let canary = (&raw const (*exception).canary).read(); + if !core::ptr::eq(canary, &raw const TYPE_DESCRIPTOR) { // A foreign Rust exception. super::__rust_foreign_exception(); } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 0f905803bb8..2243f100643 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -9,7 +9,6 @@ use crate::borrow::{Borrow, Cow}; use crate::collections::TryReserveError; use crate::hash::{Hash, Hasher}; use crate::ops::{self, Range}; -use crate::ptr::addr_of_mut; use crate::rc::Rc; use crate::str::FromStr; use crate::sync::Arc; @@ -1272,7 +1271,7 @@ unsafe impl CloneToUninit for OsStr { #[cfg_attr(debug_assertions, track_caller)] unsafe fn clone_to_uninit(&self, dst: *mut Self) { // SAFETY: we're just a wrapper around a platform-specific Slice - unsafe { self.inner.clone_to_uninit(addr_of_mut!((*dst).inner)) } + unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } } } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 412603ddea3..0672fe6f771 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1732,7 +1732,7 @@ fn windows_unix_socket_exists() { let bytes = core::slice::from_raw_parts(bytes.as_ptr().cast::<i8>(), bytes.len()); addr.sun_path[..bytes.len()].copy_from_slice(bytes); let len = mem::size_of_val(&addr) as i32; - let result = c::bind(socket, ptr::addr_of!(addr).cast::<c::SOCKADDR>(), len); + let result = c::bind(socket, (&raw const addr).cast::<c::SOCKADDR>(), len); c::closesocket(socket); assert_eq!(result, 0); } diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index e0f3aea42b6..253e1503cf7 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -95,7 +95,7 @@ impl SocketAddr { unsafe { let mut addr: libc::sockaddr_un = mem::zeroed(); let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t; - cvt(f(core::ptr::addr_of_mut!(addr) as *mut _, &mut len))?; + cvt(f((&raw mut addr) as *mut _, &mut len))?; SocketAddr::from_parts(addr, len) } } diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index c34a3b4e184..36967fc3f98 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -37,7 +37,7 @@ pub(super) fn recv_vectored_with_ancillary_from( unsafe { let mut msg_name: libc::sockaddr_un = zeroed(); let mut msg: libc::msghdr = zeroed(); - msg.msg_name = core::ptr::addr_of_mut!(msg_name) as *mut _; + msg.msg_name = (&raw mut msg_name) as *mut _; msg.msg_namelen = size_of::<libc::sockaddr_un>() as libc::socklen_t; msg.msg_iov = bufs.as_mut_ptr().cast(); msg.msg_iovlen = bufs.len() as _; @@ -70,7 +70,7 @@ pub(super) fn send_vectored_with_ancillary_to( if let Some(path) = path { sockaddr_un(path)? } else { (zeroed(), 0) }; let mut msg: libc::msghdr = zeroed(); - msg.msg_name = core::ptr::addr_of_mut!(msg_name) as *mut _; + msg.msg_name = (&raw mut msg_name) as *mut _; msg.msg_namelen = msg_namelen; msg.msg_iov = bufs.as_ptr() as *mut _; msg.msg_iovlen = bufs.len() as _; diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 48aaddd2d52..82446ea107f 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -100,7 +100,7 @@ impl UnixDatagram { let socket = UnixDatagram::unbound()?; let (addr, len) = sockaddr_un(path.as_ref())?; - cvt(libc::bind(socket.as_raw_fd(), core::ptr::addr_of!(addr) as *const _, len as _))?; + cvt(libc::bind(socket.as_raw_fd(), (&raw const addr) as *const _, len as _))?; Ok(socket) } @@ -133,7 +133,7 @@ impl UnixDatagram { let socket = UnixDatagram::unbound()?; cvt(libc::bind( socket.as_raw_fd(), - core::ptr::addr_of!(socket_addr.addr) as *const _, + (&raw const socket_addr.addr) as *const _, socket_addr.len as _, ))?; Ok(socket) @@ -215,7 +215,7 @@ impl UnixDatagram { unsafe { let (addr, len) = sockaddr_un(path.as_ref())?; - cvt(libc::connect(self.as_raw_fd(), core::ptr::addr_of!(addr) as *const _, len))?; + cvt(libc::connect(self.as_raw_fd(), (&raw const addr) as *const _, len))?; } Ok(()) } @@ -247,7 +247,7 @@ impl UnixDatagram { unsafe { cvt(libc::connect( self.as_raw_fd(), - core::ptr::addr_of!(socket_addr.addr) as *const _, + (&raw const socket_addr.addr) as *const _, socket_addr.len, ))?; } @@ -514,7 +514,7 @@ impl UnixDatagram { buf.as_ptr() as *const _, buf.len(), MSG_NOSIGNAL, - core::ptr::addr_of!(addr) as *const _, + (&raw const addr) as *const _, len, ))?; Ok(count as usize) @@ -549,7 +549,7 @@ impl UnixDatagram { buf.as_ptr() as *const _, buf.len(), MSG_NOSIGNAL, - core::ptr::addr_of!(socket_addr.addr) as *const _, + (&raw const socket_addr.addr) as *const _, socket_addr.len, ))?; Ok(count as usize) diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index 440408eb13f..be236317d04 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -103,11 +103,7 @@ impl UnixListener { )))] const backlog: libc::c_int = libc::SOMAXCONN; - cvt(libc::bind( - inner.as_inner().as_raw_fd(), - core::ptr::addr_of!(addr) as *const _, - len as _, - ))?; + cvt(libc::bind(inner.as_inner().as_raw_fd(), (&raw const addr) as *const _, len as _))?; cvt(libc::listen(inner.as_inner().as_raw_fd(), backlog))?; Ok(UnixListener(inner)) @@ -147,7 +143,7 @@ impl UnixListener { const backlog: core::ffi::c_int = 128; cvt(libc::bind( inner.as_raw_fd(), - core::ptr::addr_of!(socket_addr.addr) as *const _, + (&raw const socket_addr.addr) as *const _, socket_addr.len as _, ))?; cvt(libc::listen(inner.as_raw_fd(), backlog))?; @@ -182,7 +178,7 @@ impl UnixListener { pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() }; let mut len = mem::size_of_val(&storage) as libc::socklen_t; - let sock = self.0.accept(core::ptr::addr_of_mut!(storage) as *mut _, &mut len)?; + let sock = self.0.accept((&raw mut storage) as *mut _, &mut len)?; let addr = SocketAddr::from_parts(storage, len)?; Ok((UnixStream(sock), addr)) } diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 4967c5b89ec..cb210b41eae 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -84,7 +84,7 @@ impl UnixStream { let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?; let (addr, len) = sockaddr_un(path.as_ref())?; - cvt(libc::connect(inner.as_raw_fd(), core::ptr::addr_of!(addr) as *const _, len))?; + cvt(libc::connect(inner.as_raw_fd(), (&raw const addr) as *const _, len))?; Ok(UnixStream(inner)) } } @@ -118,7 +118,7 @@ impl UnixStream { let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?; cvt(libc::connect( inner.as_raw_fd(), - core::ptr::addr_of!(socket_addr.addr) as *const _, + (&raw const socket_addr.addr) as *const _, socket_addr.len, ))?; Ok(UnixStream(inner)) diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index c818bd05858..e1014a4f296 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -60,7 +60,7 @@ mod impl_linux { socket.as_raw_fd(), SOL_SOCKET, SO_PEERCRED, - core::ptr::addr_of_mut!(ucred) as *mut c_void, + (&raw mut ucred) as *mut c_void, &mut ucred_size, ); @@ -121,7 +121,7 @@ mod impl_apple { socket.as_raw_fd(), SOL_LOCAL, LOCAL_PEERPID, - core::ptr::addr_of_mut!(pid) as *mut c_void, + (&raw mut pid) as *mut c_void, &mut pid_size, ); diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 336e34d7b95..9fe05db8126 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -506,7 +506,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> // method of calling a catch panic whilst juggling ownership. let mut data = Data { f: ManuallyDrop::new(f) }; - let data_ptr = core::ptr::addr_of_mut!(data) as *mut u8; + let data_ptr = (&raw mut data) as *mut u8; // SAFETY: // // Access to the union's fields: this is `std` and we know that the `r#try` diff --git a/library/std/src/path.rs b/library/std/src/path.rs index e3ff7d199cc..63edfdb82f3 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3144,7 +3144,7 @@ unsafe impl CloneToUninit for Path { #[cfg_attr(debug_assertions, track_caller)] unsafe fn clone_to_uninit(&self, dst: *mut Self) { // SAFETY: Path is just a wrapper around OsStr - unsafe { self.inner.clone_to_uninit(core::ptr::addr_of_mut!((*dst).inner)) } + unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } } } diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index 2451d7b79d1..446881291e6 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -185,11 +185,7 @@ impl<T> Channel<T> { // Prepare for blocking until a receiver wakes us up. let oper = Operation::hook(token); let mut packet = Packet::<T>::message_on_stack(msg); - inner.senders.register_with_packet( - oper, - core::ptr::addr_of_mut!(packet) as *mut (), - cx, - ); + inner.senders.register_with_packet(oper, (&raw mut packet) as *mut (), cx); inner.receivers.notify(); drop(inner); @@ -256,11 +252,7 @@ impl<T> Channel<T> { // Prepare for blocking until a sender wakes us up. let oper = Operation::hook(token); let mut packet = Packet::<T>::empty_on_stack(); - inner.receivers.register_with_packet( - oper, - core::ptr::addr_of_mut!(packet) as *mut (), - cx, - ); + inner.receivers.register_with_packet(oper, (&raw mut packet) as *mut (), cx); inner.senders.notify(); drop(inner); diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 992767211d0..8e0609fe48c 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -2,7 +2,6 @@ //! systems: just a `Vec<u8>`/`[u8]`. use core::clone::CloneToUninit; -use core::ptr::addr_of_mut; use crate::borrow::Cow; use crate::collections::TryReserveError; @@ -355,6 +354,6 @@ unsafe impl CloneToUninit for Slice { #[cfg_attr(debug_assertions, track_caller)] unsafe fn clone_to_uninit(&self, dst: *mut Self) { // SAFETY: we're just a wrapper around [u8] - unsafe { self.inner.clone_to_uninit(addr_of_mut!((*dst).inner)) } + unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } } } diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 6fbbec7a945..b3834388df6 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -1,7 +1,6 @@ //! The underlying OsString/OsStr implementation on Windows is a //! wrapper around the "WTF-8" encoding; see the `wtf8` module for more. use core::clone::CloneToUninit; -use core::ptr::addr_of_mut; use crate::borrow::Cow; use crate::collections::TryReserveError; @@ -278,6 +277,6 @@ unsafe impl CloneToUninit for Slice { #[cfg_attr(debug_assertions, track_caller)] unsafe fn clone_to_uninit(&self, dst: *mut Self) { // SAFETY: we're just a wrapper around Wtf8 - unsafe { self.inner.clone_to_uninit(addr_of_mut!((*dst).inner)) } + unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } } } diff --git a/library/std/src/sys/pal/hermit/net.rs b/library/std/src/sys/pal/hermit/net.rs index 416469c0037..d9baa091a23 100644 --- a/library/std/src/sys/pal/hermit/net.rs +++ b/library/std/src/sys/pal/hermit/net.rs @@ -192,7 +192,7 @@ impl Socket { buf.as_mut_ptr(), buf.len(), flags, - core::ptr::addr_of_mut!(storage) as *mut _, + (&raw mut storage) as *mut _, &mut addrlen, ) })?; @@ -298,7 +298,7 @@ impl Socket { netc::ioctl( self.as_raw_fd(), netc::FIONBIO, - core::ptr::addr_of_mut!(nonblocking) as *mut core::ffi::c_void, + (&raw mut nonblocking) as *mut core::ffi::c_void, ) }) .map(drop) diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs index 99166b15602..e0b6eb76b03 100644 --- a/library/std/src/sys/pal/hermit/time.rs +++ b/library/std/src/sys/pal/hermit/time.rs @@ -107,8 +107,7 @@ pub struct Instant(Timespec); impl Instant { pub fn now() -> Instant { let mut time: Timespec = Timespec::zero(); - let _ = - unsafe { hermit_abi::clock_gettime(CLOCK_MONOTONIC, core::ptr::addr_of_mut!(time.t)) }; + let _ = unsafe { hermit_abi::clock_gettime(CLOCK_MONOTONIC, &raw mut time.t) }; Instant(time) } @@ -209,8 +208,7 @@ impl SystemTime { pub fn now() -> SystemTime { let mut time: Timespec = Timespec::zero(); - let _ = - unsafe { hermit_abi::clock_gettime(CLOCK_REALTIME, core::ptr::addr_of_mut!(time.t)) }; + let _ = unsafe { hermit_abi::clock_gettime(CLOCK_REALTIME, &raw mut time.t) }; SystemTime(time) } diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 86342c2add0..39aabf0b2d6 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -740,7 +740,7 @@ impl Iterator for ReadDir { // // Like for uninitialized contents, converting entry_ptr to `&dirent64` // would not be legal. However, unique to dirent64 is that we don't even - // get to use `addr_of!((*entry_ptr).d_name)` because that operation + // get to use `&raw const (*entry_ptr).d_name` because that operation // requires the full extent of *entry_ptr to be in bounds of the same // allocation, which is not necessarily the case here. // @@ -754,7 +754,7 @@ impl Iterator for ReadDir { } else { #[allow(deref_nullptr)] { - ptr::addr_of!((*ptr::null::<dirent64>()).$field) + &raw const (*ptr::null::<dirent64>()).$field } } }}; @@ -1385,7 +1385,7 @@ impl File { } cvt(unsafe { libc::fsetattrlist( self.as_raw_fd(), - core::ptr::addr_of!(attrlist).cast::<libc::c_void>().cast_mut(), + (&raw const attrlist).cast::<libc::c_void>().cast_mut(), buf.as_ptr().cast::<libc::c_void>().cast_mut(), num_times * mem::size_of::<libc::timespec>(), 0 @@ -1944,7 +1944,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { libc::copyfile_state_get( state.0, libc::COPYFILE_STATE_COPIED as u32, - core::ptr::addr_of_mut!(bytes_copied) as *mut libc::c_void, + (&raw mut bytes_copied) as *mut libc::c_void, ) })?; Ok(bytes_copied as u64) diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs index 0f2e015bbcd..6a67bb0a101 100644 --- a/library/std/src/sys/pal/unix/net.rs +++ b/library/std/src/sys/pal/unix/net.rs @@ -329,7 +329,7 @@ impl Socket { buf.as_mut_ptr() as *mut c_void, buf.len(), flags, - core::ptr::addr_of_mut!(storage) as *mut _, + (&raw mut storage) as *mut _, &mut addrlen, ) })?; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index d99bde2f9a5..f983d174ed6 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -612,7 +612,7 @@ pub unsafe fn environ() -> *mut *const *const c_char { extern "C" { static mut environ: *const *const c_char; } - ptr::addr_of_mut!(environ) + &raw mut environ } static ENV_LOCK: RwLock<()> = RwLock::new(()); diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs index 34ff464aa37..5d0110cf55d 100644 --- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs @@ -178,7 +178,7 @@ impl Process { zx_cvt(zx_object_get_info( self.handle.raw(), ZX_INFO_PROCESS, - core::ptr::addr_of_mut!(proc_info) as *mut libc::c_void, + (&raw mut proc_info) as *mut libc::c_void, mem::size_of::<zx_info_process_t>(), &mut actual, &mut avail, @@ -215,7 +215,7 @@ impl Process { zx_cvt(zx_object_get_info( self.handle.raw(), ZX_INFO_PROCESS, - core::ptr::addr_of_mut!(proc_info) as *mut libc::c_void, + (&raw mut proc_info) as *mut libc::c_void, mem::size_of::<zx_info_process_t>(), &mut actual, &mut avail, diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index d812aa0e02c..5d30f388da1 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -788,15 +788,15 @@ impl Command { let mut iov = [IoSlice::new(b"")]; let mut msg: libc::msghdr = mem::zeroed(); - msg.msg_iov = core::ptr::addr_of_mut!(iov) as *mut _; + msg.msg_iov = (&raw mut iov) as *mut _; msg.msg_iovlen = 1; // only attach cmsg if we successfully acquired the pidfd if pidfd >= 0 { msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _; - msg.msg_control = core::ptr::addr_of_mut!(cmsg.buf) as *mut _; + msg.msg_control = (&raw mut cmsg.buf) as *mut _; - let hdr = CMSG_FIRSTHDR(core::ptr::addr_of_mut!(msg) as *mut _); + let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _); (*hdr).cmsg_level = SOL_SOCKET; (*hdr).cmsg_type = SCM_RIGHTS; (*hdr).cmsg_len = CMSG_LEN(SCM_MSG_LEN as _) as _; @@ -838,17 +838,17 @@ impl Command { let mut msg: libc::msghdr = mem::zeroed(); - msg.msg_iov = core::ptr::addr_of_mut!(iov) as *mut _; + msg.msg_iov = (&raw mut iov) as *mut _; msg.msg_iovlen = 1; msg.msg_controllen = mem::size_of::<Cmsg>() as _; - msg.msg_control = core::ptr::addr_of_mut!(cmsg) as *mut _; + msg.msg_control = (&raw mut cmsg) as *mut _; match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)) { Err(_) => return -1, Ok(_) => {} } - let hdr = CMSG_FIRSTHDR(core::ptr::addr_of_mut!(msg) as *mut _); + let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _); if hdr.is_null() || (*hdr).cmsg_level != SOL_SOCKET || (*hdr).cmsg_type != SCM_RIGHTS diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index e0a0d0973c6..ac0858e1de8 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -426,8 +426,8 @@ mod imp { match sysctlbyname.get() { Some(fcn) if unsafe { fcn(oid.as_ptr(), - ptr::addr_of_mut!(guard).cast(), - ptr::addr_of_mut!(size), + (&raw mut guard).cast(), + &raw mut size, ptr::null_mut(), 0) == 0 } => guard, diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index cb6133274d9..2f2d6e6add3 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -258,7 +258,7 @@ impl Thread { tv_nsec: nsecs, }; secs -= ts.tv_sec as u64; - let ts_ptr = core::ptr::addr_of_mut!(ts); + let ts_ptr = &raw mut ts; if libc::nanosleep(ts_ptr, ts_ptr) == -1 { assert_eq!(os::errno(), libc::EINTR); secs += ts.tv_sec as u64; @@ -447,8 +447,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { libc::sysctl( mib.as_mut_ptr(), 2, - core::ptr::addr_of_mut!(cpus) as *mut _, - core::ptr::addr_of_mut!(cpus_size) as *mut _, + (&raw mut cpus) as *mut _, + (&raw mut cpus_size) as *mut _, ptr::null_mut(), 0, ) diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs index 9e336ff2d47..ebe207fde93 100644 --- a/library/std/src/sys/pal/windows/api.rs +++ b/library/std/src/sys/pal/windows/api.rs @@ -30,7 +30,6 @@ //! should go in sys/pal/windows/mod.rs rather than here. See `IoResult` as an example. use core::ffi::c_void; -use core::ptr::addr_of; use super::c; @@ -186,7 +185,7 @@ unsafe trait SizedSetFileInformation: Sized { unsafe impl<T: SizedSetFileInformation> SetFileInformation for T { const CLASS: i32 = T::CLASS; fn as_ptr(&self) -> *const c_void { - addr_of!(*self).cast::<c_void>() + (&raw const *self).cast::<c_void>() } fn size(&self) -> u32 { win32_size_of::<Self>() diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index be26356bb40..aab471e28ea 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1,5 +1,3 @@ -use core::ptr::addr_of; - use super::api::{self, WinError}; use super::{IoResult, to_u16s}; use crate::borrow::Cow; @@ -325,7 +323,7 @@ impl File { let result = c::SetFileInformationByHandle( handle.as_raw_handle(), c::FileEndOfFileInfo, - ptr::addr_of!(eof).cast::<c_void>(), + (&raw const eof).cast::<c_void>(), mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32, ); if result == 0 { @@ -364,7 +362,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileAttributeTagInfo, - ptr::addr_of_mut!(attr_tag).cast(), + (&raw mut attr_tag).cast(), mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(), ))?; if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { @@ -396,7 +394,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileBasicInfo, - core::ptr::addr_of_mut!(info) as *mut c_void, + (&raw mut info) as *mut c_void, size as u32, ))?; let mut attr = FileAttr { @@ -428,7 +426,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileStandardInfo, - core::ptr::addr_of_mut!(info) as *mut c_void, + (&raw mut info) as *mut c_void, size as u32, ))?; attr.file_size = info.AllocationSize as u64; @@ -438,7 +436,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileAttributeTagInfo, - ptr::addr_of_mut!(attr_tag).cast(), + (&raw mut attr_tag).cast(), mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(), ))?; if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { @@ -545,22 +543,20 @@ impl File { unsafe { let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag { c::IO_REPARSE_TAG_SYMLINK => { - let info: *mut c::SYMBOLIC_LINK_REPARSE_BUFFER = - ptr::addr_of_mut!((*buf).rest).cast(); + let info: *mut c::SYMBOLIC_LINK_REPARSE_BUFFER = (&raw mut (*buf).rest).cast(); assert!(info.is_aligned()); ( - ptr::addr_of_mut!((*info).PathBuffer).cast::<u16>(), + (&raw mut (*info).PathBuffer).cast::<u16>(), (*info).SubstituteNameOffset / 2, (*info).SubstituteNameLength / 2, (*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0, ) } c::IO_REPARSE_TAG_MOUNT_POINT => { - let info: *mut c::MOUNT_POINT_REPARSE_BUFFER = - ptr::addr_of_mut!((*buf).rest).cast(); + let info: *mut c::MOUNT_POINT_REPARSE_BUFFER = (&raw mut (*buf).rest).cast(); assert!(info.is_aligned()); ( - ptr::addr_of_mut!((*info).PathBuffer).cast::<u16>(), + (&raw mut (*info).PathBuffer).cast::<u16>(), (*info).SubstituteNameOffset / 2, (*info).SubstituteNameLength / 2, false, @@ -643,7 +639,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileBasicInfo, - core::ptr::addr_of_mut!(info) as *mut c_void, + (&raw mut info) as *mut c_void, size as u32, ))?; Ok(info) @@ -790,11 +786,11 @@ impl<'a> Iterator for DirBuffIter<'a> { // it does not seem that reality is so kind, and assuming this // caused crashes in some cases (https://github.com/rust-lang/rust/issues/104530) // presumably, this can be blamed on buggy filesystem drivers, but who knows. - let next_entry = ptr::addr_of!((*info).NextEntryOffset).read_unaligned() as usize; - let length = ptr::addr_of!((*info).FileNameLength).read_unaligned() as usize; - let attrs = ptr::addr_of!((*info).FileAttributes).read_unaligned(); + let next_entry = (&raw const (*info).NextEntryOffset).read_unaligned() as usize; + let length = (&raw const (*info).FileNameLength).read_unaligned() as usize; + let attrs = (&raw const (*info).FileAttributes).read_unaligned(); let name = from_maybe_unaligned( - ptr::addr_of!((*info).FileName).cast::<u16>(), + (&raw const (*info).FileName).cast::<u16>(), length / size_of::<u16>(), ); let is_directory = (attrs & c::FILE_ATTRIBUTE_DIRECTORY) != 0; @@ -1326,7 +1322,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { pfrom.as_ptr(), pto.as_ptr(), Some(callback), - core::ptr::addr_of_mut!(size) as *mut _, + (&raw mut size) as *mut _, ptr::null_mut(), 0, ) @@ -1405,7 +1401,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { cvt(c::DeviceIoControl( d.as_raw_handle(), c::FSCTL_SET_REPARSE_POINT, - addr_of!(header).cast::<c_void>(), + (&raw const header).cast::<c_void>(), data_len as u32 + 8, ptr::null_mut(), 0, diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs index f16a9f534a3..4d6c4df9a5a 100644 --- a/library/std/src/sys/pal/windows/futex.rs +++ b/library/std/src/sys/pal/windows/futex.rs @@ -57,7 +57,7 @@ pub fn wait_on_address<W: Waitable>( unsafe { let addr = ptr::from_ref(address).cast::<c_void>(); let size = mem::size_of::<W>(); - let compare_addr = ptr::addr_of!(compare).cast::<c_void>(); + let compare_addr = (&raw const compare).cast::<c_void>(); let timeout = timeout.map(dur2timeout).unwrap_or(c::INFINITE); c::WaitOnAddress(addr, compare_addr, size, timeout) == c::TRUE } diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/pal/windows/io.rs index 785a3f6768b..1e7d02908f6 100644 --- a/library/std/src/sys/pal/windows/io.rs +++ b/library/std/src/sys/pal/windows/io.rs @@ -122,7 +122,7 @@ fn msys_tty_on(handle: BorrowedHandle<'_>) -> bool { c::GetFileInformationByHandleEx( handle.as_raw_handle(), c::FileNameInfo, - core::ptr::addr_of_mut!(name_info) as *mut c_void, + (&raw mut name_info) as *mut c_void, size_of::<FILE_NAME_INFO>() as u32, ) }; diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs index 61a4504cf65..fd62d1f407c 100644 --- a/library/std/src/sys/pal/windows/net.rs +++ b/library/std/src/sys/pal/windows/net.rs @@ -390,7 +390,7 @@ impl Socket { buf.as_mut_ptr() as *mut _, length, flags, - core::ptr::addr_of_mut!(storage) as *mut _, + (&raw mut storage) as *mut _, &mut addrlen, ) }; diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index d8200ef9ca4..a8f6617c9dc 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -375,7 +375,7 @@ impl AnonPipe { let mut overlapped: c::OVERLAPPED = unsafe { crate::mem::zeroed() }; // `hEvent` is unused by `ReadFileEx` and `WriteFileEx`. // Therefore the documentation suggests using it to smuggle a pointer to the callback. - overlapped.hEvent = core::ptr::addr_of_mut!(async_result) as *mut _; + overlapped.hEvent = (&raw mut async_result) as *mut _; // Asynchronous read of the pipe. // If successful, `callback` will be called once it completes. diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index 93a6c45ce30..95b51e704f9 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -368,10 +368,10 @@ impl Command { StartupInfo: si, lpAttributeList: proc_thread_attribute_list.0.as_mut_ptr() as _, }; - si_ptr = core::ptr::addr_of_mut!(si_ex) as _; + si_ptr = (&raw mut si_ex) as _; } else { si.cb = mem::size_of::<c::STARTUPINFOW>() as u32; - si_ptr = core::ptr::addr_of_mut!(si) as _; + si_ptr = (&raw mut si) as _; } unsafe { @@ -953,7 +953,7 @@ fn make_proc_thread_attribute_list( // It's theoretically possible for the attribute count to exceed a u32 value. // Therefore, we ensure that we don't add more attributes than the buffer was initialized for. for (&attribute, value) in attributes.iter().take(attribute_count as usize) { - let value_ptr = core::ptr::addr_of!(*value.data) as _; + let value_ptr = (&raw const *value.data) as _; cvt(unsafe { c::UpdateProcThreadAttribute( proc_thread_attribute_list.0.as_mut_ptr() as _, diff --git a/library/std/src/sys/sync/thread_parking/pthread.rs b/library/std/src/sys/sync/thread_parking/pthread.rs index c64600e9e29..5f195d0bb0c 100644 --- a/library/std/src/sys/sync/thread_parking/pthread.rs +++ b/library/std/src/sys/sync/thread_parking/pthread.rs @@ -3,7 +3,6 @@ use crate::cell::UnsafeCell; use crate::marker::PhantomPinned; use crate::pin::Pin; -use crate::ptr::addr_of_mut; use crate::sync::atomic::AtomicUsize; use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; #[cfg(not(target_os = "nto"))] @@ -101,8 +100,8 @@ impl Parker { // This could lead to undefined behaviour when deadlocking. This is avoided // by not deadlocking. Note in particular the unlocking operation before any // panic, as code after the panic could try to park again. - addr_of_mut!((*parker).state).write(AtomicUsize::new(EMPTY)); - addr_of_mut!((*parker).lock).write(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER)); + (&raw mut (*parker).state).write(AtomicUsize::new(EMPTY)); + (&raw mut (*parker).lock).write(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER)); cfg_if::cfg_if! { if #[cfg(any( @@ -112,9 +111,9 @@ impl Parker { target_os = "vita", target_vendor = "apple", ))] { - addr_of_mut!((*parker).cvar).write(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)); + (&raw mut (*parker).cvar).write(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)); } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { - let r = libc::pthread_cond_init(addr_of_mut!((*parker).cvar).cast(), crate::ptr::null()); + let r = libc::pthread_cond_init((&raw mut (*parker).cvar).cast(), crate::ptr::null()); assert_eq!(r, 0); } else { use crate::mem::MaybeUninit; @@ -123,7 +122,7 @@ impl Parker { assert_eq!(r, 0); let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC); assert_eq!(r, 0); - let r = libc::pthread_cond_init(addr_of_mut!((*parker).cvar).cast(), attr.as_ptr()); + let r = libc::pthread_cond_init((&raw mut (*parker).cvar).cast(), attr.as_ptr()); assert_eq!(r, 0); let r = libc::pthread_condattr_destroy(attr.as_mut_ptr()); assert_eq!(r, 0); diff --git a/library/std/src/sys/sync/thread_parking/windows7.rs b/library/std/src/sys/sync/thread_parking/windows7.rs index cdd59757fe2..8f7e66c46ef 100644 --- a/library/std/src/sys/sync/thread_parking/windows7.rs +++ b/library/std/src/sys/sync/thread_parking/windows7.rs @@ -178,7 +178,7 @@ impl Parker { } fn ptr(&self) -> *const c_void { - core::ptr::addr_of!(self.state).cast::<c_void>() + (&raw const self.state).cast::<c_void>() } } diff --git a/library/std/src/sys/thread_local/destructors/linux_like.rs b/library/std/src/sys/thread_local/destructors/linux_like.rs index c381be0bf8c..f473dc4d79d 100644 --- a/library/std/src/sys/thread_local/destructors/linux_like.rs +++ b/library/std/src/sys/thread_local/destructors/linux_like.rs @@ -47,7 +47,7 @@ pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { dtor, ), t.cast(), - core::ptr::addr_of!(__dso_handle) as *mut _, + (&raw const __dso_handle) as *mut _, ); } } else { diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 57f07d05cae..5a0ad907581 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -74,7 +74,7 @@ pub fn setsockopt<T>( sock.as_raw(), level, option_name, - core::ptr::addr_of!(option_value) as *const _, + (&raw const option_value) as *const _, mem::size_of::<T>() as c::socklen_t, ))?; Ok(()) @@ -89,7 +89,7 @@ pub fn getsockopt<T: Copy>(sock: &Socket, level: c_int, option_name: c_int) -> i sock.as_raw(), level, option_name, - core::ptr::addr_of_mut!(option_value) as *mut _, + (&raw mut option_value) as *mut _, &mut option_len, ))?; Ok(option_value) @@ -103,7 +103,7 @@ where unsafe { let mut storage: c::sockaddr_storage = mem::zeroed(); let mut len = mem::size_of_val(&storage) as c::socklen_t; - cvt(f(core::ptr::addr_of_mut!(storage) as *mut _, &mut len))?; + cvt(f((&raw mut storage) as *mut _, &mut len))?; sockaddr_to_addr(&storage, len as usize) } } @@ -452,7 +452,7 @@ impl TcpListener { pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() }; let mut len = mem::size_of_val(&storage) as c::socklen_t; - let sock = self.inner.accept(core::ptr::addr_of_mut!(storage) as *mut _, &mut len)?; + let sock = self.inner.accept((&raw mut storage) as *mut _, &mut len)?; let addr = sockaddr_to_addr(&storage, len as usize)?; Ok((TcpStream { inner: sock }, addr)) } diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 554e07c1e59..19d4c94f450 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -26,7 +26,6 @@ use crate::borrow::Cow; use crate::collections::TryReserveError; use crate::hash::{Hash, Hasher}; use crate::iter::FusedIterator; -use crate::ptr::addr_of_mut; use crate::rc::Rc; use crate::sync::Arc; use crate::sys_common::AsInner; @@ -1055,6 +1054,6 @@ unsafe impl CloneToUninit for Wtf8 { #[cfg_attr(debug_assertions, track_caller)] unsafe fn clone_to_uninit(&self, dst: *mut Self) { // SAFETY: we're just a wrapper around [u8] - unsafe { self.bytes.clone_to_uninit(addr_of_mut!((*dst).bytes)) } + unsafe { self.bytes.clone_to_uninit(&raw mut (*dst).bytes) } } } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index a53e3565dfe..41f02af9366 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -165,7 +165,6 @@ use crate::marker::PhantomData; use crate::mem::{self, ManuallyDrop, forget}; use crate::num::NonZero; use crate::pin::Pin; -use crate::ptr::addr_of_mut; use crate::sync::Arc; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::sync::Parker; @@ -1386,9 +1385,9 @@ impl Thread { let inner = unsafe { let mut arc = Arc::<Inner>::new_uninit(); let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr(); - addr_of_mut!((*ptr).name).write(name); - addr_of_mut!((*ptr).id).write(ThreadId::new()); - Parker::new_in_place(addr_of_mut!((*ptr).parker)); + (&raw mut (*ptr).name).write(name); + (&raw mut (*ptr).id).write(ThreadId::new()); + Parker::new_in_place(&raw mut (*ptr).parker); Pin::new_unchecked(arc.assume_init()) }; diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 1d856ce1879..715f8b57876 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -222,14 +222,14 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a pub unsafe fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word { let mut val: _Unwind_Word = core::ptr::null(); _Unwind_VRS_Get(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, - core::ptr::addr_of_mut!(val) as *mut c_void); + (&raw mut val) as *mut c_void); val } pub unsafe fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word) { let mut value = value; _Unwind_VRS_Set(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, - core::ptr::addr_of_mut!(value) as *mut c_void); + (&raw mut value) as *mut c_void); } pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index f4c5fe5ff94..0ee2cb451f3 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -46,6 +46,7 @@ static SETTINGS_HASHES: &[&str] = &[ "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", + "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", ]; static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyzer_settings.json"); diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index d329fe997cd..a20105f0ef3 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -10,6 +10,7 @@ ], "rust-analyzer.linkedProjects": [ "Cargo.toml", + "library/Cargo.toml", "src/tools/x/Cargo.toml", "src/bootstrap/Cargo.toml", "src/tools/rust-analyzer/Cargo.toml", diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 3879f350e94..6b4c0e9c0b9 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -764,7 +764,6 @@ ui/consts/issue-46553.rs ui/consts/issue-47789.rs ui/consts/issue-50439.rs ui/consts/issue-52023-array-size-pointer-cast.rs -ui/consts/issue-52060.rs ui/consts/issue-54224.rs ui/consts/issue-54348.rs ui/consts/issue-54387.rs @@ -3830,7 +3829,6 @@ ui/stability-attribute/issue-28388-3.rs ui/stability-attribute/issue-99286-stable-intrinsics.rs ui/static/auxiliary/issue_24843.rs ui/static/issue-1660.rs -ui/static/issue-18118-2.rs ui/static/issue-18118.rs ui/static/issue-24446.rs ui/static/issue-24843.rs diff --git a/tests/debuginfo/constant-ordering-prologue.rs b/tests/debuginfo/constant-ordering-prologue.rs new file mode 100644 index 00000000000..f2d4fd37ce3 --- /dev/null +++ b/tests/debuginfo/constant-ordering-prologue.rs @@ -0,0 +1,35 @@ +//@ min-lldb-version: 310 + +//@ compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:break constant_ordering_prologue::binding +// gdb-command:run + +// gdb-command:print a +// gdb-check: = 19 +// gdb-command:print b +// gdb-check: = 20 +// gdb-command:print c +// gdb-check: = 21.5 + +// === LLDB TESTS ================================================================================== + +// lldb-command:b "constant_ordering_prologue::binding" +// lldb-command:run + +// lldb-command:print a +// lldb-check: = 19 +// lldb-command:print b +// lldb-check: = 20 +// lldb-command:print c +// lldb-check: = 21.5 + +fn binding(a: i64, b: u64, c: f64) { + let x = 0; +} + +fn main() { + binding(19, 20, 21.5); +} diff --git a/tests/ui/asm/aarch64/type-check-4.rs b/tests/ui/asm/aarch64/type-check-4.rs index 1169c3dcfa8..c24567bd5b0 100644 --- a/tests/ui/asm/aarch64/type-check-4.rs +++ b/tests/ui/asm/aarch64/type-check-4.rs @@ -1,31 +1,27 @@ //@ only-aarch64 -//@ compile-flags: -C target-feature=+neon +//@ build-fail -#![feature(repr_simd)] - -use std::arch::aarch64::float64x2_t; -use std::arch::{asm, global_asm}; - -#[repr(simd)] -#[derive(Copy, Clone)] -struct Simd256bit([f64; 4]); +use std::arch::global_asm; fn main() {} // Constants must be... constant -static S: i32 = 1; +static mut S: i32 = 1; const fn const_foo(x: i32) -> i32 { x } const fn const_bar<T>(x: T) -> T { x } -global_asm!("{}", const S); -//~^ ERROR referencing statics +global_asm!("{}", const unsafe { S }); +//~^ ERROR: evaluation of constant value failed +//~| mutable global memory global_asm!("{}", const const_foo(0)); -global_asm!("{}", const const_foo(S)); -//~^ ERROR referencing statics +global_asm!("{}", const const_foo(unsafe { S })); +//~^ ERROR: evaluation of constant value failed +//~| mutable global memory global_asm!("{}", const const_bar(0)); -global_asm!("{}", const const_bar(S)); -//~^ ERROR referencing statics +global_asm!("{}", const const_bar(unsafe { S })); +//~^ ERROR: evaluation of constant value failed +//~| mutable global memory diff --git a/tests/ui/asm/aarch64/type-check-4.stderr b/tests/ui/asm/aarch64/type-check-4.stderr index 89eb8467cde..8c22dfcdb5e 100644 --- a/tests/ui/asm/aarch64/type-check-4.stderr +++ b/tests/ui/asm/aarch64/type-check-4.stderr @@ -1,39 +1,21 @@ -error[E0658]: referencing statics in constants is unstable - --> $DIR/type-check-4.rs:24:25 +error[E0080]: evaluation of constant value failed + --> $DIR/type-check-4.rs:17:34 | -LL | global_asm!("{}", const S); - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. +LL | global_asm!("{}", const unsafe { S }); + | ^ constant accesses mutable global memory -error[E0658]: referencing statics in constants is unstable - --> $DIR/type-check-4.rs:27:35 - | -LL | global_asm!("{}", const const_foo(S)); - | ^ +error[E0080]: evaluation of constant value failed + --> $DIR/type-check-4.rs:21:44 | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. +LL | global_asm!("{}", const const_foo(unsafe { S })); + | ^ constant accesses mutable global memory -error[E0658]: referencing statics in constants is unstable - --> $DIR/type-check-4.rs:30:35 - | -LL | global_asm!("{}", const const_bar(S)); - | ^ +error[E0080]: evaluation of constant value failed + --> $DIR/type-check-4.rs:25:44 | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. +LL | global_asm!("{}", const const_bar(unsafe { S })); + | ^ constant accesses mutable global memory error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/asm/const-refs-to-static.rs b/tests/ui/asm/const-refs-to-static.rs index 9fc010b5763..ce2c5b3246e 100644 --- a/tests/ui/asm/const-refs-to-static.rs +++ b/tests/ui/asm/const-refs-to-static.rs @@ -2,8 +2,6 @@ //@ ignore-nvptx64 //@ ignore-spirv -#![feature(const_refs_to_static)] - use std::arch::{asm, global_asm}; use std::ptr::addr_of; diff --git a/tests/ui/asm/const-refs-to-static.stderr b/tests/ui/asm/const-refs-to-static.stderr index 8fd69da0d1e..10e1ca5bd60 100644 --- a/tests/ui/asm/const-refs-to-static.stderr +++ b/tests/ui/asm/const-refs-to-static.stderr @@ -1,5 +1,5 @@ error: invalid type for `const` operand - --> $DIR/const-refs-to-static.rs:12:19 + --> $DIR/const-refs-to-static.rs:10:19 | LL | global_asm!("{}", const addr_of!(FOO)); | ^^^^^^------------- @@ -9,7 +9,7 @@ LL | global_asm!("{}", const addr_of!(FOO)); = help: `const` operands must be of an integer type error: invalid type for `const` operand - --> $DIR/const-refs-to-static.rs:17:25 + --> $DIR/const-refs-to-static.rs:15:25 | LL | unsafe { asm!("{}", const addr_of!(FOO)) }; | ^^^^^^------------- diff --git a/tests/ui/asm/x86_64/type-check-4.rs b/tests/ui/asm/x86_64/type-check-4.rs index 9503cd6d8ab..ebc6edc07e4 100644 --- a/tests/ui/asm/x86_64/type-check-4.rs +++ b/tests/ui/asm/x86_64/type-check-4.rs @@ -1,26 +1,27 @@ //@ only-x86_64 -//@ compile-flags: -C target-feature=+avx512f +//@ build-fail -use std::arch::{asm, global_asm}; - -use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps}; +use std::arch::global_asm; fn main() {} // Constants must be... constant -static S: i32 = 1; +static mut S: i32 = 1; const fn const_foo(x: i32) -> i32 { x } const fn const_bar<T>(x: T) -> T { x } -global_asm!("{}", const S); -//~^ ERROR referencing statics +global_asm!("{}", const unsafe { S }); +//~^ ERROR evaluation of constant value failed +//~| mutable global memory global_asm!("{}", const const_foo(0)); -global_asm!("{}", const const_foo(S)); -//~^ ERROR referencing statics +global_asm!("{}", const const_foo(unsafe { S })); +//~^ ERROR evaluation of constant value failed +//~| mutable global memory global_asm!("{}", const const_bar(0)); -global_asm!("{}", const const_bar(S)); -//~^ ERROR referencing statics +global_asm!("{}", const const_bar(unsafe { S })); +//~^ ERROR evaluation of constant value failed +//~| mutable global memory diff --git a/tests/ui/asm/x86_64/type-check-4.stderr b/tests/ui/asm/x86_64/type-check-4.stderr index f1bbc9e7d33..8c22dfcdb5e 100644 --- a/tests/ui/asm/x86_64/type-check-4.stderr +++ b/tests/ui/asm/x86_64/type-check-4.stderr @@ -1,39 +1,21 @@ -error[E0658]: referencing statics in constants is unstable - --> $DIR/type-check-4.rs:19:25 +error[E0080]: evaluation of constant value failed + --> $DIR/type-check-4.rs:17:34 | -LL | global_asm!("{}", const S); - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. +LL | global_asm!("{}", const unsafe { S }); + | ^ constant accesses mutable global memory -error[E0658]: referencing statics in constants is unstable - --> $DIR/type-check-4.rs:22:35 - | -LL | global_asm!("{}", const const_foo(S)); - | ^ +error[E0080]: evaluation of constant value failed + --> $DIR/type-check-4.rs:21:44 | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. +LL | global_asm!("{}", const const_foo(unsafe { S })); + | ^ constant accesses mutable global memory -error[E0658]: referencing statics in constants is unstable - --> $DIR/type-check-4.rs:25:35 - | -LL | global_asm!("{}", const const_bar(S)); - | ^ +error[E0080]: evaluation of constant value failed + --> $DIR/type-check-4.rs:25:44 | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. +LL | global_asm!("{}", const const_bar(unsafe { S })); + | ^ constant accesses mutable global memory error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.rs b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.rs new file mode 100644 index 00000000000..eb616631d1d --- /dev/null +++ b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.rs @@ -0,0 +1,28 @@ +// Demonstrates a mostly-theoretical inference guidance now that we turn the where +// clause on `Trait` into an item bound, given that we prefer item bounds somewhat +// greedily in trait selection. + +trait Bound<T> {} +impl<T, U> Bound<T> for U {} + +trait Trait +where + <<Self as Trait>::Assoc as Other>::Assoc: Bound<u32>, +{ + type Assoc: Other; +} + +trait Other { + type Assoc; +} + +fn impls_trait<T: Bound<U>, U>() -> Vec<U> { vec![] } + +fn foo<T: Trait>() { + let mut vec_u = impls_trait::<<<T as Trait>::Assoc as Other>::Assoc, _>(); + vec_u.sort(); + drop::<Vec<u8>>(vec_u); + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.stderr b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.stderr new file mode 100644 index 00000000000..c77400f3822 --- /dev/null +++ b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/nested-associated-type-bound-incompleteness.rs:24:21 + | +LL | drop::<Vec<u8>>(vec_u); + | --------------- ^^^^^ expected `Vec<u8>`, found `Vec<u32>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Vec<u8>` + found struct `Vec<u32>` +note: function defined here + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-type-bounds/nested-gat-projection.rs b/tests/ui/associated-type-bounds/nested-gat-projection.rs new file mode 100644 index 00000000000..ad37da9ed19 --- /dev/null +++ b/tests/ui/associated-type-bounds/nested-gat-projection.rs @@ -0,0 +1,31 @@ +//@ check-pass + +trait Trait +where + for<'a> Self::Gat<'a>: OtherTrait, + for<'a, 'b, 'c> <Self::Gat<'a> as OtherTrait>::OtherGat<'b>: HigherRanked<'c>, +{ + type Gat<'a>; +} + +trait OtherTrait { + type OtherGat<'b>; +} + +trait HigherRanked<'c> {} + +fn lower_ranked<T: for<'b, 'c> OtherTrait<OtherGat<'b>: HigherRanked<'c>>>() {} + +fn higher_ranked<T: Trait>() +where + for<'a> T::Gat<'a>: OtherTrait, + for<'a, 'b, 'c> <T::Gat<'a> as OtherTrait>::OtherGat<'b>: HigherRanked<'c>, +{ +} + +fn test<T: Trait>() { + lower_ranked::<T::Gat<'_>>(); + higher_ranked::<T>(); +} + +fn main() {} diff --git a/tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs b/tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs new file mode 100644 index 00000000000..864c3189350 --- /dev/null +++ b/tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +trait Trait +where + Self::Assoc: Clone, +{ + type Assoc; +} + +fn foo<T: Trait>(x: &T::Assoc) -> T::Assoc { + x.clone() +} + +trait Trait2 +where + Self::Assoc: Iterator, + <Self::Assoc as Iterator>::Item: Clone, +{ + type Assoc; +} + +fn foo2<T: Trait2>(x: &<T::Assoc as Iterator>::Item) -> <T::Assoc as Iterator>::Item { + x.clone() +} + +fn main() {} diff --git a/tests/ui/associated-types/imply-relevant-nested-item-bounds-for-gat.rs b/tests/ui/associated-types/imply-relevant-nested-item-bounds-for-gat.rs new file mode 100644 index 00000000000..4e3b0b3b148 --- /dev/null +++ b/tests/ui/associated-types/imply-relevant-nested-item-bounds-for-gat.rs @@ -0,0 +1,19 @@ +//@ check-pass + +// Test that `for<'a> Self::Gat<'a>: Debug` is implied in the definition of `Foo`, +// just as it would be if it weren't a GAT but just a regular associated type. + +use std::fmt::Debug; + +trait Foo +where + for<'a> Self::Gat<'a>: Debug, +{ + type Gat<'a>; +} + +fn test<T: Foo>(x: T::Gat<'static>) { + println!("{:?}", x); +} + +fn main() {} diff --git a/tests/ui/associated-types/imply-relevant-nested-item-bounds.rs b/tests/ui/associated-types/imply-relevant-nested-item-bounds.rs new file mode 100644 index 00000000000..5a477a5b349 --- /dev/null +++ b/tests/ui/associated-types/imply-relevant-nested-item-bounds.rs @@ -0,0 +1,23 @@ +//@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +trait Foo +where + Self::Iterator: Iterator, + <Self::Iterator as Iterator>::Item: Bar, +{ + type Iterator; + + fn iter() -> Self::Iterator; +} + +trait Bar { + fn bar(&self); +} + +fn x<T: Foo>() { + T::iter().next().unwrap().bar(); +} + +fn main() {} diff --git a/tests/ui/consts/const-fn-not-safe-for-const.rs b/tests/ui/consts/const-fn-not-safe-for-const.rs index 6d8404880ca..8a0cd86819e 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.rs +++ b/tests/ui/consts/const-fn-not-safe-for-const.rs @@ -18,12 +18,10 @@ static Y: u32 = 0; const fn get_Y() -> u32 { Y - //~^ ERROR referencing statics in constant functions } const fn get_Y_addr() -> &'static u32 { &Y - //~^ ERROR referencing statics in constant functions } const fn get() -> u32 { diff --git a/tests/ui/consts/const-fn-not-safe-for-const.stderr b/tests/ui/consts/const-fn-not-safe-for-const.stderr index 7d7e94da86f..674e05a0ba9 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.stderr +++ b/tests/ui/consts/const-fn-not-safe-for-const.stderr @@ -6,31 +6,6 @@ LL | random() | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0658]: referencing statics in constant functions is unstable - --> $DIR/const-fn-not-safe-for-const.rs:20:5 - | -LL | Y - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error[E0658]: referencing statics in constant functions is unstable - --> $DIR/const-fn-not-safe-for-const.rs:25:6 - | -LL | &Y - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index 7bf178484cc..2539fcccb84 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -1,7 +1,6 @@ //@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> " HEX_DUMP" //@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" -#![feature(const_refs_to_static)] use std::sync::Mutex; diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr index 4ea6fa62475..aebac56f8c5 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:19:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:18:1 | LL | const MUT: Option<&mut i32> = helper(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered reference to mutable memory in `const` @@ -10,7 +10,7 @@ LL | const MUT: Option<&mut i32> = helper(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:26:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:25:1 | LL | const INT2PTR: Option<&mut i32> = helper_int2ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (0x2a[noalloc] has no provenance) @@ -21,7 +21,7 @@ LL | const INT2PTR: Option<&mut i32> = helper_int2ptr(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:28:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:27:1 | LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (0x2a[noalloc] has no provenance) @@ -32,7 +32,7 @@ LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:35:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:34:1 | LL | const DANGLING: Option<&mut i32> = helper_dangling(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free) @@ -43,7 +43,7 @@ LL | const DANGLING: Option<&mut i32> = helper_dangling(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:36:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:35:1 | LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free) diff --git a/tests/ui/consts/const-ref-to-static-linux-vtable.rs b/tests/ui/consts/const-ref-to-static-linux-vtable.rs index b9d29d0c1f4..87af63d41ab 100644 --- a/tests/ui/consts/const-ref-to-static-linux-vtable.rs +++ b/tests/ui/consts/const-ref-to-static-linux-vtable.rs @@ -1,6 +1,6 @@ -//@check-pass +//@ check-pass //! This is the reduced version of the "Linux kernel vtable" use-case. -#![feature(const_refs_to_static)] + use std::ptr::addr_of_mut; #[repr(C)] diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.rs b/tests/ui/consts/const_refs_to_static-ice-121413.rs index 8fc3912efd0..5b2d27ae853 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.rs +++ b/tests/ui/consts/const_refs_to_static-ice-121413.rs @@ -3,7 +3,6 @@ // issue: rust-lang/rust#121413 //@ compile-flags: -Zextra-const-ub-checks // ignore-tidy-linelength -#![feature(const_refs_to_static)] const REF_INTERIOR_MUT: &usize = { //~^ HELP consider importing this struct static FOO: Sync = AtomicUsize::new(0); diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr index fbe32a70293..c977c698a92 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr +++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve: use of undeclared type `AtomicUsize` - --> $DIR/const_refs_to_static-ice-121413.rs:9:24 + --> $DIR/const_refs_to_static-ice-121413.rs:8:24 | LL | static FOO: Sync = AtomicUsize::new(0); | ^^^^^^^^^^^ use of undeclared type `AtomicUsize` @@ -10,7 +10,7 @@ LL + use std::sync::atomic::AtomicUsize; | warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/const_refs_to_static-ice-121413.rs:9:17 + --> $DIR/const_refs_to_static-ice-121413.rs:8:17 | LL | static FOO: Sync = AtomicUsize::new(0); | ^^^^ @@ -24,7 +24,7 @@ LL | static FOO: dyn Sync = AtomicUsize::new(0); | +++ error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time - --> $DIR/const_refs_to_static-ice-121413.rs:9:17 + --> $DIR/const_refs_to_static-ice-121413.rs:8:17 | LL | static FOO: Sync = AtomicUsize::new(0); | ^^^^ doesn't have a size known at compile-time @@ -32,7 +32,7 @@ LL | static FOO: Sync = AtomicUsize::new(0); = help: the trait `Sized` is not implemented for `(dyn Sync + 'static)` error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time - --> $DIR/const_refs_to_static-ice-121413.rs:9:24 + --> $DIR/const_refs_to_static-ice-121413.rs:8:24 | LL | static FOO: Sync = AtomicUsize::new(0); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/consts/const_refs_to_static.rs b/tests/ui/consts/const_refs_to_static.rs index f41725b786e..3c59697e8ed 100644 --- a/tests/ui/consts/const_refs_to_static.rs +++ b/tests/ui/consts/const_refs_to_static.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(const_refs_to_static)] static S: i32 = 0; static mut S_MUT: i32 = 0; diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs index a69902c3439..44e848ab637 100644 --- a/tests/ui/consts/const_refs_to_static_fail.rs +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -1,6 +1,8 @@ //@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" -#![feature(const_refs_to_static, sync_unsafe_cell)] + +#![feature(sync_unsafe_cell)] + use std::cell::SyncUnsafeCell; static S: SyncUnsafeCell<i32> = SyncUnsafeCell::new(0); diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr index cdabd86b183..297561dbcf1 100644 --- a/tests/ui/consts/const_refs_to_static_fail.stderr +++ b/tests/ui/consts/const_refs_to_static_fail.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail.rs:9:1 + --> $DIR/const_refs_to_static_fail.rs:11:1 | LL | const C1: &SyncUnsafeCell<i32> = &S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -10,13 +10,13 @@ LL | const C1: &SyncUnsafeCell<i32> = &S; } note: erroneous constant encountered - --> $DIR/const_refs_to_static_fail.rs:12:14 + --> $DIR/const_refs_to_static_fail.rs:14:14 | LL | assert!(*C1.get() == 0); | ^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refs_to_static_fail.rs:16:13 + --> $DIR/const_refs_to_static_fail.rs:18:13 | LL | assert!(*C2 == 0); | ^^^ constant accesses mutable global memory diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index c58606d2ebb..a160862a0fa 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -1,6 +1,5 @@ //@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" -#![feature(const_refs_to_static)] #![allow(static_mut_refs)] fn invalid() { diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index d5bb4847746..0153f501174 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:9:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:8:5 | LL | const C: &bool = unsafe { std::mem::transmute(&S) }; | ^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered 0x0a, but expected a boolean @@ -10,7 +10,7 @@ LL | const C: &bool = unsafe { std::mem::transmute(&S) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:25:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:24:5 | LL | const C: &i8 = unsafe { &S }; | ^^^^^^^^^^^^ constructing invalid value: encountered reference to `extern` static in `const` @@ -21,7 +21,7 @@ LL | const C: &i8 = unsafe { &S }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:39:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:38:5 | LL | const C: &i32 = unsafe { &S_MUT }; | ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -32,19 +32,19 @@ LL | const C: &i32 = unsafe { &S_MUT }; } error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:15:9 + --> $DIR/const_refs_to_static_fail_invalid.rs:14:9 | LL | C => {} | ^ error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:31:9 + --> $DIR/const_refs_to_static_fail_invalid.rs:30:9 | LL | C => {} | ^ error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:46:9 + --> $DIR/const_refs_to_static_fail_invalid.rs:45:9 | LL | C => {} | ^ diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index 52f8c9bf149..fca6cb08537 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -1,10 +1,15 @@ +//@ normalize-stderr-32bit: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" +//@ normalize-stderr-64bit: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" + #![allow(static_mut_refs)] const C1: &'static mut [usize] = &mut []; //~^ ERROR: mutable references are not allowed -static mut S: usize = 3; -const C2: &'static mut usize = unsafe { &mut S }; -//~^ ERROR: referencing statics in constants +static mut S: i32 = 3; +const C2: &'static mut i32 = unsafe { &mut S }; +//~^ ERROR: it is undefined behavior to use this value +//~| reference to mutable memory fn main() {} diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 57fcb1c7e9a..102491e90ba 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -1,22 +1,21 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/issue-17718-const-bad-values.rs:3:34 + --> $DIR/issue-17718-const-bad-values.rs:7:34 | LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ -error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-17718-const-bad-values.rs:7:46 +error[E0080]: it is undefined behavior to use this value + --> $DIR/issue-17718-const-bad-values.rs:11:1 | -LL | const C2: &'static mut usize = unsafe { &mut S }; - | ^ +LL | const C2: &'static mut i32 = unsafe { &mut S }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $PTR, align: $PTR) { + HEX_DUMP + } error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0080, E0764. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/issue-17718-references.rs b/tests/ui/consts/issue-17718-references.rs index 6a8955f4634..120ec28c404 100644 --- a/tests/ui/consts/issue-17718-references.rs +++ b/tests/ui/consts/issue-17718-references.rs @@ -1,23 +1,26 @@ +//@ check-pass #![allow(warnings)] -struct Struct { a: usize } +struct Struct { + a: usize, +} const C: usize = 1; static S: usize = 1; const T1: &'static usize = &C; -const T2: &'static usize = &S; //~ ERROR: referencing statics in constants +const T2: &'static usize = &S; static T3: &'static usize = &C; static T4: &'static usize = &S; const T5: usize = C; -const T6: usize = S; //~ ERROR: referencing statics in constants +const T6: usize = S; static T7: usize = C; static T8: usize = S; const T9: Struct = Struct { a: C }; const T10: Struct = Struct { a: S }; -//~^ ERROR: referencing statics in constants + static T11: Struct = Struct { a: C }; static T12: Struct = Struct { a: S }; diff --git a/tests/ui/consts/issue-17718-references.stderr b/tests/ui/consts/issue-17718-references.stderr deleted file mode 100644 index 8b572203781..00000000000 --- a/tests/ui/consts/issue-17718-references.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-17718-references.rs:9:29 - | -LL | const T2: &'static usize = &S; - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-17718-references.rs:14:19 - | -LL | const T6: usize = S; - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-17718-references.rs:19:33 - | -LL | const T10: Struct = Struct { a: S }; - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/issue-52060.rs b/tests/ui/consts/issue-52060.rs deleted file mode 100644 index 0f16ede0400..00000000000 --- a/tests/ui/consts/issue-52060.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Regression test for https://github.com/rust-lang/rust/issues/52060 -// The compiler shouldn't ICE in this case -static A: &'static [u32] = &[1]; -static B: [u32; 1] = [0; A.len()]; -//~^ ERROR referencing statics in constants - -fn main() {} diff --git a/tests/ui/consts/issue-52060.stderr b/tests/ui/consts/issue-52060.stderr deleted file mode 100644 index 644a5314622..00000000000 --- a/tests/ui/consts/issue-52060.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-52060.rs:4:26 - | -LL | static B: [u32; 1] = [0; A.len()]; - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/min_const_fn/min_const_fn.rs b/tests/ui/consts/min_const_fn/min_const_fn.rs index ed5aa40b66c..e6d9d184e04 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.rs +++ b/tests/ui/consts/min_const_fn/min_const_fn.rs @@ -74,8 +74,8 @@ const fn foo11_2<T: Send>(t: T) -> T { t } // not ok static BAR: u32 = 42; -const fn foo25() -> u32 { BAR } //~ ERROR referencing statics in constant functions -const fn foo26() -> &'static u32 { &BAR } //~ ERROR referencing statics in constant functions +const fn foo25() -> u32 { BAR } +const fn foo26() -> &'static u32 { &BAR } const fn foo30(x: *const u32) -> usize { x as usize } //~^ ERROR pointers cannot be cast to integers const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index c02f8c76d44..0e939e5121a 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -22,30 +22,6 @@ LL | const fn into_inner_s(self) -> T { self.0 } | | | the destructor for this type cannot be evaluated in constant functions -error[E0658]: referencing statics in constant functions is unstable - --> $DIR/min_const_fn.rs:77:27 - | -LL | const fn foo25() -> u32 { BAR } - | ^^^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error[E0658]: referencing statics in constant functions is unstable - --> $DIR/min_const_fn.rs:78:37 - | -LL | const fn foo26() -> &'static u32 { &BAR } - | ^^^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - error: pointers cannot be cast to integers during const eval --> $DIR/min_const_fn.rs:79:42 | @@ -98,7 +74,6 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 11 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0493, E0658. -For more information about an error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr index df910546d11..f8e0606fbd7 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -29,36 +29,11 @@ LL | const REF_INTERIOR_MUT: &usize = { warning: skipping const checks | -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:10:5 - | -LL | FOO.fetch_add(1, Ordering::Relaxed) - | ^^^ help: skipping check that does not even have a feature gate --> $DIR/const_refers_to_static.rs:10:5 | LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:15:17 - | -LL | unsafe { *(&FOO as *const _ as *const usize) } - | ^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:19:32 - | -LL | const READ_MUT: u32 = unsafe { MUTABLE }; - | ^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:25:18 - | -LL | unsafe { &*(&FOO as *const _ as *const usize) } - | ^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:30:25 - | -LL | const REF_IMMUT: &u8 = &MY_STATIC; - | ^^^^^^^^^ error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index 7a7b7bc57da..147d3f238f7 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -61,29 +61,6 @@ error: could not evaluate constant pattern LL | U8_MUT3 => true, | ^^^^^^^ -warning: skipping const checks - | -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:14:15 - | -LL | unsafe { &static_cross_crate::ZERO } - | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:19:15 - | -LL | unsafe { &static_cross_crate::ZERO[0] } - | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:17 - | -LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:29:15 - | -LL | match static_cross_crate::OPT_ZERO { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 8 previous errors; 1 warning emitted +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/mutable_references.rs b/tests/ui/consts/miri_unleashed/mutable_references.rs index 6ac61e67001..a60058cc5c0 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references.rs @@ -27,9 +27,12 @@ const BLUNT: &mut i32 = &mut 42; //~^ ERROR: it is undefined behavior to use this value //~| pointing to read-only memory -const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC }; -//~^ ERROR: it is undefined behavior to use this value -//~| static +const SUBTLE: &mut i32 = unsafe { + //~^ ERROR: it is undefined behavior to use this value + //~| constructing invalid value: encountered reference to mutable memory in `const` + static mut STATIC: i32 = 0; + &mut STATIC +}; // # Interior mutability @@ -105,7 +108,6 @@ const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ }; const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 }; //~^ ERROR mutable pointer in final value - fn main() { unsafe { *MEH.x.get() = 99; diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr index 874dd0389d4..ce5cedac8bc 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr @@ -46,7 +46,7 @@ LL | const BLUNT: &mut i32 = &mut 42; error[E0080]: it is undefined behavior to use this value --> $DIR/mutable_references.rs:30:1 | -LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC }; +LL | const SUBTLE: &mut i32 = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -55,7 +55,7 @@ LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC } } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:40:1 + --> $DIR/mutable_references.rs:43:1 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory @@ -66,7 +66,7 @@ LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:46:1 + --> $DIR/mutable_references.rs:49:1 | LL | const MUH: Meh = Meh { | ^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory @@ -77,7 +77,7 @@ LL | const MUH: Meh = Meh { } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:58:1 + --> $DIR/mutable_references.rs:61:1 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.x: encountered `UnsafeCell` in read-only memory @@ -88,7 +88,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:65:1 + --> $DIR/mutable_references.rs:68:1 | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -99,7 +99,7 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:72:1 + --> $DIR/mutable_references.rs:75:1 | LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -110,37 +110,37 @@ LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; } error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references.rs:75:43 + --> $DIR/mutable_references.rs:78:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:79:1 + --> $DIR/mutable_references.rs:82:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:82:1 + --> $DIR/mutable_references.rs:85:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:102:1 + --> $DIR/mutable_references.rs:105:1 | LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:105:1 + --> $DIR/mutable_references.rs:108:1 | LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item - --> $DIR/mutable_references.rs:113:5 + --> $DIR/mutable_references.rs:115:5 | LL | *OH_YES = 99; | ^^^^^^^^^^^^ cannot assign @@ -172,63 +172,48 @@ help: skipping check that does not even have a feature gate | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references.rs:30:68 - | -LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC }; - | ^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:40:28 + --> $DIR/mutable_references.rs:43:28 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:49:8 + --> $DIR/mutable_references.rs:52:8 | LL | x: &UnsafeCell::new(42), | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:58:27 + --> $DIR/mutable_references.rs:61:27 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references.rs:72:43 - | -LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; - | ^^^^^^^ -help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references.rs:75:45 - | -LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; - | ^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:79:45 + --> $DIR/mutable_references.rs:82:45 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:82:46 + --> $DIR/mutable_references.rs:85:46 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:87:47 + --> $DIR/mutable_references.rs:90:47 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:99:51 + --> $DIR/mutable_references.rs:102:51 | LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:102:49 + --> $DIR/mutable_references.rs:105:49 | LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:105:51 + --> $DIR/mutable_references.rs:108:51 | LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/no-ice-from-static-in-const-issue-52060.rs b/tests/ui/consts/no-ice-from-static-in-const-issue-52060.rs new file mode 100644 index 00000000000..e0f9e462d32 --- /dev/null +++ b/tests/ui/consts/no-ice-from-static-in-const-issue-52060.rs @@ -0,0 +1,9 @@ +// Regression test for https://github.com/rust-lang/rust/issues/52060 +// The compiler shouldn't ICE in this case + +static mut A: &'static [u32] = &[1]; +static B: [u32; 1] = [0; unsafe { A.len() }]; +//~^ ERROR: evaluation of constant value failed +//~| mutable global memory + +fn main() {} diff --git a/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr b/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr new file mode 100644 index 00000000000..ca4d3224ec7 --- /dev/null +++ b/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/no-ice-from-static-in-const-issue-52060.rs:5:35 + | +LL | static B: [u32; 1] = [0; unsafe { A.len() }]; + | ^ constant accesses mutable global memory + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs new file mode 100644 index 00000000000..448c7100df6 --- /dev/null +++ b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs @@ -0,0 +1,11 @@ +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] + +use std::ops::Coroutine; + +fn foo() -> impl Coroutine<u8> { + //~^ ERROR type mismatch in coroutine arguments + #[coroutine] + |_: ()| {} +} + +fn main() { } diff --git a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr new file mode 100644 index 00000000000..c7d6507fd79 --- /dev/null +++ b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr @@ -0,0 +1,15 @@ +error[E0631]: type mismatch in coroutine arguments + --> $DIR/arg-count-mismatch-on-unit-input.rs:5:13 + | +LL | fn foo() -> impl Coroutine<u8> { + | ^^^^^^^^^^^^^^^^^^ expected due to this +... +LL | |_: ()| {} + | ------- found signature defined here + | + = note: expected coroutine signature `fn(u8) -> _` + found coroutine signature `fn(()) -> _` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0631`. diff --git a/tests/ui/feature-gates/feature-gate-const-refs-to-static.rs b/tests/ui/feature-gates/feature-gate-const-refs-to-static.rs deleted file mode 100644 index 008b754dc6c..00000000000 --- a/tests/ui/feature-gates/feature-gate-const-refs-to-static.rs +++ /dev/null @@ -1,11 +0,0 @@ -static S: i32 = 0; -static mut S_MUT: i32 = 0; - -const C1: &i32 = &S; //~ERROR: referencing statics in constants is unstable -const C1_READ: () = { - assert!(*C1 == 0); -}; -const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; //~ERROR: referencing statics in constants is unstable - -fn main() { -} diff --git a/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr b/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr deleted file mode 100644 index 5af48471250..00000000000 --- a/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0658]: referencing statics in constants is unstable - --> $DIR/feature-gate-const-refs-to-static.rs:4:19 - | -LL | const C1: &i32 = &S; - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error[E0658]: referencing statics in constants is unstable - --> $DIR/feature-gate-const-refs-to-static.rs:8:52 - | -LL | const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; - | ^^^^^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs index b885352dfd9..0973e2f1637 100644 --- a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs +++ b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs @@ -2,7 +2,7 @@ #![deny(let_underscore_drop)] fn main() { - let _ = foo(); //~ ERROR non-binding let on a type that implements `Drop` + let _ = foo(); //~ ERROR non-binding let on a type that has a destructor } async fn from_config(_: Config) {} diff --git a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr index 86e521580b8..70f9979556a 100644 --- a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr +++ b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr @@ -1,4 +1,4 @@ -error: non-binding let on a type that implements `Drop` +error: non-binding let on a type that has a destructor --> $DIR/issue-119696-err-on-fn.rs:5:5 | LL | let _ = foo(); diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs index 1dc80a123f6..84abb933911 100644 --- a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs +++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs @@ -12,9 +12,9 @@ pub fn ice_cold(beverage: Tait) { // Must destructure at least one field of `Foo` let Foo { field } = beverage; // boom - _ = field; //~ ERROR non-binding let on a type that implements `Drop` + _ = field; //~ ERROR non-binding let on a type that has a destructor - let _ = field; //~ ERROR non-binding let on a type that implements `Drop` + let _ = field; //~ ERROR non-binding let on a type that has a destructor } diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr index 16df2c720ea..e4b1872bba5 100644 --- a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr +++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr @@ -1,4 +1,4 @@ -error: non-binding let on a type that implements `Drop` +error: non-binding let on a type that has a destructor --> $DIR/issue-119697-extra-let.rs:15:5 | LL | _ = field; @@ -18,7 +18,7 @@ help: consider immediately dropping the value LL | drop(field); | ~~~~~ + -error: non-binding let on a type that implements `Drop` +error: non-binding let on a type that has a destructor --> $DIR/issue-119697-extra-let.rs:17:5 | LL | let _ = field; diff --git a/tests/ui/lint/let_underscore/let_underscore_drop.rs b/tests/ui/lint/let_underscore/let_underscore_drop.rs index 58988ec05d7..f5a5e4299a1 100644 --- a/tests/ui/lint/let_underscore/let_underscore_drop.rs +++ b/tests/ui/lint/let_underscore/let_underscore_drop.rs @@ -10,7 +10,7 @@ impl Drop for NontrivialDrop { } fn main() { - let _ = NontrivialDrop; //~WARNING non-binding let on a type that implements `Drop` + let _ = NontrivialDrop; //~WARNING non-binding let on a type that has a destructor let (_, _) = (NontrivialDrop, NontrivialDrop); // This should be ignored. } diff --git a/tests/ui/lint/let_underscore/let_underscore_drop.stderr b/tests/ui/lint/let_underscore/let_underscore_drop.stderr index 7b7de202e46..09f2587063b 100644 --- a/tests/ui/lint/let_underscore/let_underscore_drop.stderr +++ b/tests/ui/lint/let_underscore/let_underscore_drop.stderr @@ -1,4 +1,4 @@ -warning: non-binding let on a type that implements `Drop` +warning: non-binding let on a type that has a destructor --> $DIR/let_underscore_drop.rs:13:5 | LL | let _ = NontrivialDrop; diff --git a/tests/ui/static/issue-18118-2.rs b/tests/ui/static/issue-18118-2.rs deleted file mode 100644 index 6c81eec7d7e..00000000000 --- a/tests/ui/static/issue-18118-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub fn main() { - const z: &'static isize = { - static p: isize = 3; - &p //~ ERROR referencing statics - }; -} diff --git a/tests/ui/static/issue-18118-2.stderr b/tests/ui/static/issue-18118-2.stderr deleted file mode 100644 index f084f2b9fdf..00000000000 --- a/tests/ui/static/issue-18118-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-18118-2.rs:4:10 - | -LL | &p - | ^ - | - = note: see issue #119618 <https://github.com/rust-lang/rust/issues/119618> for more information - = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - = help: to fix this, the value can be extracted to a `const` and then used. - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/statics/const_generics.rs b/tests/ui/statics/const_generics.rs index 7f64f6995a4..6cc0a65f77d 100644 --- a/tests/ui/statics/const_generics.rs +++ b/tests/ui/statics/const_generics.rs @@ -10,7 +10,6 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O -#![feature(const_refs_to_static)] #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] diff --git a/tests/ui/statics/mutable_memory_validation.rs b/tests/ui/statics/mutable_memory_validation.rs index d16b787fef8..032b903f64e 100644 --- a/tests/ui/statics/mutable_memory_validation.rs +++ b/tests/ui/statics/mutable_memory_validation.rs @@ -4,8 +4,6 @@ //@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" -#![feature(const_refs_to_static)] - use std::cell::UnsafeCell; struct Meh { diff --git a/tests/ui/statics/mutable_memory_validation.stderr b/tests/ui/statics/mutable_memory_validation.stderr index 60d13564679..76e1827ea12 100644 --- a/tests/ui/statics/mutable_memory_validation.stderr +++ b/tests/ui/statics/mutable_memory_validation.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_memory_validation.rs:15:1 + --> $DIR/mutable_memory_validation.rs:13:1 | LL | const MUH: Meh = Meh { x: unsafe { &mut *(&READONLY as *const _ as *mut _) } }; | ^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory |
