diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index c0c6c76473ba8..5478caee57d45 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -47,7 +47,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { if let Err(err) = fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { all_constants_ok = false; match err { - ErrorHandled::Reported(_) | ErrorHandled::Linted => { + ErrorHandled::Reported(_) => { fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); } ErrorHandled::TooGeneric => { diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index dd0daf2c38b10..b9600da5c39df 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -315,10 +315,10 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec { false } /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512gfni, - avx512ifma, avx512pf, avx512vaes, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpclmulqdq, - avx512vpopcntdq, bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, xsave, xsavec, xsaveopt, xsaves + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves */ //false }) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index e1f54356228d3..4af1aaec0a112 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -163,6 +163,9 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2] ("x86", "rdrand") => smallvec!["rdrnd"], ("x86", "bmi1") => smallvec!["bmi"], ("x86", "cmpxchg16b") => smallvec!["cx16"], + // FIXME: These aliases are misleading, and should be removed before avx512_target_feature is + // stabilized. They must remain until std::arch switches off them. + // rust#100752 ("x86", "avx512vaes") => smallvec!["vaes"], ("x86", "avx512gfni") => smallvec!["gfni"], ("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4445e5f6c3a64..2091730af2267 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1588,6 +1588,9 @@ fn detect_self_contained_mingw(sess: &Session) -> bool { /// We only provide such support for a very limited number of targets. fn self_contained(sess: &Session, crate_type: CrateType) -> bool { if let Some(self_contained) = sess.opts.cg.link_self_contained { + if sess.target.link_self_contained == LinkSelfContainedDefault::False { + sess.emit_err(errors::UnsupportedLinkSelfContained); + } return self_contained; } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index bfc4515de0984..ade50af0aee8d 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -530,3 +530,7 @@ pub enum AppleSdkRootError<'a> { pub struct ReadFileError { pub message: std::io::Error, } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsupported_link_self_contained)] +pub struct UnsupportedLinkSelfContained; diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index da9aaf00ecf6e..f4a300ef2c534 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -189,7 +189,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( all_consts_ok = false; match err { // errored or at least linted - ErrorHandled::Reported(_) | ErrorHandled::Linted => {} + ErrorHandled::Reported(_) => {} ErrorHandled::TooGeneric => { span_bug!(const_.span, "codegen encountered polymorphic constant: {:?}", err) } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a4368303de576..002aaf0db13cf 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -179,6 +179,7 @@ const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("f16c", Some(sym::f16c_target_feature)), ("fma", None), ("fxsr", None), + ("gfni", Some(sym::avx512_target_feature)), ("lzcnt", None), ("movbe", Some(sym::movbe_target_feature)), ("pclmulqdq", None), @@ -195,6 +196,8 @@ const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("sse4a", Some(sym::sse4a_target_feature)), ("ssse3", None), ("tbm", Some(sym::tbm_target_feature)), + ("vaes", Some(sym::avx512_target_feature)), + ("vpclmulqdq", Some(sym::avx512_target_feature)), ("xsave", None), ("xsavec", None), ("xsaveopt", None), diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 4977a5d6bbf05..e3dfd72d5f0e3 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -55,7 +55,7 @@ impl Error for ConstEvalErrKind {} /// When const-evaluation errors, this type is constructed with the resulting information, /// and then used to emit the error as a lint or hard error. #[derive(Debug)] -pub struct ConstEvalErr<'tcx> { +pub(super) struct ConstEvalErr<'tcx> { pub span: Span, pub error: InterpError<'tcx>, pub stacktrace: Vec>, @@ -82,8 +82,8 @@ impl<'tcx> ConstEvalErr<'tcx> { ConstEvalErr { error: error.into_kind(), stacktrace, span } } - pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled { - self.struct_error(tcx, message, |_| {}) + pub(super) fn report(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled { + self.report_decorated(tcx, message, |_| {}) } /// Create a diagnostic for this const eval error. @@ -95,7 +95,7 @@ impl<'tcx> ConstEvalErr<'tcx> { /// If `lint_root.is_some()` report it as a lint, else report it as a hard error. /// (Except that for some errors, we ignore all that -- see `must_error` below.) #[instrument(skip(self, tcx, decorate), level = "debug")] - pub fn struct_error( + pub(super) fn report_decorated( &self, tcx: TyCtxtAt<'tcx>, message: &str, diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 8f5e503d659da..f5942deaf9fa1 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -255,7 +255,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>( return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| { let span = tcx.def_span(def_id); let error = ConstEvalErr { error: error.into_kind(), stacktrace: vec![], span }; - error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic") + error.report(tcx.at(span), "could not evaluate nullary intrinsic") }); } @@ -333,7 +333,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( } }; - Err(err.report_as_error(ecx.tcx.at(err.span), &msg)) + Err(err.report(ecx.tcx.at(err.span), &msg)) } Ok(mplace) => { // Since evaluation had no errors, validate the resulting constant. @@ -358,7 +358,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( if let Err(error) = validation { // Validation failed, report an error. This is always a hard error. let err = ConstEvalErr::new(&ecx, error, None); - Err(err.struct_error( + Err(err.report_decorated( ecx.tcx, "it is undefined behavior to use this value", |diag| { diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 1c33e7845cb0b..01b2b4b5d9cd3 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -103,7 +103,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( ) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> { trace!("destructure_mir_constant: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.const_to_op(&val, None)?; + let op = ecx.eval_mir_constant(&val, None, None)?; // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { @@ -139,7 +139,7 @@ pub(crate) fn deref_mir_constant<'tcx>( val: mir::ConstantKind<'tcx>, ) -> mir::ConstantKind<'tcx> { let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); - let op = ecx.const_to_op(&val, None).unwrap(); + let op = ecx.eval_mir_constant(&val, None, None).unwrap(); let mplace = ecx.deref_operand(&op).unwrap(); if let Some(alloc_id) = mplace.ptr.provenance { assert_eq!( diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index ab82268dde3ab..ed69d8554d2cc 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -5,7 +5,7 @@ use std::mem; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::vec::IndexVec; use rustc_middle::mir; -use rustc_middle::mir::interpret::{InterpError, InvalidProgramInfo}; +use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidProgramInfo}; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, @@ -696,12 +696,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { for ct in &body.required_consts { let span = ct.span; let ct = self.subst_from_current_frame_and_normalize_erasing_regions(ct.literal)?; - self.const_to_op(&ct, None).map_err(|err| { - // If there was an error, set the span of the current frame to this constant. - // Avoiding doing this when evaluation succeeds. - self.frame_mut().loc = Err(span); - err - })?; + self.eval_mir_constant(&ct, Some(span), None)?; } // Most locals are initially dead. @@ -912,9 +907,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } - pub fn eval_to_allocation( + /// Call a query that can return `ErrorHandled`. If `span` is `Some`, point to that span when an error occurs. + pub fn ctfe_query( + &self, + span: Option, + query: impl FnOnce(TyCtxtAt<'tcx>) -> Result, + ) -> InterpResult<'tcx, T> { + // Use a precise span for better cycle errors. + query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| { + match err { + ErrorHandled::Reported(err) => { + if let Some(span) = span { + // To make it easier to figure out where this error comes from, also add a note at the current location. + self.tcx.sess.span_note_without_error(span, "erroneous constant used"); + } + err_inval!(AlreadyReported(err)) + } + ErrorHandled::TooGeneric => err_inval!(TooGeneric), + } + .into() + }) + } + + pub fn eval_global( &self, gid: GlobalId<'tcx>, + span: Option, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics // and thus don't care about the parameter environment. While we could just use @@ -927,8 +945,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env }; let param_env = param_env.with_const(); - // Use a precise span for better cycle errors. - let val = self.tcx.at(self.cur_span()).eval_to_allocation_raw(param_env.and(gid))?; + let val = self.ctfe_query(span, |tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?; self.raw_const_to_mplace(val) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index e68456a1d731a..6fc2407b77803 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -177,8 +177,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::type_name => self.tcx.mk_static_str(), _ => bug!(), }; - let val = - self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?; + let val = self.ctfe_query(None, |tcx| { + tcx.const_eval_global_id(self.param_env, gid, Some(tcx.span)) + })?; let val = self.const_val_to_op(val, ty, Some(dest.layout))?; self.copy_op(&val, dest, /*allow_transmute*/ false)?; } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 7c20d9138e171..528c1cb06c0eb 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -501,8 +501,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_unsup!(ReadExternStatic(def_id)); } - // Use a precise span for better cycle errors. - (self.tcx.at(self.cur_span()).eval_static_initializer(def_id)?, Some(def_id)) + // We don't give a span -- statics don't need that, they cannot be generic or associated. + let val = self.ctfe_query(None, |tcx| tcx.eval_static_initializer(def_id))?; + (val, Some(def_id)) } }; M::before_access_global(*self.tcx, &self.machine, id, alloc, def_id, is_write)?; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index f0a83b7a02689..cf9202540c7fe 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -4,8 +4,9 @@ use rustc_hir::def::Namespace; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; -use rustc_middle::ty::{ConstInt, Ty}; +use rustc_middle::ty::{ConstInt, Ty, ValTree}; use rustc_middle::{mir, ty}; +use rustc_span::Span; use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; @@ -527,14 +528,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?, Constant(ref constant) => { - let val = + let c = self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?; // This can still fail: // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all // checked yet. // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail. - self.const_to_op(&val, layout)? + self.eval_mir_constant(&c, Some(constant.span), layout)? } }; trace!("{:?}: {:?}", mir_op, *op); @@ -549,9 +550,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ops.iter().map(|op| self.eval_operand(op, None)).collect() } - pub fn const_to_op( + fn eval_ty_constant( + &self, + val: ty::Const<'tcx>, + span: Option, + ) -> InterpResult<'tcx, ValTree<'tcx>> { + Ok(match val.kind() { + ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => { + throw_inval!(TooGeneric) + } + ty::ConstKind::Error(reported) => { + throw_inval!(AlreadyReported(reported)) + } + ty::ConstKind::Unevaluated(uv) => { + let instance = self.resolve(uv.def, uv.substs)?; + let cid = GlobalId { instance, promoted: None }; + self.ctfe_query(span, |tcx| tcx.eval_to_valtree(self.param_env.and(cid)))? + .unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}")) + } + ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { + span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {val:?}") + } + ty::ConstKind::Value(valtree) => valtree, + }) + } + + pub fn eval_mir_constant( &self, val: &mir::ConstantKind<'tcx>, + span: Option, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { // FIXME(const_prop): normalization needed b/c const prop lint in @@ -563,44 +590,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = self.tcx.normalize_erasing_regions(self.param_env, *val); match val { mir::ConstantKind::Ty(ct) => { - match ct.kind() { - ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => { - throw_inval!(TooGeneric) - } - ty::ConstKind::Error(reported) => { - throw_inval!(AlreadyReported(reported)) - } - ty::ConstKind::Unevaluated(uv) => { - // NOTE: We evaluate to a `ValTree` here as a check to ensure - // we're working with valid constants, even though we never need it. - let instance = self.resolve(uv.def, uv.substs)?; - let cid = GlobalId { instance, promoted: None }; - let _valtree = self - .tcx - .eval_to_valtree(self.param_env.and(cid))? - .unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}")); - - Ok(self.eval_to_allocation(cid)?.into()) - } - ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { - span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {ct:?}") - } - ty::ConstKind::Value(valtree) => { - let ty = ct.ty(); - let const_val = self.tcx.valtree_to_const_val((ty, valtree)); - self.const_val_to_op(const_val, ty, layout) - } - } + let ty = ct.ty(); + let valtree = self.eval_ty_constant(ct, span)?; + let const_val = self.tcx.valtree_to_const_val((ty, valtree)); + self.const_val_to_op(const_val, ty, layout) } mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout), mir::ConstantKind::Unevaluated(uv, _) => { let instance = self.resolve(uv.def, uv.substs)?; - Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) + Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into()) } } } - pub(crate) fn const_val_to_op( + pub(super) fn const_val_to_op( &self, val_val: ConstValue<'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index eb6b403d00e88..70ce559526c36 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -184,3 +184,5 @@ codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error} codegen_ssa_read_file = failed to read file: {message} + +codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 182fbe36919d4..c02680b77fb15 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -22,7 +22,7 @@ use rustc_lint_defs::builtin::{ RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, }; use rustc_lint_defs::BuiltinLintDiagnostics; -use rustc_parse::parser::Parser; +use rustc_parse::parser::{Parser, Recovery}; use rustc_session::parse::ParseSess; use rustc_session::Session; use rustc_span::edition::Edition; @@ -219,6 +219,8 @@ pub(super) trait Tracker<'matcher> { /// For tracing. fn description() -> &'static str; + + fn recovery() -> Recovery; } /// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization. @@ -230,6 +232,9 @@ impl<'matcher> Tracker<'matcher> for NoopTracker { fn description() -> &'static str { "none" } + fn recovery() -> Recovery { + Recovery::Forbidden + } } /// Expands the rules based macro defined by `lhses` and `rhses` for a given @@ -330,7 +335,12 @@ fn expand_macro<'cx>( let mut tracker = CollectTrackerAndEmitter::new(cx, sp); let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut tracker); - assert!(try_success_result.is_err(), "Macro matching returned a success on the second try"); + + if try_success_result.is_ok() { + // Nonterminal parser recovery might turn failed matches into successful ones, + // but for that it must have emitted an error already + tracker.cx.sess.delay_span_bug(sp, "Macro matching returned a success on the second try"); + } if let Some(result) = tracker.result { // An irrecoverable error occurred and has been emitted. @@ -338,7 +348,7 @@ fn expand_macro<'cx>( } let Some((token, label, remaining_matcher)) = tracker.best_failure else { - return tracker.result.expect("must have encountered Error or ErrorReported"); + return DummyResult::any(sp); }; let span = token.span.substitute_dummy(sp); @@ -360,7 +370,7 @@ fn expand_macro<'cx>( // Check whether there's a missing comma in this macro call, like `println!("{}" a);` if let Some((arg, comma_span)) = arg.add_comma() { for lhs in lhses { - let parser = parser_from_cx(sess, arg.clone()); + let parser = parser_from_cx(sess, arg.clone(), Recovery::Allowed); let mut tt_parser = TtParser::new(name); if let Success(_) = @@ -406,7 +416,12 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, fn after_arm(&mut self, result: &NamedParseResult) { match result { Success(_) => { - unreachable!("should not collect detailed info for successful macro match"); + // Nonterminal parser recovery might turn failed matches into successful ones, + // but for that it must have emitted an error already + self.cx.sess.delay_span_bug( + self.root_span, + "should not collect detailed info for successful macro match", + ); } Failure(token, msg) => match self.best_failure { Some((ref best_token, _, _)) if best_token.span.lo() >= token.span.lo() => {} @@ -432,6 +447,10 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, fn description() -> &'static str { "detailed" } + + fn recovery() -> Recovery { + Recovery::Allowed + } } impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> { @@ -477,7 +496,7 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>( // 68836 suggests a more comprehensive but more complex change to deal with // this situation.) // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match. - let parser = parser_from_cx(sess, arg.clone()); + let parser = parser_from_cx(sess, arg.clone(), T::recovery()); // Try each arm's matchers. let mut tt_parser = TtParser::new(name); for (i, lhs) in lhses.iter().enumerate() { @@ -1559,8 +1578,8 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { } } -fn parser_from_cx(sess: &ParseSess, tts: TokenStream) -> Parser<'_> { - Parser::new(sess, tts, true, rustc_parse::MACRO_ARGUMENTS) +fn parser_from_cx(sess: &ParseSess, tts: TokenStream, recovery: Recovery) -> Parser<'_> { + Parser::new(sess, tts, true, rustc_parse::MACRO_ARGUMENTS).recovery(recovery) } /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 5cf2fdde39254..6934f87a574fa 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -439,6 +439,8 @@ declare_features! ( (active, lint_reasons, "1.31.0", Some(54503), None), /// Give access to additional metadata about declarative macro meta-variables. (active, macro_metavar_expr, "1.61.0", Some(83527), None), + /// Allows `#[manually_drop]` on type definitions. + (active, manually_drop_attr, "1.64.0", Some(100344), None), /// Allows `#[marker]` on certain traits allowing overlapping implementations. (active, marker_trait_attr, "1.30.0", Some(29864), None), /// A minimal, sound subset of specialization intended to be used by the diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4b6e068db4312..b34286e4fe1fe 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -480,6 +480,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ deprecated_safe, Normal, template!(List: r#"since = "version", note = "...""#), ErrorFollowing, experimental!(deprecated_safe), ), + // lang-team MCP 135 + gated!( + manually_drop, Normal, template!(Word), WarnFollowing, manually_drop_attr, experimental!(manually_drop), + ), // `#[collapse_debuginfo]` gated!( diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 0ba5e61510125..9828461432c5f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -113,8 +113,10 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b allowed_union_field(*elem, tcx, param_env, span) } _ => { - // Fallback case: allow `ManuallyDrop` and things that are `Copy`. - ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop()) + // Fallback case: if there is no destructor (including field drop glue), because it is + // `Copy` or is `#[manually_drop]` with no `Drop`, then allow it. + ty.ty_adt_def() + .is_some_and(|adt_def| adt_def.is_manually_drop() && !adt_def.has_dtor(tcx)) || ty.is_copy_modulo_regions(tcx, param_env) } } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 2b019c8c9b7a5..ed2218b8746ee 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -504,7 +504,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // method lookup. let Ok(pick) = self .probe_for_name( - call_expr.span, Mode::MethodCall, segment.ident, IsSuggestion(true), diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 4a8b774936543..3f390cba3e7c2 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -93,17 +93,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr_id: hir::HirId, allow_private: bool, ) -> bool { - let mode = probe::Mode::MethodCall; match self.probe_for_name( - method_name.span, - mode, + probe::Mode::MethodCall, method_name, IsSuggestion(false), self_ty, call_expr_id, ProbeScope::TraitsInScope, ) { - Ok(..) => true, + Ok(pick) => { + pick.maybe_emit_unstable_name_collision_hint( + self.tcx, + method_name.span, + call_expr_id, + ); + true + } Err(NoMatch(..)) => false, Err(Ambiguity(..)) => true, Err(PrivateMatch(..)) => allow_private, @@ -125,10 +130,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let params = self .probe_for_name( - method_name.span, probe::Mode::MethodCall, method_name, - IsSuggestion(false), + IsSuggestion(true), self_ty, call_expr.hir_id, ProbeScope::TraitsInScope, @@ -175,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args: &'tcx [hir::Expr<'tcx>], ) -> Result, MethodError<'tcx>> { let pick = - self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; + self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick, args); @@ -200,13 +204,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .mk_ref(*region, ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() }); // We probe again to see if there might be a borrow mutability discrepancy. match self.lookup_probe( - span, segment.ident, trait_type, call_expr, ProbeScope::TraitsInScope, ) { - Ok(ref new_pick) if *new_pick != pick => { + Ok(ref new_pick) if pick.differs_from(new_pick) => { needs_mut = true; } _ => {} @@ -214,28 +217,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // We probe again, taking all traits into account (not only those in scope). - let mut candidates = match self.lookup_probe( - span, - segment.ident, - self_ty, - call_expr, - ProbeScope::AllTraits, - ) { - // If we find a different result the caller probably forgot to import a trait. - Ok(ref new_pick) if *new_pick != pick => vec![new_pick.item.container_id(self.tcx)], - Err(Ambiguity(ref sources)) => sources - .iter() - .filter_map(|source| { - match *source { - // Note: this cannot come from an inherent impl, - // because the first probing succeeded. - CandidateSource::Impl(def) => self.tcx.trait_id_of_impl(def), - CandidateSource::Trait(_) => None, - } - }) - .collect(), - _ => Vec::new(), - }; + let mut candidates = + match self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::AllTraits) { + // If we find a different result the caller probably forgot to import a trait. + Ok(ref new_pick) if pick.differs_from(new_pick) => { + vec![new_pick.item.container_id(self.tcx)] + } + Err(Ambiguity(ref sources)) => sources + .iter() + .filter_map(|source| { + match *source { + // Note: this cannot come from an inherent impl, + // because the first probing succeeded. + CandidateSource::Impl(def) => self.tcx.trait_id_of_impl(def), + CandidateSource::Trait(_) => None, + } + }) + .collect(), + _ => Vec::new(), + }; candidates.retain(|candidate| *candidate != self.tcx.parent(result.callee.def_id)); return Err(IllegalSizedBound(candidates, needs_mut, span)); @@ -247,23 +247,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self, call_expr))] pub fn lookup_probe( &self, - span: Span, method_name: Ident, self_ty: Ty<'tcx>, call_expr: &'tcx hir::Expr<'tcx>, scope: ProbeScope, ) -> probe::PickResult<'tcx> { - let mode = probe::Mode::MethodCall; - let self_ty = self.resolve_vars_if_possible(self_ty); - self.probe_for_name( - span, - mode, + let pick = self.probe_for_name( + probe::Mode::MethodCall, method_name, IsSuggestion(false), self_ty, call_expr.hir_id, scope, - ) + )?; + pick.maybe_emit_unstable_name_collision_hint(self.tcx, method_name.span, call_expr.hir_id); + Ok(pick) } pub(super) fn obligation_for_method( @@ -587,7 +585,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let pick = self.probe_for_name( - span, probe::Mode::Path, method_name, IsSuggestion(false), @@ -596,6 +593,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProbeScope::TraitsInScope, )?; + pick.maybe_emit_unstable_name_collision_hint(self.tcx, span, expr_id); + self.lint_fully_qualified_call_from_2018( span, method_name, diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3fcd073f59793..46a760851893d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -17,6 +17,7 @@ use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::middle::stability; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; +use rustc_middle::ty::AssocItem; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; @@ -83,8 +84,6 @@ struct ProbeContext<'a, 'tcx> { unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option>, Option>)>, - is_suggestion: IsSuggestion, - scope_expr_id: hir::HirId, } @@ -193,7 +192,7 @@ impl AutorefOrPtrAdjustment { } } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, Clone)] pub struct Pick<'tcx> { pub item: ty::AssocItem, pub kind: PickKind<'tcx>, @@ -209,6 +208,9 @@ pub struct Pick<'tcx> { /// `*mut T`, convert it to `*const T`. pub autoref_or_ptr_adjustment: Option, pub self_ty: Ty<'tcx>, + + /// Unstable candidates alongside the stable ones. + unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -298,7 +300,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub fn probe_for_name( &self, - span: Span, mode: Mode, item_name: Ident, is_suggestion: IsSuggestion, @@ -307,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { scope: ProbeScope, ) -> PickResult<'tcx> { self.probe_op( - span, + item_name.span, mode, Some(item_name), None, @@ -446,7 +447,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type, orig_values, steps.steps, - is_suggestion, scope_expr_id, ); @@ -541,7 +541,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return_type: Option>, orig_steps_var_values: OriginalQueryValues<'tcx>, steps: &'tcx [CandidateStep<'tcx>], - is_suggestion: IsSuggestion, scope_expr_id: hir::HirId, ) -> ProbeContext<'a, 'tcx> { ProbeContext { @@ -559,7 +558,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { allow_similar_names: false, private_candidate: None, unsatisfied_predicates: Vec::new(), - is_suggestion, scope_expr_id, } } @@ -881,7 +879,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - pub fn matches_return_type( + fn matches_return_type( &self, method: &ty::AssocItem, self_ty: Option>, @@ -1052,26 +1050,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } fn pick_core(&mut self) -> Option> { - let mut unstable_candidates = Vec::new(); - let pick = self.pick_all_method(Some(&mut unstable_candidates)); + let pick = self.pick_all_method(Some(&mut vec![])); // In this case unstable picking is done by `pick_method`. if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable { return pick; } - match pick { - // Emit a lint if there are unstable candidates alongside the stable ones. - // - // We suppress warning if we're picking the method only because it is a - // suggestion. - Some(Ok(ref p)) if !self.is_suggestion.0 && !unstable_candidates.is_empty() => { - self.emit_unstable_name_collision_hint(p, &unstable_candidates); - pick - } - Some(_) => pick, - None => self.pick_all_method(None), + if pick.is_none() { + return self.pick_all_method(None); } + pick } fn pick_all_method( @@ -1216,7 +1205,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty)); let mut possibly_unsatisfied_predicates = Vec::new(); - let mut unstable_candidates = Vec::new(); for (kind, candidates) in &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] @@ -1226,26 +1214,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self_ty, candidates.iter(), &mut possibly_unsatisfied_predicates, - Some(&mut unstable_candidates), + Some(&mut vec![]), ); - if let Some(pick) = res { - if !self.is_suggestion.0 && !unstable_candidates.is_empty() { - if let Ok(p) = &pick { - // Emit a lint if there are unstable candidates alongside the stable ones. - // - // We suppress warning if we're picking the method only because it is a - // suggestion. - self.emit_unstable_name_collision_hint(p, &unstable_candidates); - } - } - return Some(pick); + if res.is_some() { + return res; } } debug!("searching unstable candidates"); let res = self.consider_candidates( self_ty, - unstable_candidates.iter().map(|(c, _)| c), + self.inherent_candidates.iter().chain(&self.extension_candidates), &mut possibly_unsatisfied_predicates, None, ); @@ -1300,7 +1279,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { Option>, Option>, )>, - unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, ) -> Option> where ProbesIter: Iterator> + Clone, @@ -1324,7 +1303,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - if let Some(uc) = unstable_candidates { + if let Some(uc) = &mut unstable_candidates { applicable_candidates.retain(|&(p, _)| { if let stability::EvalResult::Deny { feature, .. } = self.tcx.eval_stability(p.item.def_id, None, self.span, None) @@ -1343,30 +1322,63 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { applicable_candidates.pop().map(|(probe, status)| { if status == ProbeResult::Match { - Ok(probe.to_unadjusted_pick(self_ty)) + Ok(probe + .to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default())) } else { Err(MethodError::BadReturnType) } }) } +} + +impl<'tcx> Pick<'tcx> { + /// In case there were unstable name collisions, emit them as a lint. + /// Checks whether two picks do not refer to the same trait item for the same `Self` type. + /// Only useful for comparisons of picks in order to improve diagnostics. + /// Do not use for type checking. + pub fn differs_from(&self, other: &Self) -> bool { + let Self { + item: + AssocItem { + def_id, + name: _, + kind: _, + container: _, + trait_item_def_id: _, + fn_has_self_parameter: _, + }, + kind: _, + import_ids: _, + autoderefs: _, + autoref_or_ptr_adjustment: _, + self_ty, + unstable_candidates: _, + } = *self; + self_ty != other.self_ty || def_id != other.item.def_id + } - fn emit_unstable_name_collision_hint( + /// In case there were unstable name collisions, emit them as a lint. + pub fn maybe_emit_unstable_name_collision_hint( &self, - stable_pick: &Pick<'_>, - unstable_candidates: &[(Candidate<'tcx>, Symbol)], + tcx: TyCtxt<'tcx>, + span: Span, + scope_expr_id: hir::HirId, ) { - let def_kind = stable_pick.item.kind.as_def_kind(); - self.tcx.struct_span_lint_hir( + if self.unstable_candidates.is_empty() { + return; + } + let def_kind = self.item.kind.as_def_kind(); + tcx.struct_span_lint_hir( lint::builtin::UNSTABLE_NAME_COLLISIONS, - self.scope_expr_id, - self.span, + scope_expr_id, + span, format!( "{} {} with this name may be added to the standard library in the future", def_kind.article(), - def_kind.descr(stable_pick.item.def_id), + def_kind.descr(self.item.def_id), ), |lint| { - match (stable_pick.item.kind, stable_pick.item.container) { + match (self.item.kind, self.item.container) { (ty::AssocKind::Fn, _) => { // FIXME: This should be a `span_suggestion` instead of `help` // However `self.span` only @@ -1375,31 +1387,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { lint.help(&format!( "call with fully qualified syntax `{}(...)` to keep using the current \ method", - self.tcx.def_path_str(stable_pick.item.def_id), + tcx.def_path_str(self.item.def_id), )); } (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { - let def_id = stable_pick.item.container_id(self.tcx); + let def_id = self.item.container_id(tcx); lint.span_suggestion( - self.span, + span, "use the fully qualified path to the associated const", format!( "<{} as {}>::{}", - stable_pick.self_ty, - self.tcx.def_path_str(def_id), - stable_pick.item.name + self.self_ty, + tcx.def_path_str(def_id), + self.item.name ), Applicability::MachineApplicable, ); } _ => {} } - if self.tcx.sess.is_nightly_build() { - for (candidate, feature) in unstable_candidates { + if tcx.sess.is_nightly_build() { + for (candidate, feature) in &self.unstable_candidates { lint.help(&format!( "add `#![feature({})]` to the crate attributes to enable `{}`", feature, - self.tcx.def_path_str(candidate.item.def_id), + tcx.def_path_str(candidate.item.def_id), )); } } @@ -1408,7 +1420,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }, ); } +} +impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn select_trait_candidate( &self, trait_ref: ty::TraitRef<'tcx>, @@ -1667,6 +1681,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { autoderefs: 0, autoref_or_ptr_adjustment: None, self_ty, + unstable_candidates: vec![], }) } @@ -1686,7 +1701,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.return_type, self.orig_steps_var_values.clone(), steps, - IsSuggestion(true), self.scope_expr_id, ); pcx.allow_similar_names = true; @@ -1894,7 +1908,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } impl<'tcx> Candidate<'tcx> { - fn to_unadjusted_pick(&self, self_ty: Ty<'tcx>) -> Pick<'tcx> { + fn to_unadjusted_pick( + &self, + self_ty: Ty<'tcx>, + unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>, + ) -> Pick<'tcx> { Pick { item: self.item, kind: match self.kind { @@ -1919,6 +1937,7 @@ impl<'tcx> Candidate<'tcx> { autoderefs: 0, autoref_or_ptr_adjustment: None, self_ty, + unstable_candidates, } } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index edfe12963dc63..19f56c738239b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -376,7 +376,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .hir() .expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id)); let probe = self.lookup_probe( - span, item_name, output_ty, call_expr, @@ -914,7 +913,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - self.check_for_inner_self(&mut err, source, span, rcvr_ty, item_name); + self.check_for_inner_self(&mut err, source, rcvr_ty, item_name); bound_spans.sort(); bound_spans.dedup(); @@ -1321,7 +1320,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]); let pick = self.probe_for_name( - span, Mode::MethodCall, item_name, IsSuggestion(true), @@ -1500,7 +1498,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, &|_, field_ty| { self.lookup_probe( - span, item_name, field_ty, call_expr, @@ -1548,7 +1545,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, err: &mut Diagnostic, source: SelfSource<'tcx>, - span: Span, actual: Ty<'tcx>, item_name: Ident, ) { @@ -1571,15 +1567,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - self.lookup_probe( - span, - item_name, - field_ty, - call_expr, - ProbeScope::TraitsInScope, - ) - .ok() - .map(|pick| (variant, field, pick)) + self.lookup_probe(item_name, field_ty, call_expr, ProbeScope::TraitsInScope) + .ok() + .map(|pick| (variant, field, pick)) }) .collect(); @@ -1644,12 +1634,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let [first] = ***substs else { return; }; let ty::GenericArgKind::Type(ty) = first.unpack() else { return; }; let Ok(pick) = self.lookup_probe( - span, - item_name, - ty, - call_expr, - ProbeScope::TraitsInScope, - ) else { return; }; + item_name, + ty, + call_expr, + ProbeScope::TraitsInScope, + ) else { return; }; let name = self.ty_to_value_string(actual); let inner_id = kind.did(); @@ -1899,7 +1888,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::QPath(ty) = self_source else { return; }; for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) { if let Ok(pick) = self.probe_for_name( - ty.span, Mode::Path, item_name, IsSuggestion(true), @@ -2107,7 +2095,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "), (self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"), ] { - match self.lookup_probe(span, item_name, *rcvr_ty, rcvr, ProbeScope::AllTraits) { + match self.lookup_probe(item_name, *rcvr_ty, rcvr, ProbeScope::AllTraits) { Ok(pick) => { // If the method is defined for the receiver we have, it likely wasn't `use`d. // We point at the method, but we just skip the rest of the check for arbitrary @@ -2141,7 +2129,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ] { if let Some(new_rcvr_t) = *rcvr_ty && let Ok(pick) = self.lookup_probe( - span, item_name, new_rcvr_t, rcvr, @@ -2522,7 +2509,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: method_name.span, }; let probe = self.lookup_probe( - expr.span, new_name, self_ty, self_expr, diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 952ea14887f7b..09a256c9b179b 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -330,12 +330,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514). // This helps avoid accidental drops. + // + // FIXME: This is not correct for `#[manually_drop]` in general, only when the struct is + // a smart pointer whose pointee is at the same address, and whose pointee implements `Drop`. + // Instead of checking for `#[manually_drop]`, this should likely be a more restricted check + // for such types, or else union really should special-case and only permit `ManuallyDrop`, and + // not `#[manually_drop]` types in general. if inside_union && source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop()) { let mut err = self.tcx.sess.struct_span_err( expr.span, - "not automatically applying `DerefMut` on `ManuallyDrop` union field", + "not automatically applying `DerefMut` on manually dropped union field", ); err.help( "writing to this reference calls the destructor for the old value", diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 1ea8baa3cae3c..ae0dbad8b08d7 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -16,8 +16,6 @@ pub enum ErrorHandled { /// Already reported an error for this evaluation, and the compilation is /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. Reported(ErrorGuaranteed), - /// Already emitted a lint for this evaluation. - Linted, /// Don't emit an error, the evaluation failed because the MIR was generic /// and the substs didn't fully monomorphize it. TooGeneric, @@ -89,18 +87,6 @@ fn print_backtrace(backtrace: &Backtrace) { eprintln!("\n\nAn error occurred in miri:\n{}", backtrace); } -impl From for InterpErrorInfo<'_> { - fn from(err: ErrorHandled) -> Self { - match err { - ErrorHandled::Reported(ErrorGuaranteed { .. }) | ErrorHandled::Linted => { - err_inval!(ReferencedConstant) - } - ErrorHandled::TooGeneric => err_inval!(TooGeneric), - } - .into() - } -} - impl From for InterpErrorInfo<'_> { fn from(err: ErrorGuaranteed) -> Self { InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into() @@ -138,9 +124,6 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context. TooGeneric, - /// Cannot compute this constant because it depends on another one - /// which already produced an error. - ReferencedConstant, /// Abort in case errors are already reported. AlreadyReported(ErrorGuaranteed), /// An error occurred during layout computation. @@ -158,9 +141,11 @@ impl fmt::Display for InvalidProgramInfo<'_> { use InvalidProgramInfo::*; match self { TooGeneric => write!(f, "encountered overly generic constant"), - ReferencedConstant => write!(f, "referenced constant has errors"), AlreadyReported(ErrorGuaranteed { .. }) => { - write!(f, "encountered constants with type errors, stopping evaluation") + write!( + f, + "an error has already been reported elsewhere (this sould not usually be printed)" + ) } Layout(ref err) => write!(f, "{err}"), FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"), diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 473894ac1cae8..b6c6e9d559c8c 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -175,6 +175,8 @@ impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxtAt<'tcx> { /// Evaluate a static's initializer, returning the allocation of the initializer's memory. + /// + /// The span is entirely ignored here, but still helpful for better query cycle errors. pub fn eval_static_initializer( self, def_id: DefId, @@ -187,6 +189,8 @@ impl<'tcx> TyCtxtAt<'tcx> { } /// Evaluate anything constant-like, returning the allocation of the final memory. + /// + /// The span is entirely ignored here, but still helpful for better query cycle errors. fn eval_to_allocation( self, gid: GlobalId<'tcx>, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 12e9ebfeaecae..63f5678d3c813 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2304,7 +2304,7 @@ impl<'tcx> ConstantKind<'tcx> { // FIXME: We might want to have a `try_eval`-like function on `Unevaluated` match tcx.const_eval_resolve(param_env, uneval, None) { Ok(val) => Self::Val(val, ty), - Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self, + Err(ErrorHandled::TooGeneric) => self, Err(ErrorHandled::Reported(guar)) => { Self::Ty(tcx.const_error_with_guaranteed(ty, guar)) } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index b0a2412ab153f..dcdd6453f843a 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -243,7 +243,7 @@ impl AdtDefData { if Some(did) == tcx.lang_items().owned_box() { flags |= AdtFlags::IS_BOX; } - if Some(did) == tcx.lang_items().manually_drop() { + if tcx.has_attr(did, sym::manually_drop) { flags |= AdtFlags::IS_MANUALLY_DROP; } if Some(did) == tcx.lang_items().unsafe_cell_type() { @@ -463,9 +463,7 @@ impl<'tcx> AdtDef<'tcx> { } Err(err) => { let msg = match err { - ErrorHandled::Reported(_) | ErrorHandled::Linted => { - "enum discriminant evaluation failed" - } + ErrorHandled::Reported(_) => "enum discriminant evaluation failed", ErrorHandled::TooGeneric => "enum discriminant depends on generics", }; tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg); diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index c1c613f6c602e..321cba693d9ee 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -226,7 +226,7 @@ impl<'tcx> ConstKind<'tcx> { // (which may be identity substs, see above), // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ValTree(val?))), - Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => None, + Err(ErrorHandled::TooGeneric) => None, Err(ErrorHandled::Reported(e)) => Some(Err(e)), } } @@ -237,7 +237,7 @@ impl<'tcx> ConstKind<'tcx> { // (which may be identity substs, see above), // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ConstVal(val))), - Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => None, + Err(ErrorHandled::TooGeneric) => None, Err(ErrorHandled::Reported(e)) => Some(Err(e)), } } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 14d265a402ef8..a9d5cceb6099c 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -443,8 +443,7 @@ where }); } - let skip_contents = - adt.is_union() || Some(adt.did()) == self.tcx().lang_items().manually_drop(); + let skip_contents = adt.is_union() || adt.is_manually_drop(); let contents_drop = if skip_contents { (self.succ, self.unwind) } else { diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 9b9f942b491a2..3f5890040c394 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -471,7 +471,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - self.ecx.const_to_op(&c.literal, None).ok() + // No span, we don't want errors to be shown. + self.ecx.eval_mir_constant(&c.literal, None, None).ok() } /// Returns the value, if any, of evaluating `place`. diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 163446c52e4c2..786063d538c0a 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -5,7 +5,6 @@ use crate::const_prop::CanConstProp; use crate::const_prop::ConstPropMachine; use crate::const_prop::ConstPropMode; use crate::MirLint; -use rustc_const_eval::const_eval::ConstEvalErr; use rustc_const_eval::interpret::Immediate; use rustc_const_eval::interpret::{ self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup, @@ -286,25 +285,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } /// Returns the value, if any, of evaluating `c`. - fn eval_constant( - &mut self, - c: &Constant<'tcx>, - _source_info: SourceInfo, - ) -> Option> { + fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Option> { // FIXME we need to revisit this for #67176 if c.needs_subst() { return None; } - match self.ecx.const_to_op(&c.literal, None) { - Ok(op) => Some(op), - Err(error) => { - let tcx = self.ecx.tcx.at(c.span); - let err = ConstEvalErr::new(&self.ecx, error, Some(c.span)); - err.report_as_error(tcx, "erroneous constant used"); - None - } - } + self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&c.literal, Some(c.span), None)) } /// Returns the value, if any, of evaluating `place`. diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index e296d4766c18b..cdf8011d4f5ab 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -773,7 +773,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match self.tcx.const_eval_resolve(param_env, ct.expand(), None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => val, - Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, + Err(ErrorHandled::Reported(_)) => return, Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, "collection encountered polymorphic constant: {:?}", @@ -788,7 +788,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match self.tcx.const_eval_resolve(param_env, uv, None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => val, - Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, + Err(ErrorHandled::Reported(_)) => return, Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, "collection encountered polymorphic constant: {:?}", diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 14dc490fb0232..13a38a1773509 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -503,8 +503,8 @@ impl<'a> Parser<'a> { parser } - pub fn forbid_recovery(mut self) -> Self { - self.recovery = Recovery::Forbidden; + pub fn recovery(mut self, recovery: Recovery) -> Self { + self.recovery = recovery; self } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2b6ff0a5cb9d3..88a3a2bd31a20 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -169,6 +169,7 @@ impl CheckAttrVisitor<'_> { sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target), sym::deprecated => self.check_deprecated(hir_id, attr, span, target), sym::macro_use | sym::macro_escape => self.check_macro_use(hir_id, attr, target), + sym::manually_drop => self.check_manually_drop(hir_id, attr, span, target), sym::path => self.check_generic_attr(hir_id, attr, target, Target::Mod), sym::plugin_registrar => self.check_plugin_registrar(hir_id, attr, target), sym::macro_export => self.check_macro_export(hir_id, attr, target), @@ -2017,6 +2018,17 @@ impl CheckAttrVisitor<'_> { } } + fn check_manually_drop(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + if !matches!(target, Target::Struct | Target::Enum) { + self.tcx.emit_spanned_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::ManuallyDropShouldBeAppliedToStructEnum { defn_span: span }, + ); + } + } + fn check_plugin_registrar(&self, hir_id: HirId, attr: &Attribute, target: Target) { if target != Target::Fn { self.tcx.emit_spanned_lint( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index c6cd69add28a0..ea794655680d1 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -603,6 +603,13 @@ pub struct MacroUse { pub name: Symbol, } +#[derive(LintDiagnostic)] +#[diag(passes_should_be_applied_to_struct_enum)] +pub struct ManuallyDropShouldBeAppliedToStructEnum { + #[label] + pub defn_span: Span, +} + #[derive(LintDiagnostic)] #[diag(passes_macro_export)] pub struct MacroExport; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a56450a3573d1..db050d7aae65d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -887,6 +887,7 @@ symbols! { main, managed_boxes, manually_drop, + manually_drop_attr, map, marker, marker_trait_attr, diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 93a956403e50f..6f0bbf0672d44 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -72,7 +72,8 @@ //! best we can with this target. Don't start relying on too much here unless //! you know what you're getting in to! -use super::{crt_objects, wasm_base, Cc, LinkerFlavor, Target}; +use super::crt_objects::{self, LinkSelfContainedDefault}; +use super::{wasm_base, Cc, LinkerFlavor, Target}; pub fn target() -> Target { let mut options = wasm_base::options(); @@ -83,6 +84,9 @@ pub fn target() -> Target { options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained(); + // FIXME: Figure out cases in which WASM needs to link with a native toolchain. + options.link_self_contained = LinkSelfContainedDefault::True; + // Right now this is a bit of a workaround but we're currently saying that // the target by default has a static crt which we're taking as a signal // for "use the bundled crt". If that's turned off then the system's crt diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs index 528a84a8b37cb..625d3b37c4f26 100644 --- a/compiler/rustc_target/src/spec/wasm_base.rs +++ b/compiler/rustc_target/src/spec/wasm_base.rs @@ -1,4 +1,3 @@ -use super::crt_objects::LinkSelfContainedDefault; use super::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel}; pub fn options() -> TargetOptions { @@ -95,9 +94,6 @@ pub fn options() -> TargetOptions { pre_link_args, - // FIXME: Figure out cases in which WASM needs to link with a native toolchain. - link_self_contained: LinkSelfContainedDefault::True, - // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when // PIC code is implemented this has quite a drastic effect if it stays // at the default, `pic`. In an effort to keep wasm binaries as minimal diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 1de85e2f288be..db3ddc9208ae2 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -198,13 +198,6 @@ pub fn is_const_evaluatable<'tcx>( .sess .delay_span_bug(span, "Missing value for constant, but no error reported?"), )), - Err(ErrorHandled::Linted) => { - let reported = infcx - .tcx - .sess - .delay_span_bug(span, "constant in type had error reported as lint"); - Err(NotConstEvaluatable::Error(reported)) - } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), } @@ -254,11 +247,6 @@ pub fn is_const_evaluatable<'tcx>( Err(err) }, - Err(ErrorHandled::Linted) => { - let reported = - infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); - Err(NotConstEvaluatable::Error(reported)) - } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index b486c07f354b9..4905bb69cc5ca 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -558,12 +558,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { NotConstEvaluatable::Error(reported), )), ), - (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { - span_bug!( - obligation.cause.span(), - "ConstEquate: const_eval_resolve returned an unexpected error" - ) - } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { if c1.has_non_region_infer() || c2.has_non_region_infer() { ProcessResult::Unchanged diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index aad3c37f84e5a..ec70d4411b915 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -48,8 +48,9 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { } ty::Adt(def, _) => { - if Some(def.did()) == tcx.lang_items().manually_drop() { - // `ManuallyDrop` never has a dtor. + if def.is_manually_drop() && !def.has_dtor(tcx) { + // A `#[manually_drop]` type without a Drop impl (e.g. `ManuallyDrop`) + // does not run any code at all when dropped. true } else { // Other types might. Moreover, PhantomData doesn't diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a12f67125bbc0..3a899c03b4c94 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -727,12 +727,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } (Err(ErrorHandled::Reported(_)), _) | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr), - (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { - span_bug!( - obligation.cause.span(), - "ConstEquate: const_eval_resolve returned an unexpected error" - ) - } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { if c1.has_non_region_infer() || c2.has_non_region_infer() { Ok(EvaluatedToAmbig) diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 024dcd591bd77..4353c5db0da6e 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -212,10 +212,7 @@ fn drop_tys_helper<'tcx>( } let adt_components = move |adt_def: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>| { - if adt_def.is_manually_drop() { - debug!("drop_tys_helper: `{:?}` is manually drop", adt_def); - Ok(Vec::new()) - } else if let Some(dtor_info) = adt_has_dtor(adt_def) { + if let Some(dtor_info) = adt_has_dtor(adt_def) { match dtor_info { DtorType::Significant => { debug!("drop_tys_helper: `{:?}` implements `Drop`", adt_def); @@ -230,6 +227,9 @@ fn drop_tys_helper<'tcx>( Ok(substs.types().collect()) } } + } else if adt_def.is_manually_drop() { + debug!("drop_tys_helper: `{:?}` is manually drop", adt_def); + Ok(Vec::new()) } else if adt_def.is_union() { debug!("drop_tys_helper: `{:?}` is a union", adt_def); Ok(Vec::new()) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2d12805270f93..91509fcdf03cd 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -200,6 +200,7 @@ #![feature(lang_items)] #![feature(link_llvm_intrinsics)] #![feature(macro_metavar_expr)] +#![cfg_attr(not(bootstrap), feature(manually_drop_attr))] #![feature(min_specialization)] #![feature(must_not_suspend)] #![feature(negative_impls)] diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 3d719afe49e4a..f5a9ad20c0aa0 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -44,7 +44,8 @@ use crate::ptr; /// [`mem::zeroed`]: crate::mem::zeroed /// [`MaybeUninit`]: crate::mem::MaybeUninit #[stable(feature = "manually_drop", since = "1.20.0")] -#[lang = "manually_drop"] +#[cfg_attr(bootstrap, lang = "manually_drop")] +#[cfg_attr(not(bootstrap), manually_drop)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct ManuallyDrop { diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f5a49410ea555..7e355b7fccfc4 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -210,8 +210,8 @@ metrics. ## link-self-contained -On targets that support it this flag controls whether the linker will use libraries and objects -shipped with Rust instead or those in the system. +On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the +linker will use libraries and objects shipped with Rust instead or those in the system. It takes one of the following values: * no value: rustc will use heuristic to disable self-contained mode if system has necessary tools. diff --git a/src/doc/unstable-book/src/language-features/manually-drop-attr.md b/src/doc/unstable-book/src/language-features/manually-drop-attr.md new file mode 100644 index 0000000000000..602240d8d3569 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/manually-drop-attr.md @@ -0,0 +1,36 @@ +# `manually_drop_attr` + +The tracking issue for this feature is: [#100344] + +[#100344]: https://github.com/rust-lang/rust/issues/100344 + +The `manually_drop_attr` feature enables the `#[manually_drop]` attribute, which disables the drop glue for the type it is applied to. + +For example, `std::mem::ManuallyDrop` is implemented as follows: + +```rs +#[manually_drop] +struct ManuallyDrop(T); +``` + +But you can also use the attribute to change the order in which fields are dropped, by overriding `Drop`: + +```rs +/// This struct changes the order in which `x` and `y` are dropped from the default. +#[manually_drop] +struct MyStruct { + x: String, + y: String, +} + +impl Drop for MyStruct { + fn drop(&mut self) { + unsafe { + std::ptr::drop_in_place(&mut self.y); + std::ptr::drop_in_place(&mut self.x); + } + } +} +``` + +This can be useful in combination with `repr(C)`, to decouple the layout from the destruction order. See MCP [#135](https://github.com/rust-lang/lang-team/issues/135). diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 52b90f332d3df..9b1cac85cfd58 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -802,7 +802,6 @@ table, align-items: baseline; } #crate-search-div { - display: inline-block; /* ensures that 100% in properties of #crate-search-div:after are relative to the size of this div */ position: relative; @@ -1048,7 +1047,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ .rightside { padding-left: 12px; - padding-right: 2px; float: right; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 0538762e44d03..874f130d7e23c 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -47,10 +47,8 @@ function blurHandler(event, parentElem, hideCallback) { } } -(function() { - window.rootPath = getVar("root-path"); - window.currentCrate = getVar("current-crate"); -}()); +window.rootPath = getVar("root-path"); +window.currentCrate = getVar("current-crate"); function setMobileTopbar() { // FIXME: It would be nicer to generate this text content directly in HTML, diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr index c4cd9c2a49fd7..a1483911b297d 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr @@ -1,14 +1,14 @@ error[E0391]: cycle detected when const-evaluating + checking `Tr::A` - --> $DIR/defaults-cyclic-fail.rs:5:5 + --> $DIR/defaults-cyclic-fail.rs:5:19 | LL | const A: u8 = Self::B; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ | note: ...which requires const-evaluating + checking `Tr::B`... - --> $DIR/defaults-cyclic-fail.rs:8:5 + --> $DIR/defaults-cyclic-fail.rs:8:19 | LL | const B: u8 = Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ = note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle note: cycle used when const-evaluating + checking `main::promoted[1]` --> $DIR/defaults-cyclic-fail.rs:16:16 diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs index 6762d7583fb2d..495dfb338ae31 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs @@ -31,8 +31,7 @@ impl Tr for u32 { fn main() { assert_eq!(<() as Tr>::A, 255); assert_eq!(<() as Tr>::B, 0); // causes the error above - //~^ ERROR evaluation of constant value failed - //~| ERROR erroneous constant used + //~^ constant assert_eq!(::A, 254); assert_eq!(::B, 255); diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr index aa130f438a877..fb7159e40c996 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -4,20 +4,36 @@ error[E0080]: evaluation of `<() as Tr>::B` failed LL | const B: u8 = Self::A + 1; | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/defaults-not-assumed-fail.rs:33:16 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above - | ^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^ -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/defaults-not-assumed-fail.rs:33:5 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +note: erroneous constant used + --> $DIR/defaults-not-assumed-fail.rs:33:5 + | +LL | assert_eq!(<() as Tr>::B, 0); // causes the error above + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant used + --> $DIR/defaults-not-assumed-fail.rs:33:5 + | +LL | assert_eq!(<() as Tr>::B, 0); // causes the error above + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr index c8c57bccb5017..be57817615176 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr @@ -10,10 +10,10 @@ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:27 | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr index 76ed8d4a6e864..8347b260b5625 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr @@ -10,10 +10,10 @@ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`... LL | const DEFAULT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 + --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:30 | LL | const DEFAULT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `FooDefault::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 | diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 6a98f08f3d3ae..3955a3120c475 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -10,10 +10,10 @@ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... LL | const TRAIT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:28 | LL | const TRAIT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | diff --git a/src/test/ui/borrowck/issue-81899.rs b/src/test/ui/borrowck/issue-81899.rs index 24b20b6507b11..1f1af5c7e0502 100644 --- a/src/test/ui/borrowck/issue-81899.rs +++ b/src/test/ui/borrowck/issue-81899.rs @@ -2,13 +2,14 @@ // The `panic!()` below is important to trigger the fixed ICE. const _CONST: &[u8] = &f(&[], |_| {}); -//~^ ERROR constant +//~^ constant const fn f(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { - panic!() //~ ERROR: evaluation of constant value failed + panic!() //~ ERROR evaluation of constant value failed + //~^ panic } fn main() {} diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr index 12e80b9df8289..a4d5f212188d6 100644 --- a/src/test/ui/borrowck/issue-81899.stderr +++ b/src/test/ui/borrowck/issue-81899.stderr @@ -12,12 +12,12 @@ LL | panic!() | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-81899.rs:4:23 | LL | const _CONST: &[u8] = &f(&[], |_| {}); - | ^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.rs b/src/test/ui/borrowck/issue-88434-minimal-example.rs index 983a023105229..b75abcb731e23 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.rs +++ b/src/test/ui/borrowck/issue-88434-minimal-example.rs @@ -1,13 +1,14 @@ // Regression test related to issue 88434 const _CONST: &() = &f(&|_| {}); -//~^ ERROR constant +//~^ constant const fn f(_: &F) where F: FnMut(&u8), { panic!() //~ ERROR evaluation of constant value failed + //~^ panic } fn main() { } diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr index dc87c4c2b077b..b95ddc49c9964 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr +++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr @@ -12,12 +12,12 @@ LL | panic!() | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-88434-minimal-example.rs:3:21 | LL | const _CONST: &() = &f(&|_| {}); - | ^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs index a99c5b76a4e47..f9134e669dcab 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs @@ -1,13 +1,14 @@ // Regression test for issue 88434 const _CONST: &[u8] = &f(&[], |_| {}); -//~^ ERROR constant +//~^ constant const fn f(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { panic!() //~ ERROR evaluation of constant value failed + //~^ panic } fn main() { } diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index 4b4a25d7be121..604a6577639f4 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -12,12 +12,12 @@ LL | panic!() | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-88434-removal-index-should-be-less.rs:3:23 | LL | const _CONST: &[u8] = &f(&[], |_| {}); - | ^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-err-late.rs b/src/test/ui/consts/const-err-late.rs index a20ae702586c4..d2476e4934656 100644 --- a/src/test/ui/consts/const-err-late.rs +++ b/src/test/ui/consts/const-err-late.rs @@ -16,7 +16,5 @@ impl S { } fn main() { - black_box((S::::FOO, S::::FOO)); - //~^ ERROR erroneous constant - //~| ERROR erroneous constant + black_box((S::::FOO, S::::FOO)); //~ constant } diff --git a/src/test/ui/consts/const-err-late.stderr b/src/test/ui/consts/const-err-late.stderr index 3a8b103175b6b..c5c668189b952 100644 --- a/src/test/ui/consts/const-err-late.stderr +++ b/src/test/ui/consts/const-err-late.stderr @@ -4,11 +4,17 @@ error[E0080]: evaluation of `S::::FOO` failed LL | const FOO: u8 = [5u8][1]; | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/const-err-late.rs:19:16 | LL | black_box((S::::FOO, S::::FOO)); - | ^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/const-err-late.rs:19:16 + | +LL | black_box((S::::FOO, S::::FOO)); + | ^^^^^^^^^^^^^ error[E0080]: evaluation of `S::::FOO` failed --> $DIR/const-err-late.rs:13:21 @@ -16,12 +22,30 @@ error[E0080]: evaluation of `S::::FOO` failed LL | const FOO: u8 = [5u8][1]; | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 -error[E0080]: erroneous constant used +note: erroneous constant used + --> $DIR/const-err-late.rs:19:31 + | +LL | black_box((S::::FOO, S::::FOO)); + | ^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/const-err-late.rs:19:31 + | +LL | black_box((S::::FOO, S::::FOO)); + | ^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/const-err-late.rs:19:16 + | +LL | black_box((S::::FOO, S::::FOO)); + | ^^^^^^^^^^^^^ + +note: erroneous constant used --> $DIR/const-err-late.rs:19:31 | LL | black_box((S::::FOO, S::::FOO)); - | ^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-err-multi.rs b/src/test/ui/consts/const-err-multi.rs index fb26e8aac10ff..b265bc4c4d84f 100644 --- a/src/test/ui/consts/const-err-multi.rs +++ b/src/test/ui/consts/const-err-multi.rs @@ -1,11 +1,11 @@ pub const A: i8 = -i8::MIN; //~^ ERROR constant pub const B: i8 = A; -//~^ ERROR constant +//~^ constant pub const C: u8 = A as u8; -//~^ ERROR constant +//~^ constant pub const D: i8 = 50 - A; -//~^ ERROR constant +//~^ constant fn main() { let _ = (A, B, C, D); diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr index fca9e227068ff..28af8e5eb0918 100644 --- a/src/test/ui/consts/const-err-multi.stderr +++ b/src/test/ui/consts/const-err-multi.stderr @@ -4,24 +4,24 @@ error[E0080]: evaluation of constant value failed LL | pub const A: i8 = -i8::MIN; | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-err-multi.rs:3:19 | LL | pub const B: i8 = A; - | ^ referenced constant has errors + | ^ -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-err-multi.rs:5:19 | LL | pub const C: u8 = A as u8; - | ^ referenced constant has errors + | ^ -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-err-multi.rs:7:24 | LL | pub const D: i8 = 50 - A; - | ^ referenced constant has errors + | ^ -error: aborting due to 4 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/erroneous-const.rs b/src/test/ui/consts/const-eval/erroneous-const.rs index cf11531ba62ae..e0fd057a241a5 100644 --- a/src/test/ui/consts/const-eval/erroneous-const.rs +++ b/src/test/ui/consts/const-eval/erroneous-const.rs @@ -10,7 +10,7 @@ const fn no_codegen() { if false { // This bad constant is only used in dead code in a no-codegen function... and yet we still // must make sure that the build fails. - let _ = PrintName::::VOID; //~ERROR could not evaluate static initializer + let _ = PrintName::::VOID; //~ constant } } diff --git a/src/test/ui/consts/const-eval/erroneous-const.stderr b/src/test/ui/consts/const-eval/erroneous-const.stderr index 33579135d7c4e..03030392a5132 100644 --- a/src/test/ui/consts/const-eval/erroneous-const.stderr +++ b/src/test/ui/consts/const-eval/erroneous-const.stderr @@ -4,18 +4,12 @@ error[E0080]: evaluation of `PrintName::::VOID` failed LL | const VOID: () = [()][2]; | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 -error[E0080]: could not evaluate static initializer +note: erroneous constant used --> $DIR/erroneous-const.rs:13:17 | LL | let _ = PrintName::::VOID; | ^^^^^^^^^^^^^^^^^^^^ - | | - | referenced constant has errors - | inside `no_codegen::` at $DIR/erroneous-const.rs:13:17 -... -LL | pub static FOO: () = no_codegen::(); - | ------------------- inside `FOO` at $DIR/erroneous-const.rs:17:22 -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/erroneous-const2.rs b/src/test/ui/consts/const-eval/erroneous-const2.rs index 2fbf7be883535..15c0f910728a9 100644 --- a/src/test/ui/consts/const-eval/erroneous-const2.rs +++ b/src/test/ui/consts/const-eval/erroneous-const2.rs @@ -10,7 +10,7 @@ pub static FOO: () = { if false { // This bad constant is only used in dead code in a static initializer... and yet we still // must make sure that the build fails. - let _ = PrintName::::VOID; //~ERROR could not evaluate static initializer + let _ = PrintName::::VOID; //~ constant } }; diff --git a/src/test/ui/consts/const-eval/erroneous-const2.stderr b/src/test/ui/consts/const-eval/erroneous-const2.stderr index 630b1cf16aec9..8626f4d783397 100644 --- a/src/test/ui/consts/const-eval/erroneous-const2.stderr +++ b/src/test/ui/consts/const-eval/erroneous-const2.stderr @@ -4,12 +4,12 @@ error[E0080]: evaluation of `PrintName::::VOID` failed LL | const VOID: () = [()][2]; | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 -error[E0080]: could not evaluate static initializer +note: erroneous constant used --> $DIR/erroneous-const2.rs:13:17 | LL | let _ = PrintName::::VOID; - | ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/format.rs b/src/test/ui/consts/const-eval/format.rs index 3eef0d6c3d4d0..0d8b7c12d8abb 100644 --- a/src/test/ui/consts/const-eval/format.rs +++ b/src/test/ui/consts/const-eval/format.rs @@ -1,8 +1,6 @@ const fn failure() { panic!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR erroneous constant used - //~| ERROR erroneous constant used } const fn print() { @@ -10,8 +8,6 @@ const fn print() { //~^ ERROR cannot call non-const formatting macro in constant functions //~| ERROR `Arguments::<'a>::new_v1` is not yet stable as a const fn //~| ERROR cannot call non-const fn `_print` in constant functions - //~| ERROR erroneous constant used - //~| ERROR erroneous constant used } fn main() {} diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr index 64c7696486f78..4bf39db58746c 100644 --- a/src/test/ui/consts/const-eval/format.stderr +++ b/src/test/ui/consts/const-eval/format.stderr @@ -8,7 +8,7 @@ LL | panic!("{:?}", 0); = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:9:22 + --> $DIR/format.rs:7:22 | LL | println!("{:?}", 0); | ^ @@ -17,7 +17,7 @@ LL | println!("{:?}", 0); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: `Arguments::<'a>::new_v1` is not yet stable as a const fn - --> $DIR/format.rs:9:5 + --> $DIR/format.rs:7:5 | LL | println!("{:?}", 0); | ^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | println!("{:?}", 0); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const fn `_print` in constant functions - --> $DIR/format.rs:9:5 + --> $DIR/format.rs:7:5 | LL | println!("{:?}", 0); | ^^^^^^^^^^^^^^^^^^^ @@ -34,35 +34,62 @@ LL | println!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/format.rs:2:12 | LL | panic!("{:?}", 0); - | ^^^^^^ referenced constant has errors + | ^^^^^^ -error[E0080]: erroneous constant used +note: erroneous constant used + --> $DIR/format.rs:2:12 + | +LL | panic!("{:?}", 0); + | ^^^^^^ + +note: erroneous constant used --> $DIR/format.rs:2:20 | LL | panic!("{:?}", 0); - | ^ referenced constant has errors + | ^ | - = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant used + --> $DIR/format.rs:2:20 + | +LL | panic!("{:?}", 0); + | ^ + | + = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: erroneous constant used - --> $DIR/format.rs:9:14 +note: erroneous constant used + --> $DIR/format.rs:7:14 | LL | println!("{:?}", 0); - | ^^^^^^ referenced constant has errors + | ^^^^^^ -error[E0080]: erroneous constant used - --> $DIR/format.rs:9:22 +note: erroneous constant used + --> $DIR/format.rs:7:14 | LL | println!("{:?}", 0); - | ^ referenced constant has errors + | ^^^^^^ + +note: erroneous constant used + --> $DIR/format.rs:7:22 | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | println!("{:?}", 0); + | ^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant used + --> $DIR/format.rs:7:22 + | +LL | println!("{:?}", 0); + | ^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0080. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs index 2dbe1c2bd161b..e4dcc62302caa 100644 --- a/src/test/ui/consts/const-eval/issue-44578.rs +++ b/src/test/ui/consts/const-eval/issue-44578.rs @@ -23,6 +23,5 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ ERROR evaluation of constant value failed - //~| ERROR erroneous constant used + //~^ constant } diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index 963381b587093..0cbf5448000ae 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -4,20 +4,36 @@ error[E0080]: evaluation of ` as Foo>::AMT` failed LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-44578.rs:25:20 | LL | println!("{}", as Foo>::AMT); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/issue-44578.rs:25:20 | LL | println!("{}", as Foo>::AMT); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +note: erroneous constant used + --> $DIR/issue-44578.rs:25:20 + | +LL | println!("{}", as Foo>::AMT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant used + --> $DIR/issue-44578.rs:25:20 + | +LL | println!("{}", as Foo>::AMT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-50814-2.rs b/src/test/ui/consts/const-eval/issue-50814-2.rs index 49d1d8ff0805e..53eb7b149f931 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.rs +++ b/src/test/ui/consts/const-eval/issue-50814-2.rs @@ -15,7 +15,7 @@ impl Foo for A { } fn foo() -> &'static usize { - & as Foo>::BAR //~ ERROR E0080 + & as Foo>::BAR //~ constant } impl C for () { diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index 6604f2b9f8b5e..956f7aec9da8f 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -4,11 +4,11 @@ error[E0080]: evaluation of ` as Foo<()>>::BAR` failed LL | const BAR: usize = [5, 6, 7][T::BOO]; | ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 -error[E0080]: evaluation of `foo::<()>` failed +note: erroneous constant used --> $DIR/issue-50814-2.rs:18:6 | LL | & as Foo>::BAR - | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn foo::<()>` --> $DIR/issue-50814-2.rs:30:22 @@ -16,6 +16,6 @@ note: the above error was encountered while instantiating `fn foo::<()>` LL | println!("{:x}", foo::<()>() as *const usize as usize); | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-50814.rs b/src/test/ui/consts/const-eval/issue-50814.rs index 9c6108292b527..374ed1d93df94 100644 --- a/src/test/ui/consts/const-eval/issue-50814.rs +++ b/src/test/ui/consts/const-eval/issue-50814.rs @@ -18,7 +18,7 @@ impl Unsigned for Sum { fn foo(_: T) -> &'static u8 { &Sum::::MAX - //~^ ERROR evaluation of `foo::` failed [E0080] + //~^ constant } fn main() { diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index 38e9dc36ee98f..05b6271f4e4d5 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -4,11 +4,11 @@ error[E0080]: evaluation of ` as Unsigned>::MAX` failed LL | const MAX: u8 = A::MAX + B::MAX; | ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow -error[E0080]: evaluation of `foo::` failed +note: erroneous constant used --> $DIR/issue-50814.rs:20:6 | LL | &Sum::::MAX - | ^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn foo::` --> $DIR/issue-50814.rs:25:5 @@ -16,6 +16,6 @@ note: the above error was encountered while instantiating `fn foo::` LL | foo(0); | ^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs index d2a840932a5d1..28edf51440233 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs @@ -11,6 +11,5 @@ impl PrintName { } fn main() { - let _ = PrintName::VOID; - //~^ ERROR erroneous constant used [E0080] + let _ = PrintName::VOID; //~ constant } diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr index 4204d302bf83c..7c36a3a426e9e 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -6,12 +6,18 @@ LL | const VOID: ! = panic!(); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/panic-assoc-never-type.rs:14:13 | LL | let _ = PrintName::VOID; - | ^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/panic-assoc-never-type.rs:14:13 + | +LL | let _ = PrintName::VOID; + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index 6f5c028cbcab6..e5b5c7a846c11 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -60,14 +60,14 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-ref-ptr.rs:34:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:38:86 + --> $DIR/ub-ref-ptr.rs:37:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -75,14 +75,14 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:38:85 +note: erroneous constant used + --> $DIR/ub-ref-ptr.rs:37:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; - | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:42:1 + --> $DIR/ub-ref-ptr.rs:40:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated) @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:45:1 + --> $DIR/ub-ref-ptr.rs:43:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated) @@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:48:41 + --> $DIR/ub-ref-ptr.rs:46:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:52:1 + --> $DIR/ub-ref-ptr.rs:50:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:54:38 + --> $DIR/ub-ref-ptr.rs:52:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:57:1 + --> $DIR/ub-ref-ptr.rs:55:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:59:1 + --> $DIR/ub-ref-ptr.rs:57:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer @@ -148,6 +148,6 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; ╾─alloc41─╼ │ ╾──╼ } -error: aborting due to 16 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 5ffb710d45683..607366cabc4e9 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -60,14 +60,14 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-ref-ptr.rs:34:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:38:86 + --> $DIR/ub-ref-ptr.rs:37:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -75,14 +75,14 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:38:85 +note: erroneous constant used + --> $DIR/ub-ref-ptr.rs:37:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; - | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:42:1 + --> $DIR/ub-ref-ptr.rs:40:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated) @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:45:1 + --> $DIR/ub-ref-ptr.rs:43:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated) @@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:48:41 + --> $DIR/ub-ref-ptr.rs:46:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:52:1 + --> $DIR/ub-ref-ptr.rs:50:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:54:38 + --> $DIR/ub-ref-ptr.rs:52:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:57:1 + --> $DIR/ub-ref-ptr.rs:55:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:59:1 + --> $DIR/ub-ref-ptr.rs:57:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer @@ -148,6 +148,6 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; ╾───────alloc41───────╼ │ ╾──────╼ } -error: aborting due to 16 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.rs b/src/test/ui/consts/const-eval/ub-ref-ptr.rs index 92049d4c1792f..a1c81239009ac 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.rs @@ -33,11 +33,9 @@ const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; //~^ ERROR evaluation of constant value failed -//~| ERROR evaluation of constant value failed const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; //~^ ERROR evaluation of constant value failed -//~| ERROR evaluation of constant value failed const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; //~^ ERROR it is undefined behavior to use this value diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr index c8b46608d6bac..9994c2e5a8345 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -139,11 +139,11 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; ╾─allocN─╼ │ ╾──╼ } -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-wide-ptr.rs:83:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:90:1 @@ -156,11 +156,11 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 ╾allocN─╼ │ ╾──╼ } -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-wide-ptr.rs:90:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:94:1 @@ -173,11 +173,11 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran ╾allocN─╼ │ ╾──╼ } -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-wide-ptr.rs:94:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $DIR/ub-wide-ptr.rs:102:1 @@ -292,6 +292,6 @@ error[E0080]: could not evaluate static initializer LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable -error: aborting due to 32 previous errors +error: aborting due to 29 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index 70574d2dc3b5f..06a377d9f7c97 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -139,11 +139,11 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; ╾───────allocN───────╼ │ ╾──────╼ } -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-wide-ptr.rs:83:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:90:1 @@ -156,11 +156,11 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 ╾──────allocN───────╼ │ ╾──────╼ } -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-wide-ptr.rs:90:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:94:1 @@ -173,11 +173,11 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran ╾──────allocN───────╼ │ ╾──────╼ } -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/ub-wide-ptr.rs:94:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $DIR/ub-wide-ptr.rs:102:1 @@ -292,6 +292,6 @@ error[E0080]: could not evaluate static initializer LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable -error: aborting due to 32 previous errors +error: aborting due to 29 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs index 65f6f023528d0..2894ef831884c 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs @@ -82,18 +82,18 @@ const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; // bad data *inside* the slice const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; //~^ ERROR it is undefined behavior to use this value -//~| ERROR evaluation of constant value failed +//~| constant // good MySliceBool const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]); // bad: sized field is not okay const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); //~^ ERROR it is undefined behavior to use this value -//~| ERROR evaluation of constant value failed +//~| constant // bad: unsized part is not okay const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); //~^ ERROR it is undefined behavior to use this value -//~| ERROR evaluation of constant value failed +//~| constant // # raw slice const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // ok diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs index d88bf2a84793a..a94fcbbfa5634 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.rs +++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs @@ -29,7 +29,6 @@ const fn read_field3() -> Field3 { //~^ ERROR evaluation of constant value failed //~| uninitialized FIELD3 - //~^ ERROR erroneous constant used [E0080] } fn main() { diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr index 00964489e040f..9899c56c0ec3f 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr +++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr @@ -4,12 +4,18 @@ error[E0080]: evaluation of constant value failed LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 - | ^^^^^^ referenced constant has errors + | ^^^^^^ -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/union-const-eval-field.rs:31:5 + | +LL | FIELD3 + | ^^^^^^ + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-float-bits-reject-conv.rs b/src/test/ui/consts/const-float-bits-reject-conv.rs index 5bf54fdbb3fd6..c77e99abbf6d3 100644 --- a/src/test/ui/consts/const-float-bits-reject-conv.rs +++ b/src/test/ui/consts/const-float-bits-reject-conv.rs @@ -1,4 +1,5 @@ // compile-flags: -Zmir-opt-level=0 +// error-pattern: cannot use f32::to_bits on a NaN #![feature(const_float_bits_conv)] #![feature(const_float_classify)] @@ -25,22 +26,21 @@ fn f32() { // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits // ...actually, let's just check that these break. :D const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; + //~^ inside const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; + //~^ inside + + // The rest of the code is dead because the constants already fail to evaluate. const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); - //~^ ERROR evaluation of constant value failed const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); - //~^ ERROR evaluation of constant value failed // LLVM does not guarantee that loads and stores of NaNs preserve their exact bit pattern. // In practice, this seems to only cause a problem on x86, since the most widely used calling // convention mandates that floating point values are returned on the x87 FPU stack. See #73328. - if !cfg!(target_arch = "x86") { - const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); - //~^ ERROR evaluation of constant value failed - const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); - //~^ ERROR evaluation of constant value failed - } + // However, during CTFE we still preserve bit patterns (though that is not a guarantee). + const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); } fn f64() { @@ -48,20 +48,18 @@ fn f64() { // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits // ...actually, let's just check that these break. :D const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; + //~^ inside const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; + //~^ inside + + // The rest of the code is dead because the constants already fail to evaluate. const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); - //~^ ERROR evaluation of constant value failed const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); - //~^ ERROR evaluation of constant value failed // See comment above. - if !cfg!(target_arch = "x86") { - const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); - //~^ ERROR evaluation of constant value failed - const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); - //~^ ERROR evaluation of constant value failed - } + const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); } fn main() { diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr index b3575f64153ae..e1ad72416f264 100644 --- a/src/test/ui/consts/const-float-bits-reject-conv.stderr +++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr @@ -10,10 +10,10 @@ LL | panic!("const-eval error: cannot use f32::to_bits on a LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } | -------------------------------------------------------------------- inside `core::f32::::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:27:30 + ::: $DIR/const-float-bits-reject-conv.rs:28:30 | LL | const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; - | ------------------ inside `f32::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:27:30 + | ------------------ inside `f32::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:28:30 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -29,36 +29,36 @@ LL | panic!("const-eval error: cannot use f32::to_bits on a LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } | -------------------------------------------------------------------- inside `core::f32::::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:28:30 + ::: $DIR/const-float-bits-reject-conv.rs:30:30 | LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; - | ------------------ inside `f32::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:28:30 + | ------------------ inside `f32::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:30:30 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:30:34 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:35:34 | LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); - | ^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:32:34 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:36:34 | LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); - | ^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:39:38 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:42:34 | -LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); - | ^^^^^^^^^^^ referenced constant has errors +LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + | ^^^^^^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:41:38 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:43:34 | -LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); - | ^^^^^^^^^^^ referenced constant has errors +LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + | ^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/f64.rs:LL:COL @@ -91,37 +91,37 @@ LL | panic!("const-eval error: cannot use f64::to_bits on a LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } | -------------------------------------------------------------------- inside `core::f64::::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:51:30 + ::: $DIR/const-float-bits-reject-conv.rs:52:30 | LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; - | ------------------ inside `f64::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:51:30 + | ------------------ inside `f64::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:52:30 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:53:34 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:57:34 | LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); - | ^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:55:34 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:58:34 | LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); - | ^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:60:38 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:61:34 | -LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); - | ^^^^^^^^^^^ referenced constant has errors +LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + | ^^^^^^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const-float-bits-reject-conv.rs:62:38 +note: erroneous constant used + --> $DIR/const-float-bits-reject-conv.rs:62:34 | -LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); - | ^^^^^^^^^^^ referenced constant has errors +LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + | ^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-integer-bool-ops.rs b/src/test/ui/consts/const-integer-bool-ops.rs index 6924956bdf706..4110ae3e45692 100644 --- a/src/test/ui/consts/const-integer-bool-ops.rs +++ b/src/test/ui/consts/const-integer-bool-ops.rs @@ -6,7 +6,7 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; -//~^ ERROR evaluation of constant value failed +//~^ constant const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -16,7 +16,7 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; -//~^ ERROR evaluation of constant value failed +//~^ constant const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -26,7 +26,7 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ ERROR evaluation of constant value failed +//~^ constant const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -36,43 +36,43 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; -//~^ ERROR evaluation of constant value failed +//~^ constant const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; -//~^ ERROR evaluation of constant value failed +//~^ constant const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; -//~^ ERROR evaluation of constant value failed +//~^ constant const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; -//~^ ERROR evaluation of constant value failed +//~^ constant const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; -//~^ ERROR evaluation of constant value failed +//~^ constant const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; -//~^ ERROR evaluation of constant value failed +//~^ constant const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; -//~^ ERROR evaluation of constant value failed +//~^ constant fn main() { let _ = ARR; diff --git a/src/test/ui/consts/const-integer-bool-ops.stderr b/src/test/ui/consts/const-integer-bool-ops.stderr index 9001fefd1029f..b5c3b22fdbe36 100644 --- a/src/test/ui/consts/const-integer-bool-ops.stderr +++ b/src/test/ui/consts/const-integer-bool-ops.stderr @@ -16,11 +16,11 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:8:18 | LL | const ARR: [i32; X] = [99; 34]; - | ^ referenced constant has errors + | ^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:11:19 @@ -40,11 +40,11 @@ error[E0308]: mismatched types LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:18:19 | LL | const ARR1: [i32; X1] = [99; 47]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:21:19 @@ -64,11 +64,11 @@ error[E0308]: mismatched types LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:31:19 @@ -88,11 +88,11 @@ error[E0308]: mismatched types LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:38:19 | LL | const ARR3: [i32; X3] = [99; 6]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:41:18 @@ -100,11 +100,11 @@ error[E0308]: mismatched types LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:44:19 | LL | const ARRR: [i32; Y] = [99; 1]; - | ^ referenced constant has errors + | ^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:47:19 @@ -112,11 +112,11 @@ error[E0308]: mismatched types LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:50:20 | LL | const ARRR1: [i32; Y1] = [99; 1]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:53:19 @@ -124,11 +124,11 @@ error[E0308]: mismatched types LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:56:20 | LL | const ARRR2: [i32; Y2] = [99; 1]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:59:19 @@ -136,11 +136,11 @@ error[E0308]: mismatched types LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:62:20 | LL | const ARRR3: [i32; Y3] = [99; 0]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:65:19 @@ -148,11 +148,11 @@ error[E0308]: mismatched types LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:68:20 | LL | const ARRR4: [i32; Y4] = [99; 0]; - | ^^ referenced constant has errors + | ^^ error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:71:19 @@ -160,13 +160,12 @@ error[E0308]: mismatched types LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-integer-bool-ops.rs:74:20 | LL | const ARRR5: [i32; Y5] = [99; 0]; - | ^^ referenced constant has errors + | ^^ -error: aborting due to 28 previous errors +error: aborting due to 18 previous errors -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.rs b/src/test/ui/consts/const-len-underflow-separate-spans.rs index 478761aef2faa..4544c8876ae09 100644 --- a/src/test/ui/consts/const-len-underflow-separate-spans.rs +++ b/src/test/ui/consts/const-len-underflow-separate-spans.rs @@ -9,5 +9,5 @@ const LEN: usize = ONE - TWO; fn main() { let a: [i8; LEN] = unimplemented!(); -//~^ ERROR E0080 +//~^ constant } diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr index 1416e695e4c6e..269553631cc67 100644 --- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr @@ -4,12 +4,12 @@ error[E0080]: evaluation of constant value failed LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-len-underflow-separate-spans.rs:11:17 | LL | let a: [i8; LEN] = unimplemented!(); - | ^^^ referenced constant has errors + | ^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr index 0f420ae1b6b7c..109d15a8e4d85 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr +++ b/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr @@ -19,13 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-76510.rs:11:70 | LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - | ^ referenced constant has errors + | ^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0596, E0658, E0764. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr index 0f420ae1b6b7c..109d15a8e4d85 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr +++ b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -19,13 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-76510.rs:11:70 | LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - | ^ referenced constant has errors + | ^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0596, E0658, E0764. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.rs b/src/test/ui/consts/const-mut-refs/issue-76510.rs index 08cf64ee330db..b853e2737f126 100644 --- a/src/test/ui/consts/const-mut-refs/issue-76510.rs +++ b/src/test/ui/consts/const-mut-refs/issue-76510.rs @@ -9,7 +9,7 @@ const S: &'static mut str = &mut " hello "; const fn trigger() -> [(); unsafe { let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - //~^ ERROR evaluation of constant value failed + //~^ constant 0 }] { [(); 0] diff --git a/src/test/ui/consts/const-tup-index-span.rs b/src/test/ui/consts/const-tup-index-span.rs index 763263c6aeb4f..778a212249c19 100644 --- a/src/test/ui/consts/const-tup-index-span.rs +++ b/src/test/ui/consts/const-tup-index-span.rs @@ -4,7 +4,7 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected tuple, found `usize` const ARR: [i32; TUP.0] = []; -//~^ ERROR evaluation of constant value failed +//~^ constant fn main() { } diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr index b178e05e27a09..ad84680561726 100644 --- a/src/test/ui/consts/const-tup-index-span.stderr +++ b/src/test/ui/consts/const-tup-index-span.stderr @@ -11,13 +11,12 @@ help: use a trailing comma to create a tuple with one element LL | const TUP: (usize,) = (5usize << 64,); | + ++ -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/const-tup-index-span.rs:6:18 | LL | const ARR: [i32; TUP.0] = []; - | ^^^ referenced constant has errors + | ^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs index 159cdf257b19c..9c239c8a100f9 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -29,7 +29,7 @@ const UNALIGNED_PTR: () = unsafe { }; const UNALIGNED_READ: () = { - INNER; //[with_flag]~ERROR evaluation of constant value failed + INNER; //[with_flag]~ constant // There is an error here but its span is in the standard library so we cannot match it... // so we have this in a *nested* const, such that the *outer* const fails to use it. const INNER: () = unsafe { diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 3e119582291d3..4726905ade341 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -47,12 +47,12 @@ LL | unsafe { read(self) } LL | ptr.read(); | ---------- inside `INNER` at $DIR/detect-extra-ub.rs:38:9 -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/detect-extra-ub.rs:32:5 | LL | INNER; - | ^^^^^ referenced constant has errors + | ^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr index bad07989e4035..4758ea4ae8818 100644 --- a/src/test/ui/consts/invalid-union.32bit.stderr +++ b/src/test/ui/consts/invalid-union.32bit.stderr @@ -9,12 +9,24 @@ LL | fn main() { ╾─alloc7──╼ │ ╾──╼ } -error[E0080]: erroneous constant used - --> $DIR/invalid-union.rs:42:25 +note: erroneous constant used + --> $DIR/invalid-union.rs:43:25 | LL | let _: &'static _ = &C; - | ^^ referenced constant has errors + | ^^ -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/invalid-union.rs:43:25 + | +LL | let _: &'static _ = &C; + | ^^ + +note: erroneous constant used + --> $DIR/invalid-union.rs:43:25 + | +LL | let _: &'static _ = &C; + | ^^ + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index a209f0038ccaf..22b85d20ce9dd 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -9,12 +9,24 @@ LL | fn main() { ╾───────alloc7────────╼ │ ╾──────╼ } -error[E0080]: erroneous constant used - --> $DIR/invalid-union.rs:42:25 +note: erroneous constant used + --> $DIR/invalid-union.rs:43:25 | LL | let _: &'static _ = &C; - | ^^ referenced constant has errors + | ^^ -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/invalid-union.rs:43:25 + | +LL | let _: &'static _ = &C; + | ^^ + +note: erroneous constant used + --> $DIR/invalid-union.rs:43:25 + | +LL | let _: &'static _ = &C; + | ^^ + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/invalid-union.rs b/src/test/ui/consts/invalid-union.rs index 435d26d6e995e..28706b4a923e7 100644 --- a/src/test/ui/consts/invalid-union.rs +++ b/src/test/ui/consts/invalid-union.rs @@ -39,5 +39,6 @@ const C: S = { }; fn main() { //~ ERROR it is undefined behavior to use this value - let _: &'static _ = &C; //~ ERROR erroneous constant used + // FIXME the span here is wrong, sould be pointing at the line below, not above. + let _: &'static _ = &C; } diff --git a/src/test/ui/consts/issue-36163.stderr b/src/test/ui/consts/issue-36163.stderr index 9ac6c984cb0cd..7137c053847ce 100644 --- a/src/test/ui/consts/issue-36163.stderr +++ b/src/test/ui/consts/issue-36163.stderr @@ -5,10 +5,10 @@ LL | B = A, | ^ | note: ...which requires const-evaluating + checking `A`... - --> $DIR/issue-36163.rs:1:1 + --> $DIR/issue-36163.rs:1:18 | LL | const A: isize = Foo::B as isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating + checking `Foo::B::{constant#0}`, completing the cycle note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 diff --git a/src/test/ui/consts/issue-54954.rs b/src/test/ui/consts/issue-54954.rs index d4e1df2277094..520bf508ff339 100644 --- a/src/test/ui/consts/issue-54954.rs +++ b/src/test/ui/consts/issue-54954.rs @@ -9,8 +9,8 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - //~^ ERROR evaluation of constant value failed - //~| ERROR evaluation of constant value failed + //~^ constant + //~| constant z } diff --git a/src/test/ui/consts/issue-54954.stderr b/src/test/ui/consts/issue-54954.stderr index 668985c2b5914..85055828737b3 100644 --- a/src/test/ui/consts/issue-54954.stderr +++ b/src/test/ui/consts/issue-54954.stderr @@ -16,19 +16,19 @@ LL | | core::mem::size_of::() LL | | } | |_____- `Tt::const_val` defined here -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-54954.rs:11:15 | LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ referenced constant has errors + | ^^^^^^^ -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-54954.rs:11:34 | LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ referenced constant has errors + | ^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0080, E0379, E0790. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0379, E0790. +For more information about an error, try `rustc --explain E0379`. diff --git a/src/test/ui/consts/issue-56164.rs b/src/test/ui/consts/issue-56164.rs index df3e3bf902809..22c257d0b08af 100644 --- a/src/test/ui/consts/issue-56164.rs +++ b/src/test/ui/consts/issue-56164.rs @@ -1,6 +1,5 @@ const fn foo() { (||{})() } //~^ ERROR cannot call non-const closure -//~| ERROR erroneous constant used const fn bad(input: fn()) { input() diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr index c5b2c57fbee3d..2579b3e782720 100644 --- a/src/test/ui/consts/issue-56164.stderr +++ b/src/test/ui/consts/issue-56164.stderr @@ -8,18 +8,23 @@ LL | const fn foo() { (||{})() } = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: function pointer calls are not allowed in constant functions - --> $DIR/issue-56164.rs:6:5 + --> $DIR/issue-56164.rs:5:5 | LL | input() | ^^^^^^^ -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/issue-56164.rs:1:18 | LL | const fn foo() { (||{})() } - | ^^^^^^ referenced constant has errors + | ^^^^^^ -error: aborting due to 3 previous errors +note: erroneous constant used + --> $DIR/issue-56164.rs:1:18 + | +LL | const fn foo() { (||{})() } + | ^^^^^^ + +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0080. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/consts/issue-66693.rs b/src/test/ui/consts/issue-66693.rs index 1ff250be1b02e..df45d01ec0299 100644 --- a/src/test/ui/consts/issue-66693.rs +++ b/src/test/ui/consts/issue-66693.rs @@ -10,7 +10,6 @@ static _FOO: () = panic!(true); const fn _foo() { panic!(&1); //~^ ERROR: argument to `panic!()` in a const context must have type `&str` - //~| ERROR: erroneous constant used } // ensure that conforming panics don't cause an error diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr index 911374f507ec8..e9a3fced61cc1 100644 --- a/src/test/ui/consts/issue-66693.stderr +++ b/src/test/ui/consts/issue-66693.stderr @@ -22,12 +22,17 @@ LL | panic!(&1); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/issue-66693.rs:11:12 | LL | panic!(&1); - | ^^ referenced constant has errors + | ^^ -error: aborting due to 4 previous errors +note: erroneous constant used + --> $DIR/issue-66693.rs:11:12 + | +LL | panic!(&1); + | ^^ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.rs b/src/test/ui/consts/miri_unleashed/assoc_const.rs index 76ed667a514ff..7bb0c1b772ad1 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const.rs +++ b/src/test/ui/consts/miri_unleashed/assoc_const.rs @@ -26,5 +26,5 @@ fn main() { // this is fine, but would have been forbidden by the static checks on `F` let x = <() as Bar>::F; // this test only causes errors due to the line below, so post-monomorphization - let y = , String>>::F; //~ ERROR erroneous constant + let y = , String>>::F; //~ constant } diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr index 519bd0748e2b7..33e7e4af276f7 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr @@ -13,11 +13,23 @@ LL | pub unsafe fn drop_in_place(to_drop: *mut T) { LL | const F: u32 = (U::X, 42).1; | - inside `, String>>::F` at $DIR/assoc_const.rs:12:31 -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/assoc_const.rs:29:13 | LL | let y = , String>>::F; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/assoc_const.rs:29:13 + | +LL | let y = , String>>::F; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/assoc_const.rs:29:13 + | +LL | let y = , String>>::F; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: skipping const checks | @@ -27,6 +39,6 @@ help: skipping check that does not even have a feature gate LL | const F: u32 = (U::X, 42).1; | ^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.rs b/src/test/ui/consts/miri_unleashed/assoc_const_2.rs index 8377141ea5e12..aad5b34606ee3 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const_2.rs +++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.rs @@ -24,5 +24,5 @@ impl Bar for String {} fn main() { let x = <() as Bar<()>>::F; // this test only causes errors due to the line below, so post-monomorphization - let y = >::F; //~ ERROR erroneous constant + let y = >::F; //~ constant } diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr index 2bf753c2ba3df..fc4b18056da5b 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -4,12 +4,24 @@ error[E0080]: evaluation of `>:: LL | const F: u32 = 100 / U::X; | ^^^^^^^^^^ attempt to divide `100_u32` by zero -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/assoc_const_2.rs:27:13 | LL | let y = >::F; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/assoc_const_2.rs:27:13 + | +LL | let y = >::F; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/assoc_const_2.rs:27:13 + | +LL | let y = >::F; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.rs b/src/test/ui/consts/uninhabited-const-issue-61744.rs index a07c39882774e..ca6449cce30d5 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.rs +++ b/src/test/ui/consts/uninhabited-const-issue-61744.rs @@ -15,5 +15,5 @@ trait Const { impl Const for T {} pub fn main() -> () { - dbg!(i32::CONSTANT); //~ ERROR erroneous constant used + dbg!(i32::CONSTANT); //~ constant } diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index 9c7cc88613ebe..8b39f390bb47e 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -140,12 +140,24 @@ LL | fake_type() LL | const CONSTANT: i32 = unsafe { fake_type() }; | ----------- inside `::CONSTANT` at $DIR/uninhabited-const-issue-61744.rs:12:36 -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/uninhabited-const-issue-61744.rs:18:10 | LL | dbg!(i32::CONSTANT); - | ^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/uninhabited-const-issue-61744.rs:18:10 + | +LL | dbg!(i32::CONSTANT); + | ^^^^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/uninhabited-const-issue-61744.rs:18:10 + | +LL | dbg!(i32::CONSTANT); + | ^^^^^^^^^^^^^ + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index 4856418ed6002..aca5242b29689 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -1,8 +1,8 @@ error[E0391]: cycle detected when const-evaluating + checking `FOO` - --> $DIR/issue-17252.rs:1:1 + --> $DIR/issue-17252.rs:1:20 | LL | const FOO: usize = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = note: ...which immediately requires const-evaluating + checking `FOO` again note: cycle used when const-evaluating + checking `main::{constant#0}` diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index 074939f68a889..c6cafe575e51b 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -1,14 +1,14 @@ error[E0391]: cycle detected when const-evaluating + checking `A` - --> $DIR/issue-23302-3.rs:1:1 + --> $DIR/issue-23302-3.rs:1:16 | LL | const A: i32 = B; - | ^^^^^^^^^^^^^^^^^ + | ^ | note: ...which requires const-evaluating + checking `B`... - --> $DIR/issue-23302-3.rs:3:1 + --> $DIR/issue-23302-3.rs:3:16 | LL | const B: i32 = A; - | ^^^^^^^^^^^^^^^^^ + | ^ = note: ...which again requires const-evaluating + checking `A`, completing the cycle note: cycle used when simplifying constant for the type system `A` --> $DIR/issue-23302-3.rs:1:1 diff --git a/src/test/ui/issues/issue-41394.rs b/src/test/ui/issues/issue-41394.rs index 64873ac35a002..07cad8796e169 100644 --- a/src/test/ui/issues/issue-41394.rs +++ b/src/test/ui/issues/issue-41394.rs @@ -5,7 +5,7 @@ enum Foo { enum Bar { A = Foo::A as isize - //~^ ERROR evaluation of constant value failed + //~^ const } fn main() {} diff --git a/src/test/ui/issues/issue-41394.stderr b/src/test/ui/issues/issue-41394.stderr index 47a24547d4533..1b5c64628a155 100644 --- a/src/test/ui/issues/issue-41394.stderr +++ b/src/test/ui/issues/issue-41394.stderr @@ -6,13 +6,12 @@ LL | A = "" + 1 | | | &str -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-41394.rs:7:9 | LL | A = Foo::A as isize - | ^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0369. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs index 6851b67cb3b3a..e98affc5cc299 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs @@ -19,5 +19,5 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` fn main() { let _ = [0; B::VALUE]; - //~^ ERROR evaluation of constant value failed + //~^ constant } diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr index 2c2cd5c5244cf..ba385d887fb39 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr @@ -13,13 +13,13 @@ LL | type MyA: TraitA; LL | impl TraitB for B { | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 | LL | let _ = [0; B::VALUE]; - | ^^^^^^^^ referenced constant has errors + | ^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0046, E0080, E0437. +Some errors have detailed explanations: E0046, E0437. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr index ee6aab748e445..e35f9f14c7ecc 100644 --- a/src/test/ui/limits/issue-55878.stderr +++ b/src/test/ui/limits/issue-55878.stderr @@ -9,14 +9,30 @@ LL | intrinsics::size_of::() LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ---------------------------------------------- inside `main` at $DIR/issue-55878.rs:7:26 -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/issue-55878.rs:7:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +note: erroneous constant used + --> $DIR/issue-55878.rs:7:26 + | +LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant used + --> $DIR/issue-55878.rs:7:26 + | +LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/macros/recovery-allowed.rs b/src/test/ui/macros/recovery-allowed.rs new file mode 100644 index 0000000000000..ebf65f1cc01e6 --- /dev/null +++ b/src/test/ui/macros/recovery-allowed.rs @@ -0,0 +1,8 @@ +macro_rules! please_recover { + ($a:expr) => {}; +} + +please_recover! { not 1 } +//~^ ERROR unexpected `1` after identifier + +fn main() {} diff --git a/src/test/ui/macros/recovery-allowed.stderr b/src/test/ui/macros/recovery-allowed.stderr new file mode 100644 index 0000000000000..ec036e8b1e24b --- /dev/null +++ b/src/test/ui/macros/recovery-allowed.stderr @@ -0,0 +1,10 @@ +error: unexpected `1` after identifier + --> $DIR/recovery-allowed.rs:5:23 + | +LL | please_recover! { not 1 } + | ----^ + | | + | help: use `!` to perform bitwise not + +error: aborting due to previous error + diff --git a/src/test/ui/macros/recovery-forbidden.rs b/src/test/ui/macros/recovery-forbidden.rs new file mode 100644 index 0000000000000..5dd2619330c4a --- /dev/null +++ b/src/test/ui/macros/recovery-forbidden.rs @@ -0,0 +1,13 @@ +// check-pass + +macro_rules! dont_recover_here { + ($e:expr) => { + compile_error!("Must not recover to single !1 expr"); + }; + + (not $a:literal) => {}; +} + +dont_recover_here! { not 1 } + +fn main() {} diff --git a/src/test/ui/manually_drop_attr/feature-gate-manually_drop_attr.rs b/src/test/ui/manually_drop_attr/feature-gate-manually_drop_attr.rs new file mode 100644 index 0000000000000..835921ac6af9b --- /dev/null +++ b/src/test/ui/manually_drop_attr/feature-gate-manually_drop_attr.rs @@ -0,0 +1,5 @@ +#[manually_drop] +//~^ ERROR the `#[manually_drop]` attribute is an experimental feature +struct Foo {} + +fn main() {} diff --git a/src/test/ui/manually_drop_attr/feature-gate-manually_drop_attr.stderr b/src/test/ui/manually_drop_attr/feature-gate-manually_drop_attr.stderr new file mode 100644 index 0000000000000..e105179cb2743 --- /dev/null +++ b/src/test/ui/manually_drop_attr/feature-gate-manually_drop_attr.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[manually_drop]` attribute is an experimental feature + --> $DIR/feature-gate-manually_drop_attr.rs:1:1 + | +LL | #[manually_drop] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #100344 for more information + = help: add `#![feature(manually_drop_attr)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/manually_drop_attr/manually_drop-bad-item.rs b/src/test/ui/manually_drop_attr/manually_drop-bad-item.rs new file mode 100644 index 0000000000000..502fc2862cf0e --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-bad-item.rs @@ -0,0 +1,10 @@ +#![feature(manually_drop_attr)] +#![forbid(unused_attributes)] +#![manually_drop] +//~^ ERROR attribute should be applied to a struct or enum + +#[manually_drop] +//~^ ERROR attribute should be applied to a struct or enum +fn foo() {} + +fn main() {} diff --git a/src/test/ui/manually_drop_attr/manually_drop-bad-item.stderr b/src/test/ui/manually_drop_attr/manually_drop-bad-item.stderr new file mode 100644 index 0000000000000..ed4085934f5d5 --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-bad-item.stderr @@ -0,0 +1,23 @@ +error: attribute should be applied to a struct or enum + --> $DIR/manually_drop-bad-item.rs:6:1 + | +LL | #[manually_drop] + | ^^^^^^^^^^^^^^^^ +LL | +LL | fn foo() {} + | ----------- not a struct or enum + | +note: the lint level is defined here + --> $DIR/manually_drop-bad-item.rs:2:11 + | +LL | #![forbid(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: attribute should be applied to a struct or enum + --> $DIR/manually_drop-bad-item.rs:3:1 + | +LL | #![manually_drop] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/manually_drop_attr/manually_drop-destructor.rs b/src/test/ui/manually_drop_attr/manually_drop-destructor.rs new file mode 100644 index 0000000000000..a9138ebb70224 --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-destructor.rs @@ -0,0 +1,83 @@ +//! A test of `#[manually_drop]` on a type that *does* have a `Drop` impl. +//! +//! The mirror image of `manually_drop-nodestructor.rs` +#![feature(manually_drop_attr)] +// run-pass +extern crate core; +use core::cell::Cell; + +struct DropCounter<'a>(&'a Cell); +impl<'a> Drop for DropCounter<'a> { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } +} + +#[manually_drop] +struct ManuallyDropped<'a> { + field_1: DropCounter<'a>, + field_2: DropCounter<'a>, +} + +impl<'a> Drop for ManuallyDropped<'a> { + fn drop(&mut self) { + // just do a LITTLE dropping. + unsafe { + core::ptr::drop_in_place(&mut self.field_1) + } + } +} + +#[manually_drop] +enum ManuallyDroppedEnum<'a> { + _A, + B(DropCounter<'a>, DropCounter<'a>), +} + +impl<'a> Drop for ManuallyDroppedEnum<'a> { + fn drop(&mut self) { + // just do a LITTLE dropping. + if let ManuallyDroppedEnum::B(a, _) = self { + unsafe { + core::ptr::drop_in_place(a); + } + } + } +} + +/// Dropping a `#[manually_drop]` struct does not implicitly drop its fields. +/// +/// (Though it does run `Drop`, which can choose to drop them explicitly.) +fn test_destruction() { + let counter = Cell::new(0); + core::mem::drop(ManuallyDropped { + field_1: DropCounter(&counter), + field_2: DropCounter(&counter), + }); + // We only run the drop specifically requested in the Drop impl. + assert_eq!(counter.get(), 1); + assert!(core::mem::needs_drop::()); + + core::mem::drop(ManuallyDroppedEnum::B(DropCounter(&counter), DropCounter(&counter))); + assert_eq!(counter.get(), 2); + assert!(core::mem::needs_drop::()); + +} + +/// Assignment does still drop the fields. +fn test_assignment() { + let counter = Cell::new(0); + let mut manually_dropped = ManuallyDropped { + field_1: DropCounter(&counter), + field_2: DropCounter(&counter), + }; + assert_eq!(counter.get(), 0); + manually_dropped.field_1 = DropCounter(&counter); + manually_dropped.field_2 = DropCounter(&counter); + assert_eq!(counter.get(), 2); +} + +fn main() { + test_destruction(); + test_assignment(); +} diff --git a/src/test/ui/manually_drop_attr/manually_drop-dropck.rs b/src/test/ui/manually_drop_attr/manually_drop-dropck.rs new file mode 100644 index 0000000000000..95a108735564c --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-dropck.rs @@ -0,0 +1,38 @@ +//! The drop checker only complains about a `#[manually_drop]` type if it _itself_ defines `Drop`. + +// FIXME: this does test dropck, does it also test needs_drop? + +#![feature(manually_drop_attr)] + + +// For example, this is absolutely fine: + +#[manually_drop] +struct ManuallyDrop(T); + +fn drop_out_of_order_ok(x: T) { + let mut manually_dropped = ManuallyDrop(None); + // x will be dropped before manually_dropped. + let x = x; + // ... but this is still fine, because it doesn't have logic on Drop. + manually_dropped.0 = Some(&x); +} + +// ... but this is not: + +#[manually_drop] +struct ManuallyDropWithDestructor(T); +impl Drop for ManuallyDropWithDestructor { + fn drop(&mut self) { + // maybe we read self.0 here! + } +} + +fn drop_out_of_order_not_ok(x: T) { + let mut manually_dropped_bad = ManuallyDropWithDestructor(None); + let x = x; + manually_dropped_bad.0 = Some(&x); + //~^ ERROR `x` does not live long enough +} + +fn main() {} diff --git a/src/test/ui/manually_drop_attr/manually_drop-dropck.stderr b/src/test/ui/manually_drop_attr/manually_drop-dropck.stderr new file mode 100644 index 0000000000000..39bd679cf207f --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-dropck.stderr @@ -0,0 +1,17 @@ +error[E0597]: `x` does not live long enough + --> $DIR/manually_drop-dropck.rs:34:35 + | +LL | manually_dropped_bad.0 = Some(&x); + | ^^ borrowed value does not live long enough +LL | +LL | } + | - + | | + | `x` dropped here while still borrowed + | borrow might be used here, when `manually_dropped_bad` is dropped and runs the `Drop` code for type `ManuallyDropWithDestructor` + | + = note: values in a scope are dropped in the opposite order they are defined + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/manually_drop_attr/manually_drop-in-union.rs b/src/test/ui/manually_drop_attr/manually_drop-in-union.rs new file mode 100644 index 0000000000000..cd48d89c6ec37 --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-in-union.rs @@ -0,0 +1,18 @@ +//! A `#[manually_drop]` type with a destructor is still not allowed inside a union! +#![feature(manually_drop_attr)] + +extern crate core; + +#[manually_drop] +struct ManuallyDropHasDrop; + +impl Drop for ManuallyDropHasDrop { + fn drop(&mut self) {} +} + +union MyUnion { + x: ManuallyDropHasDrop, + //~^ ERROR: unions cannot contain fields that may need dropping +} + +fn main() {} diff --git a/src/test/ui/manually_drop_attr/manually_drop-in-union.stderr b/src/test/ui/manually_drop_attr/manually_drop-in-union.stderr new file mode 100644 index 0000000000000..7c2ac50dee17e --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-in-union.stderr @@ -0,0 +1,15 @@ +error[E0740]: unions cannot contain fields that may need dropping + --> $DIR/manually_drop-in-union.rs:14:5 + | +LL | x: ManuallyDropHasDrop, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type +help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped + | +LL | x: std::mem::ManuallyDrop, + | +++++++++++++++++++++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0740`. diff --git a/src/test/ui/manually_drop_attr/manually_drop-nodestructor.rs b/src/test/ui/manually_drop_attr/manually_drop-nodestructor.rs new file mode 100644 index 0000000000000..da0597f398455 --- /dev/null +++ b/src/test/ui/manually_drop_attr/manually_drop-nodestructor.rs @@ -0,0 +1,60 @@ +//! A test of `#[manually_drop]` on a type that *doesn't* have a `Drop` impl. +//! +//! The mirror image of `manually_drop-destructor.rs` + +#![feature(manually_drop_attr)] +// run-pass +extern crate core; +use core::cell::Cell; + +struct DropCounter<'a>(&'a Cell); +impl<'a> Drop for DropCounter<'a> { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } +} + +#[manually_drop] +struct ManuallyDropped<'a> { + field_1: DropCounter<'a>, + field_2: DropCounter<'a>, +} + +#[manually_drop] +enum ManuallyDroppedEnum<'a> { + _A, + B(DropCounter<'a>, DropCounter<'a>), +} + +/// Dropping a `#[manually_drop]` type does not implicitly drop its fields. +fn test_destruction() { + let counter = Cell::new(0); + core::mem::drop(ManuallyDropped { + field_1: DropCounter(&counter), + field_2: DropCounter(&counter), + }); + assert_eq!(counter.get(), 0); + assert!(!core::mem::needs_drop::()); + + core::mem::drop(ManuallyDroppedEnum::B(DropCounter(&counter), DropCounter(&counter))); + assert_eq!(counter.get(), 0); + assert!(!core::mem::needs_drop::()); +} + +/// Assignment does still drop the fields. +fn test_assignment() { + let counter = Cell::new(0); + let mut manually_dropped = ManuallyDropped { + field_1: DropCounter(&counter), + field_2: DropCounter(&counter), + }; + assert_eq!(counter.get(), 0); + manually_dropped.field_1 = DropCounter(&counter); + manually_dropped.field_2 = DropCounter(&counter); + assert_eq!(counter.get(), 2); +} + +fn main() { + test_destruction(); + test_assignment(); +} diff --git a/src/test/ui/resolve/issue-50599.rs b/src/test/ui/resolve/issue-50599.rs index 78a20cf8ebb05..72238a59198a7 100644 --- a/src/test/ui/resolve/issue-50599.rs +++ b/src/test/ui/resolve/issue-50599.rs @@ -2,5 +2,5 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; - //~^ ERROR evaluation of constant value failed + //~^ constant } diff --git a/src/test/ui/resolve/issue-50599.stderr b/src/test/ui/resolve/issue-50599.stderr index 910deddd8bcdc..b07482c83ccc2 100644 --- a/src/test/ui/resolve/issue-50599.stderr +++ b/src/test/ui/resolve/issue-50599.stderr @@ -16,13 +16,12 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; LL + const M: usize = (f64::from(N) * LOG10_2) as usize; | -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/issue-50599.rs:4:29 | LL | let mut digits = [0u32; M]; - | ^ referenced constant has errors + | ^ -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0425. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index f37f093d9ede7..caf5bade5c75b 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -2,5 +2,5 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); - //~^ERROR evaluation of constant value failed + //~^ constant } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 02f267c6c8d73..af16a6e8f8418 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -6,13 +6,12 @@ LL | const l: usize = v.count(); | | | help: consider using `let` instead of `const`: `let l` -error[E0080]: evaluation of constant value failed +note: erroneous constant used --> $DIR/type-dependent-def-issue-49241.rs:4:18 | LL | let s: [u32; l] = v.into_iter().collect(); - | ^ referenced constant has errors + | ^ -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0435. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/union/union-deref.mirunsafeck.stderr b/src/test/ui/union/union-deref.mirunsafeck.stderr index be5e60ab88a59..ce3571deb1c8b 100644 --- a/src/test/ui/union/union-deref.mirunsafeck.stderr +++ b/src/test/ui/union/union-deref.mirunsafeck.stderr @@ -1,4 +1,4 @@ -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:16:14 | LL | unsafe { u.f.0 = Vec::new() }; @@ -7,7 +7,7 @@ LL | unsafe { u.f.0 = Vec::new() }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:18:19 | LL | unsafe { &mut u.f.0 }; @@ -16,7 +16,7 @@ LL | unsafe { &mut u.f.0 }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:20:14 | LL | unsafe { u.f.0.push(0) }; @@ -25,7 +25,7 @@ LL | unsafe { u.f.0.push(0) }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:24:14 | LL | unsafe { u.f.0.0 = Vec::new() }; @@ -34,7 +34,7 @@ LL | unsafe { u.f.0.0 = Vec::new() }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:26:19 | LL | unsafe { &mut u.f.0.0 }; @@ -43,7 +43,7 @@ LL | unsafe { &mut u.f.0.0 }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:28:14 | LL | unsafe { u.f.0.0.push(0) }; diff --git a/src/test/ui/union/union-deref.rs b/src/test/ui/union/union-deref.rs index 5aa28d93f96ed..b8afc9793d921 100644 --- a/src/test/ui/union/union-deref.rs +++ b/src/test/ui/union/union-deref.rs @@ -13,17 +13,17 @@ union U2 { x:(), f: (ManuallyDrop<(T,)>,) } fn main() { let mut u : U1> = U1 { x: () }; unsafe { (*u.f).0 = Vec::new() }; // explicit deref, this compiles - unsafe { u.f.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field + unsafe { u.f.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on manually dropped union field unsafe { &mut (*u.f).0 }; // explicit deref, this compiles - unsafe { &mut u.f.0 }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field + unsafe { &mut u.f.0 }; //~ERROR not automatically applying `DerefMut` on manually dropped union field unsafe { (*u.f).0.push(0) }; // explicit deref, this compiles - unsafe { u.f.0.push(0) }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field + unsafe { u.f.0.push(0) }; //~ERROR not automatically applying `DerefMut` on manually dropped union field let mut u : U2> = U2 { x: () }; unsafe { (*u.f.0).0 = Vec::new() }; // explicit deref, this compiles - unsafe { u.f.0.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field + unsafe { u.f.0.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on manually dropped union field unsafe { &mut (*u.f.0).0 }; // explicit deref, this compiles - unsafe { &mut u.f.0.0 }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field + unsafe { &mut u.f.0.0 }; //~ERROR not automatically applying `DerefMut` on manually dropped union field unsafe { (*u.f.0).0.push(0) }; // explicit deref, this compiles - unsafe { u.f.0.0.push(0) }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field + unsafe { u.f.0.0.push(0) }; //~ERROR not automatically applying `DerefMut` on manually dropped union field } diff --git a/src/test/ui/union/union-deref.thirunsafeck.stderr b/src/test/ui/union/union-deref.thirunsafeck.stderr index be5e60ab88a59..ce3571deb1c8b 100644 --- a/src/test/ui/union/union-deref.thirunsafeck.stderr +++ b/src/test/ui/union/union-deref.thirunsafeck.stderr @@ -1,4 +1,4 @@ -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:16:14 | LL | unsafe { u.f.0 = Vec::new() }; @@ -7,7 +7,7 @@ LL | unsafe { u.f.0 = Vec::new() }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:18:19 | LL | unsafe { &mut u.f.0 }; @@ -16,7 +16,7 @@ LL | unsafe { &mut u.f.0 }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:20:14 | LL | unsafe { u.f.0.push(0) }; @@ -25,7 +25,7 @@ LL | unsafe { u.f.0.push(0) }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:24:14 | LL | unsafe { u.f.0.0 = Vec::new() }; @@ -34,7 +34,7 @@ LL | unsafe { u.f.0.0 = Vec::new() }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:26:19 | LL | unsafe { &mut u.f.0.0 }; @@ -43,7 +43,7 @@ LL | unsafe { &mut u.f.0.0 }; = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor -error: not automatically applying `DerefMut` on `ManuallyDrop` union field +error: not automatically applying `DerefMut` on manually dropped union field --> $DIR/union-deref.rs:28:14 | LL | unsafe { u.f.0.0.push(0) }; diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index aedbe08e3e46e..ad20bb132325e 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -113,6 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { } if let ty::Adt(def, _) = arg_ty.kind() { + // FIXME: This is not correct with `#[manually_drop]`, as that is just like any other type. if def.is_manually_drop() { continue; } diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr index da5bc38b3b66c..d8b6e3f1262b7 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr @@ -4,11 +4,11 @@ error[E0080]: evaluation of `main::{constant#3}` failed LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 -error[E0080]: erroneous constant used +note: erroneous constant used --> $DIR/indexing_slicing_index.rs:31:5 | LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts. - | ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^^ error: indexing may panic --> $DIR/indexing_slicing_index.rs:22:5 @@ -65,6 +65,6 @@ error[E0080]: evaluation of constant value failed LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index ac5dcbf0f4f2f..8fbee9a352294 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -712,7 +712,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if tcx.is_foreign_item(def_id) { throw_unsup_format!("foreign thread-local statics are not supported"); } - let allocation = tcx.eval_static_initializer(def_id)?; + // We don't give a span -- statics don't need that, they cannot be generic or associated. + let allocation = this.ctfe_query(None, |tcx| tcx.eval_static_initializer(def_id))?; let mut allocation = allocation.inner().clone(); // This allocation will be deallocated when the thread dies, so it is not in read-only memory. allocation.mutability = Mutability::Mut; diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 0cfa3812e400d..7658cea10f9f8 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -146,7 +146,9 @@ fn prune_stacktrace<'tcx>( } } -/// Emit a custom diagnostic without going through the miri-engine machinery +/// Emit a custom diagnostic without going through the miri-engine machinery. +/// +/// Returns `Some` if this was regular program termination with a given exit code, `None` otherwise. pub fn report_error<'tcx, 'mir>( ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, e: InterpErrorInfo<'tcx>, @@ -155,106 +157,102 @@ pub fn report_error<'tcx, 'mir>( let mut msg = vec![]; - let (title, helps) = match &e.kind() { - MachineStop(info) => { - let info = info.downcast_ref::().expect("invalid MachineStop payload"); - use TerminationInfo::*; - let title = match info { - Exit(code) => return Some(*code), - Abort(_) => Some("abnormal termination"), - UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance => - Some("unsupported operation"), - StackedBorrowsUb { .. } => Some("Undefined Behavior"), - Deadlock => Some("deadlock"), - MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None, - }; - #[rustfmt::skip] - let helps = match info { - UnsupportedInIsolation(_) => - vec![ - (None, format!("pass the flag `-Zmiri-disable-isolation` to disable isolation;")), - (None, format!("or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning")), - ], - StackedBorrowsUb { help, history, .. } => { - let url = "https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md"; - msg.extend(help.clone()); - let mut helps = vec![ - (None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental")), - (None, format!("see {url} for further information")), - ]; - if let Some(TagHistory {created, invalidated, protected}) = history.clone() { - helps.push((Some(created.1), created.0)); - if let Some((msg, span)) = invalidated { - helps.push((Some(span), msg)); - } - if let Some((protector_msg, protector_span)) = protected { - helps.push((Some(protector_span), protector_msg)); - } + let (title, helps) = if let MachineStop(info) = e.kind() { + let info = info.downcast_ref::().expect("invalid MachineStop payload"); + use TerminationInfo::*; + let title = match info { + Exit(code) => return Some(*code), + Abort(_) => Some("abnormal termination"), + UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance => + Some("unsupported operation"), + StackedBorrowsUb { .. } => Some("Undefined Behavior"), + Deadlock => Some("deadlock"), + MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None, + }; + #[rustfmt::skip] + let helps = match info { + UnsupportedInIsolation(_) => + vec![ + (None, format!("pass the flag `-Zmiri-disable-isolation` to disable isolation;")), + (None, format!("or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning")), + ], + StackedBorrowsUb { help, history, .. } => { + let url = "https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md"; + msg.extend(help.clone()); + let mut helps = vec![ + (None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental")), + (None, format!("see {url} for further information")), + ]; + if let Some(TagHistory {created, invalidated, protected}) = history.clone() { + helps.push((Some(created.1), created.0)); + if let Some((msg, span)) = invalidated { + helps.push((Some(span), msg)); + } + if let Some((protector_msg, protector_span)) = protected { + helps.push((Some(protector_span), protector_msg)); } - helps } - MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } => - vec![ - (Some(*first), format!("it's first defined here, in crate `{first_crate}`")), - (Some(*second), format!("then it's defined here again, in crate `{second_crate}`")), - ], - SymbolShimClashing { link_name, span } => - vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))], - Int2PtrWithStrictProvenance => - vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))], - _ => vec![], - }; - (title, helps) - } - _ => { - #[rustfmt::skip] - let title = match e.kind() { - Unsupported(_) => - "unsupported operation", - UndefinedBehavior(_) => - "Undefined Behavior", - ResourceExhaustion(_) => - "resource exhaustion", - InvalidProgram( - InvalidProgramInfo::AlreadyReported(_) | - InvalidProgramInfo::Layout(..) | - InvalidProgramInfo::ReferencedConstant - ) => - "post-monomorphization error", - kind => - bug!("This error should be impossible in Miri: {kind:?}"), - }; - #[rustfmt::skip] - let helps = match e.kind() { - Unsupported( - UnsupportedOpInfo::ThreadLocalStatic(_) | - UnsupportedOpInfo::ReadExternStatic(_) | - UnsupportedOpInfo::PartialPointerOverwrite(_) | - UnsupportedOpInfo::PartialPointerCopy(_) | - UnsupportedOpInfo::ReadPointerAsBytes - ) => - panic!("Error should never be raised by Miri: {kind:?}", kind = e.kind()), - Unsupported( - UnsupportedOpInfo::Unsupported(_) - ) => - vec![(None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support"))], - UndefinedBehavior(UndefinedBehaviorInfo::AlignmentCheckFailed { .. }) - if ecx.machine.check_alignment == AlignmentCheck::Symbolic - => - vec![ - (None, format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior")), - (None, format!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives")), - ], - UndefinedBehavior(_) => - vec![ - (None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")), - (None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")), - ], - InvalidProgram(_) | ResourceExhaustion(_) | MachineStop(_) => - vec![], - }; - (Some(title), helps) - } + helps + } + MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } => + vec![ + (Some(*first), format!("it's first defined here, in crate `{first_crate}`")), + (Some(*second), format!("then it's defined here again, in crate `{second_crate}`")), + ], + SymbolShimClashing { link_name, span } => + vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))], + Int2PtrWithStrictProvenance => + vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))], + _ => vec![], + }; + (title, helps) + } else { + #[rustfmt::skip] + let title = match e.kind() { + UndefinedBehavior(_) => + "Undefined Behavior", + ResourceExhaustion(_) => + "resource exhaustion", + Unsupported( + // We list only the ones that can actually happen. + UnsupportedOpInfo::Unsupported(_) + ) => + "unsupported operation", + InvalidProgram( + // We list only the ones that can actually happen. + InvalidProgramInfo::AlreadyReported(_) | + InvalidProgramInfo::Layout(..) + ) => + "post-monomorphization error", + kind => + bug!("This error should be impossible in Miri: {kind:?}"), + }; + #[rustfmt::skip] + let helps = match e.kind() { + Unsupported(_) => + vec![(None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support"))], + UndefinedBehavior(UndefinedBehaviorInfo::AlignmentCheckFailed { .. }) + if ecx.machine.check_alignment == AlignmentCheck::Symbolic + => + vec![ + (None, format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior")), + (None, format!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives")), + ], + UndefinedBehavior(_) => + vec![ + (None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")), + (None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")), + ], + InvalidProgram( + InvalidProgramInfo::AlreadyReported(rustc_errors::ErrorGuaranteed { .. }) + ) => { + // This got already reported. No point in reporting it again. + return None; + } + _ => + vec![], + }; + (Some(title), helps) }; let stacktrace = ecx.generate_stacktrace(); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index f98727186c48d..1fdf3e52a8b65 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -117,7 +117,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_ref(); let instance = this.resolve_path(path); let cid = GlobalId { instance, promoted: None }; - let const_val = this.eval_to_allocation(cid)?; + // We don't give a span -- this isn't actually used directly by the program anyway. + let const_val = this.eval_global(cid, None)?; this.read_scalar(&const_val.into()) } diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 8028ce7535488..66df0d737c087 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -46,6 +46,7 @@ extern crate rustc_ast; extern crate rustc_middle; extern crate rustc_const_eval; extern crate rustc_data_structures; +extern crate rustc_errors; extern crate rustc_hir; extern crate rustc_index; extern crate rustc_session; diff --git a/src/tools/miri/tests/fail/erroneous_const.rs b/src/tools/miri/tests/fail/erroneous_const.rs index d14998ccba269..d37837c71931e 100644 --- a/src/tools/miri/tests/fail/erroneous_const.rs +++ b/src/tools/miri/tests/fail/erroneous_const.rs @@ -11,7 +11,7 @@ impl PrintName { fn no_codegen() { if false { - let _ = PrintName::::VOID; //~ERROR: post-monomorphization error + let _ = PrintName::::VOID; //~NOTE: constant } } fn main() { diff --git a/src/tools/miri/tests/fail/erroneous_const.stderr b/src/tools/miri/tests/fail/erroneous_const.stderr index 8138d69f4031e..c32ebf67a1167 100644 --- a/src/tools/miri/tests/fail/erroneous_const.stderr +++ b/src/tools/miri/tests/fail/erroneous_const.stderr @@ -6,21 +6,12 @@ LL | const VOID: ! = panic!(); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: post-monomorphization error: referenced constant has errors +note: erroneous constant used --> $DIR/erroneous_const.rs:LL:CC | LL | let _ = PrintName::::VOID; - | ^^^^^^^^^^^^^^^^^^^^ referenced constant has errors - | - = note: inside `no_codegen::` at $DIR/erroneous_const.rs:LL:CC -note: inside `main` at $DIR/erroneous_const.rs:LL:CC - --> $DIR/erroneous_const.rs:LL:CC - | -LL | no_codegen::(); - | ^^^^^^^^^^^^^^^^^^^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`.