diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 5add2cf09b7b8..2547e1a246588 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -2680,11 +2680,11 @@ rustc_queries! { /// Perform monomorphization-time checking on this item. /// This is used for lints/errors that can only be checked once the instance is fully /// monomorphized. - query check_mono_item(key: ty::Instance<'tcx>) { + query check_mono_item(key: ty::Instance<'tcx>) -> Result<(), ErrorGuaranteed> { desc { "monomorphization-time checking" } } - query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned>], &'tcx [Spanned>]), NormalizationErrorInMono> { + query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned>], &'tcx [Spanned>], Option), NormalizationErrorInMono> { desc { "collecting items used by `{}`", key.0 } cache_on_disk } diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 2dacf64f8cf85..e6dd3a4d04bb0 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -193,7 +193,7 @@ impl_erasable_for_types_with_no_type_params! { Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError>, Result<&'_ ty::List>, ty::util::AlwaysRequiresDrop>, Result<(&'_ Steal>, thir::ExprId), ErrorGuaranteed>, - Result<(&'_ [Spanned>], &'_ [Spanned>]), NormalizationErrorInMono>, + Result<(&'_ [Spanned>], &'_ [Spanned>], Option), NormalizationErrorInMono>, Result<(), ErrorGuaranteed>, Result>>, ErrorGuaranteed>, Result>, ErrorGuaranteed>, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 9ddd33678c341..cb59d4a6f3019 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -232,7 +232,7 @@ use rustc_middle::ty::{ use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; use rustc_session::config::{DebugInfo, EntryFnType}; -use rustc_span::{DUMMY_SP, Span, Spanned, dummy_spanned, respan}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Spanned, dummy_spanned, respan}; use tracing::{debug, instrument, trace}; use crate::errors::{ @@ -408,12 +408,13 @@ fn collect_items_rec<'tcx>( // source. If the cause is in another crate, the goal here is to quickly locate which mono // item in the current crate is ultimately responsible for causing the error. // - // To give at least _some_ context to the user: while collecting mono items, we check the - // error count. If it has changed, a PME occurred, and we trigger some diagnostics about the - // current step of mono items collection. - // - // FIXME: don't rely on global state, instead bubble up errors. Note: this is very hard to do. - let error_count = tcx.dcx().err_count(); + // To give at least _some_ context to the user: while collecting mono items, we track whether a + // post-monomorphization error was encountered while processing this item. Rather than reading + // the global error count (which is racy under the parallel front-end, since errors emitted on + // other threads would be miscounted), we bubble up an `ErrorGuaranteed` from the places that + // actually emit such errors (const-eval, the ABI checks, and a `deny`-level `large_assignments` + // lint) through `items_of_instance`. + let mut encountered_error: Option = None; // In `mentioned_items` we collect items that were mentioned in this MIR but possibly do not // need to be monomorphized. This is done to ensure that optimizing away function calls does not @@ -472,7 +473,8 @@ fn collect_items_rec<'tcx>( )); rustc_data_structures::stack::ensure_sufficient_stack(|| { - let Ok((used, mentioned)) = tcx.items_of_instance((instance, mode)) else { + let Ok((used, mentioned, used_error)) = tcx.items_of_instance((instance, mode)) + else { // Normalization errors here are usually due to trait solving overflow. // FIXME: I assume that there are few type errors at post-analysis stage, but not // entirely sure. @@ -488,6 +490,7 @@ fn collect_items_rec<'tcx>( def_path_str, }); }; + encountered_error = encountered_error.or(used_error); used_items.extend(used.into_iter().copied()); mentioned_items.extend(mentioned.into_iter().copied()); }); @@ -538,7 +541,7 @@ fn collect_items_rec<'tcx>( // Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the // mono item graph. - if tcx.dcx().err_count() > error_count + if encountered_error.is_some() && starting_item.node.is_generic_fn() && starting_item.node.is_user_defined() { @@ -686,6 +689,10 @@ struct MirUsedCollector<'a, 'tcx> { /// Note that this contains *not-monomorphized* items! used_mentioned_items: &'a mut UnordSet>, instance: Instance<'tcx>, + /// Set if collection encountered an already-reported post-monomorphization error (e.g. a + /// const-eval failure). Bubbled up so callers can emit the "while instantiating" note without + /// consulting the global error count. + encountered_error: Option, } impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { @@ -715,8 +722,9 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { "collection encountered polymorphic constant: {:?}", const_ ), - Err(err @ ErrorHandled::Reported(..)) => { + Err(err @ ErrorHandled::Reported(info, _span)) => { err.emit_note(self.tcx); + self.encountered_error = self.encountered_error.or(Some(info.into())); return None; } } @@ -1303,14 +1311,14 @@ fn collect_items_of_instance<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, mode: CollectionMode, -) -> Result<(MonoItems<'tcx>, MonoItems<'tcx>), NormalizationErrorInMono> { +) -> Result<(MonoItems<'tcx>, MonoItems<'tcx>, Option), NormalizationErrorInMono> { // This item is getting monomorphized, do mono-time checks. let body = tcx.instance_mir(instance.def); // Plenty of code paths later assume that everything can be normalized. So we have to check // normalization first. // We choose to emit the error outside to provide helpful diagnostics. check_normalization_error(tcx, instance, body)?; - tcx.ensure_ok().check_mono_item(instance); + let mono_check_error = tcx.check_mono_item(instance).err(); // Naively, in "used" collection mode, all functions get added to *both* `used_items` and // `mentioned_items`. Mentioned items processing will then notice that they have already been @@ -1331,6 +1339,7 @@ fn collect_items_of_instance<'tcx>( used_items: &mut used_items, used_mentioned_items: &mut used_mentioned_items, instance, + encountered_error: mono_check_error, }; if mode == CollectionMode::UsedItems { @@ -1361,22 +1370,24 @@ fn collect_items_of_instance<'tcx>( } } - Ok((used_items, mentioned_items)) + let encountered_error = collector.encountered_error; + Ok((used_items, mentioned_items, encountered_error)) } fn items_of_instance<'tcx>( tcx: TyCtxt<'tcx>, (instance, mode): (Instance<'tcx>, CollectionMode), ) -> Result< - (&'tcx [Spanned>], &'tcx [Spanned>]), + (&'tcx [Spanned>], &'tcx [Spanned>], Option), NormalizationErrorInMono, > { - let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode)?; + let (used_items, mentioned_items, encountered_error) = + collect_items_of_instance(tcx, instance, mode)?; let used_items = tcx.arena.alloc_from_iter(used_items); let mentioned_items = tcx.arena.alloc_from_iter(mentioned_items); - Ok((used_items, mentioned_items)) + Ok((used_items, mentioned_items, encountered_error)) } /// `item` must be already monomorphized. diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 10218523ca232..4c33dcc1aa155 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -5,7 +5,7 @@ use rustc_hir::{CRATE_HIR_ID, HirId}; use rustc_middle::mir::{self, Location, traversal}; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use rustc_target::callconv::{FnAbi, PassMode}; use crate::errors; @@ -57,7 +57,8 @@ fn do_check_simd_vector_abi<'tcx>( def_id: DefId, is_call: bool, loc: impl Fn() -> (Span, HirId), -) { +) -> Option { + let mut res = None; let codegen_attrs = tcx.codegen_fn_attrs(def_id); let have_feature = |feat: Symbol| { let target_feats = tcx.sess.unstable_target_features.contains(&feat); @@ -74,23 +75,25 @@ fn do_check_simd_vector_abi<'tcx>( Some((_, feature)) => feature, None => { let (span, _hir_id) = loc(); - tcx.dcx().emit_err(errors::AbiErrorUnsupportedVectorType { - span, - ty: arg_abi.layout.ty, - is_call, - }); + res = res.or(Some(tcx.dcx().emit_err( + errors::AbiErrorUnsupportedVectorType { + span, + ty: arg_abi.layout.ty, + is_call, + }, + ))); continue; } }; if !feature.is_empty() && !have_feature(Symbol::intern(feature)) { let (span, _hir_id) = loc(); - tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { + res = res.or(Some(tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { span, required_feature: feature, ty: arg_abi.layout.ty, is_call, is_scalable: false, - }); + }))); } } UsesVectorRegisters::ScalableVector => { @@ -101,13 +104,13 @@ fn do_check_simd_vector_abi<'tcx>( }; if !required_feature.is_empty() && !have_feature(Symbol::intern(required_feature)) { let (span, _) = loc(); - tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { + res = res.or(Some(tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { span, required_feature, ty: arg_abi.layout.ty, is_call, is_scalable: true, - }); + }))); } } UsesVectorRegisters::No => { @@ -118,13 +121,14 @@ fn do_check_simd_vector_abi<'tcx>( // The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed. if abi.conv == CanonAbi::X86(X86Call::Vectorcall) && !have_feature(sym::sse2) { let (span, _hir_id) = loc(); - tcx.dcx().emit_err(errors::AbiRequiredTargetFeature { + res = res.or(Some(tcx.dcx().emit_err(errors::AbiRequiredTargetFeature { span, required_feature: "sse2", abi: "vectorcall", is_call, - }); + }))); } + res } /// Emit an error when a non-rustic ABI has unsized parameters. @@ -136,42 +140,47 @@ fn do_check_unsized_params<'tcx>( fn_abi: &FnAbi<'tcx, Ty<'tcx>>, is_call: bool, loc: impl Fn() -> (Span, HirId), -) { +) -> Option { // Unsized parameters are allowed with the (unstable) "Rust" (and similar) ABIs. if fn_abi.conv.is_rustic_abi() { - return; + return None; } + let mut res = None; for arg_abi in fn_abi.args.iter() { if !arg_abi.layout.layout.is_sized() { let (span, _hir_id) = loc(); - tcx.dcx().emit_err(errors::AbiErrorUnsupportedUnsizedParameter { + res = res.or(Some(tcx.dcx().emit_err(errors::AbiErrorUnsupportedUnsizedParameter { span, ty: arg_abi.layout.ty, is_call, - }); + }))); } } + res } /// Checks the ABI of an Instance, emitting an error when: /// /// - a non-rustic ABI uses unsized parameters /// - the signature requires target features that are not enabled -fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { +fn check_instance_abi<'tcx>( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, +) -> Option { let typing_env = ty::TypingEnv::fully_monomorphized(); let ty = instance.ty(tcx, typing_env); if ty.is_fn() && ty.fn_sig(tcx).abi() == ExternAbi::Unadjusted { // We disable all checks for the unadjusted ABI to allow linking to arbitrary LLVM // intrinsics - return; + return None; } let Ok(abi) = tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) else { // An error will be reported during codegen if we cannot determine the ABI of this // function. tcx.dcx().delayed_bug("ABI computation failure should lead to compilation failure"); - return; + return None; }; // Unlike the call-site check, we do also check "Rust" ABI functions here. // This should never trigger, *except* if we start making use of vector registers @@ -186,8 +195,11 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { def_id.as_local().map(|did| tcx.local_def_id_to_hir_id(did)).unwrap_or(CRATE_HIR_ID), ) }; - do_check_unsized_params(tcx, abi, /*is_call*/ false, loc); - do_check_simd_vector_abi(tcx, abi, instance.def_id(), /*is_call*/ false, loc); + // Call both checks unconditionally for their diagnostic side effects before combining. + let unsized_res = do_check_unsized_params(tcx, abi, /*is_call*/ false, loc); + let simd_res = + do_check_simd_vector_abi(tcx, abi, instance.def_id(), /*is_call*/ false, loc); + unsized_res.or(simd_res) } /// Check the ABI at a call site, emitting an error when: @@ -199,14 +211,14 @@ fn check_call_site_abi<'tcx>( callee: Ty<'tcx>, caller: InstanceKind<'tcx>, loc: impl Fn() -> (Span, HirId) + Copy, -) { +) -> Option { let extern_abi = callee.fn_sig(tcx).abi(); if extern_abi.is_rustic_abi() || extern_abi == ExternAbi::Unadjusted { // We directly handle the soundness of Rust ABIs -- so let's skip the majority of // call sites to avoid a perf regression. // We disable all checks for the unadjusted ABI to allow linking to arbitrary LLVM // intrinsics - return; + return None; } let typing_env = ty::TypingEnv::fully_monomorphized(); let callee_abi = match *callee.kind() { @@ -216,7 +228,7 @@ fn check_call_site_abi<'tcx>( ty::FnDef(def_id, args) => { // Intrinsics are handled separately by the compiler. if tcx.intrinsic(def_id).is_some() { - return; + return None; } let instance = ty::Instance::expect_resolve(tcx, typing_env, def_id, args, DUMMY_SP); tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) @@ -228,13 +240,21 @@ fn check_call_site_abi<'tcx>( let Ok(callee_abi) = callee_abi else { // ABI failed to compute; this will not get through codegen. - return; + return None; }; - do_check_unsized_params(tcx, callee_abi, /*is_call*/ true, loc); - do_check_simd_vector_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, loc); + // Call both checks unconditionally for their diagnostic side effects before combining. + let unsized_res = do_check_unsized_params(tcx, callee_abi, /*is_call*/ true, loc); + let simd_res = + do_check_simd_vector_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, loc); + unsized_res.or(simd_res) } -fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &mir::Body<'tcx>) { +fn check_callees_abi<'tcx>( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + body: &mir::Body<'tcx>, +) -> Option { + let mut res = None; // Check all function call terminators. for (bb, _data) in traversal::mono_reachable(body, tcx, instance) { let terminator = body.basic_blocks[bb].terminator(); @@ -247,7 +267,7 @@ fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &m ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(callee_ty), ); - check_call_site_abi(tcx, callee_ty, body.source.instance, || { + res = res.or(check_call_site_abi(tcx, callee_ty, body.source.instance, || { let loc = Location { block: bb, statement_index: body.basic_blocks[bb].statements.len(), @@ -259,18 +279,21 @@ fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &m .lint_root(&body.source_scopes) .unwrap_or(CRATE_HIR_ID), ) - }); + })); } _ => {} } } + res } pub(crate) fn check_feature_dependent_abi<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &'tcx mir::Body<'tcx>, -) { - check_instance_abi(tcx, instance); - check_callees_abi(tcx, instance, body); +) -> Option { + // Call both checks unconditionally for their diagnostic side effects before combining. + let instance_res = check_instance_abi(tcx, instance); + let callees_res = check_callees_abi(tcx, instance, body); + instance_res.or(callees_res) } diff --git a/compiler/rustc_monomorphize/src/mono_checks/mod.rs b/compiler/rustc_monomorphize/src/mono_checks/mod.rs index 6569eeafec17d..d9be59c4abd2c 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/mod.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/mod.rs @@ -4,14 +4,25 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{Instance, TyCtxt}; +use rustc_span::ErrorGuaranteed; mod abi_check; mod move_check; -fn check_mono_item<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { +fn check_mono_item<'tcx>( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, +) -> Result<(), ErrorGuaranteed> { let body = tcx.instance_mir(instance.def); - abi_check::check_feature_dependent_abi(tcx, instance, body); - move_check::check_moves(tcx, instance, body); + // Run both checks unconditionally for their diagnostic side effects before combining. Each + // returns `Some` if it emitted a hard post-monomorphization error: `abi_check` for ABI errors, + // and `move_check` when `large_assignments` is escalated to `deny`/`forbid`. + let abi_res = abi_check::check_feature_dependent_abi(tcx, instance, body); + let move_res = move_check::check_moves(tcx, instance, body); + match abi_res.or(move_res) { + Some(guar) => Err(guar), + None => Ok(()), + } } pub(super) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index af03e2a0d2d66..5a3c577e0115a 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Location, traversal}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; -use rustc_span::{Span, Spanned, sym}; +use rustc_span::{ErrorGuaranteed, Span, Spanned, sym}; use tracing::{debug, trace}; use crate::errors::LargeAssignmentsLint; @@ -17,17 +17,23 @@ struct MoveCheckVisitor<'tcx> { body: &'tcx mir::Body<'tcx>, /// Spans for move size lints already emitted. Helps avoid duplicate lints. move_size_spans: Vec, + /// Set if the `large_assignments` lint was emitted at error level (`deny`/`forbid`). Bubbled up + /// so the post-monomorphization "while instantiating" note can be attached without consulting + /// the global error count. + encountered_error: Option, } pub(crate) fn check_moves<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &'tcx mir::Body<'tcx>, -) { - let mut visitor = MoveCheckVisitor { tcx, instance, body, move_size_spans: vec![] }; +) -> Option { + let mut visitor = + MoveCheckVisitor { tcx, instance, body, move_size_spans: vec![], encountered_error: None }; for (bb, data) in traversal::mono_reachable(body, tcx, instance) { visitor.visit_basic_block_data(bb, data) } + visitor.encountered_error } impl<'tcx> MirVisitor<'tcx> for MoveCheckVisitor<'tcx> { @@ -184,6 +190,14 @@ impl<'tcx> MoveCheckVisitor<'tcx> { }, ); + // When `large_assignments` is set to `deny`/`forbid` the lint above was emitted as a hard + // error. The lint emission API does not hand back an `ErrorGuaranteed`, so recover the proof + // token from the `DiagCtxt`. We gate on the effective level so we only attribute an error to + // this instantiation when our own lint is the one that escalated to an error. + if self.tcx.lint_level_spec_at_node(LARGE_ASSIGNMENTS, lint_root).level().is_error() { + self.encountered_error = self.encountered_error.or_else(|| self.tcx.dcx().has_errors()); + } + self.move_size_spans.push(reported_span); } } diff --git a/tests/ui/abi/simd-abi-checks-avx.rs b/tests/ui/abi/simd-abi-checks-avx.rs index c68ba2fb5f890..7432381d15b72 100644 --- a/tests/ui/abi/simd-abi-checks-avx.rs +++ b/tests/ui/abi/simd-abi-checks-avx.rs @@ -1,7 +1,7 @@ //@ only-x86_64 //@ build-fail //@ compile-flags: -C target-feature=-avx -//@ ignore-parallel-frontend post-monomorphization errors + #![feature(portable_simd)] #![feature(simd_ffi)] #![allow(improper_ctypes_definitions)] diff --git a/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs index dbe507e3cd137..6777bee050a16 100644 --- a/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs +++ b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ ignore-parallel-frontend post-monomorphization errors + // Regression test for #66975 #![warn(unconditional_panic)] #![feature(never_type)] diff --git a/tests/ui/consts/const-eval/issue-50814-2.rs b/tests/ui/consts/const-eval/issue-50814-2.rs index 34a200e2887b9..1b917a0916da3 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.rs +++ b/tests/ui/consts/const-eval/issue-50814-2.rs @@ -2,7 +2,7 @@ //@ revisions: normal mir-opt //@ [mir-opt]compile-flags: -Zmir-opt-level=4 //@ dont-require-annotations: NOTE -//@ ignore-parallel-frontend post-monomorphization errors + trait C { const BOO: usize; } diff --git a/tests/ui/consts/const-eval/issue-50814.rs b/tests/ui/consts/const-eval/issue-50814.rs index 3901a2c0c9316..011f065ad814b 100644 --- a/tests/ui/consts/const-eval/issue-50814.rs +++ b/tests/ui/consts/const-eval/issue-50814.rs @@ -1,6 +1,6 @@ //@ build-fail //@ dont-require-annotations: NOTE -//@ ignore-parallel-frontend post-monomorphization errors + trait Unsigned { const MAX: u8; } diff --git a/tests/ui/consts/mono-reachable-invalid-const.rs b/tests/ui/consts/mono-reachable-invalid-const.rs index 3d76e4a65a4e2..aba41dabe71f9 100644 --- a/tests/ui/consts/mono-reachable-invalid-const.rs +++ b/tests/ui/consts/mono-reachable-invalid-const.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ ignore-parallel-frontend post-monomorphization errors + struct Bar; impl Bar { diff --git a/tests/ui/consts/required-consts/collect-in-called-fn.rs b/tests/ui/consts/required-consts/collect-in-called-fn.rs index d07c0927a16a9..2045b8266c792 100644 --- a/tests/ui/consts/required-consts/collect-in-called-fn.rs +++ b/tests/ui/consts/required-consts/collect-in-called-fn.rs @@ -4,7 +4,7 @@ //@[opt] compile-flags: -O //! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is //! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-closure.rs b/tests/ui/consts/required-consts/collect-in-dead-closure.rs index 825336e9d3ef3..5f8b6bbb174c4 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-closure.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-closure.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.rs b/tests/ui/consts/required-consts/collect-in-dead-drop.rs index fa9b8730c11c9..f7293d162df7b 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-drop.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.rs b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.rs index a76481b673132..e6be9f56cb7a0 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.rs @@ -4,7 +4,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.rs b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.rs index 4fe05db34d78e..a86902af52677 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs index a6132ef1fe07e..4cdb27413540f 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs @@ -4,7 +4,7 @@ //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. #![feature(type_alias_impl_trait)] -//@ ignore-parallel-frontend post-monomorphization errors + mod m { struct Fail(T); impl Fail { diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn.rs b/tests/ui/consts/required-consts/collect-in-dead-fn.rs index f4627323249d4..0c4795801068d 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fn.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.rs b/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.rs index 8808a4e26f0cb..04544cb413984 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Late(T); impl Late { const FAIL: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-fnptr.rs b/tests/ui/consts/required-consts/collect-in-dead-fnptr.rs index 1a9b99f9868f6..4cdb50f4385a1 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fnptr.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fnptr.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-forget.rs b/tests/ui/consts/required-consts/collect-in-dead-forget.rs index bc717edbe73ee..7586004116c36 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-forget.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-forget.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This passes without optimizations, so it can (and should) also pass with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.rs b/tests/ui/consts/required-consts/collect-in-dead-move.rs index 05491136e8d5e..4e2d959db32c7 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-move.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-move.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-dead-vtable.rs b/tests/ui/consts/required-consts/collect-in-dead-vtable.rs index 1ca52064a3fdd..d4ad730837730 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-vtable.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-vtable.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! This fails without optimizations, so it should also fail with optimizations. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.rs b/tests/ui/consts/required-consts/collect-in-promoted-const.rs index 415f22fd05dda..c475720938697 100644 --- a/tests/ui/consts/required-consts/collect-in-promoted-const.rs +++ b/tests/ui/consts/required-consts/collect-in-promoted-const.rs @@ -3,7 +3,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they get promoted. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs b/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs index 2d63c620a0384..9309457e22a46 100644 --- a/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs @@ -2,7 +2,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they are unused. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR explicit panic diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.rs b/tests/ui/consts/required-consts/interpret-in-promoted.rs index cbb1a309006c5..b223e6d16aa12 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.rs +++ b/tests/ui/consts/required-consts/interpret-in-promoted.rs @@ -2,7 +2,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //@ dont-require-annotations: NOTE -//@ ignore-parallel-frontend post-monomorphization errors + //! Make sure we evaluate const fn calls even if they get promoted and their result ignored. const unsafe fn ub() { diff --git a/tests/ui/consts/required-consts/interpret-in-static.rs b/tests/ui/consts/required-consts/interpret-in-static.rs index edc7b1d01fd6c..19ad6be1c9fa7 100644 --- a/tests/ui/consts/required-consts/interpret-in-static.rs +++ b/tests/ui/consts/required-consts/interpret-in-static.rs @@ -2,7 +2,7 @@ //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they are unused. -//@ ignore-parallel-frontend post-monomorphization errors + struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR explicit panic diff --git a/tests/ui/inline-const/required-const.rs b/tests/ui/inline-const/required-const.rs index 437652532ec54..8f640e933d019 100644 --- a/tests/ui/inline-const/required-const.rs +++ b/tests/ui/inline-const/required-const.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags: -Zmir-opt-level=3 -//@ ignore-parallel-frontend post-monomorphization errors + fn foo() { if false { const { panic!() } //~ ERROR E0080 diff --git a/tests/ui/lint/large_assignments/copy_into_box_rc_arc.rs b/tests/ui/lint/large_assignments/copy_into_box_rc_arc.rs index a8e23c0246eeb..dfa0b8015d037 100644 --- a/tests/ui/lint/large_assignments/copy_into_box_rc_arc.rs +++ b/tests/ui/lint/large_assignments/copy_into_box_rc_arc.rs @@ -3,7 +3,7 @@ #![move_size_limit = "1000"] //@ build-fail //@ only-64bit -//@ ignore-parallel-frontend post-monomorphization errors + //@ edition:2018 //@ compile-flags: -Zmir-opt-level=1 diff --git a/tests/ui/lint/large_assignments/copy_into_fn.rs b/tests/ui/lint/large_assignments/copy_into_fn.rs index 8f8e7f0822bbc..5222e833bcc8f 100644 --- a/tests/ui/lint/large_assignments/copy_into_fn.rs +++ b/tests/ui/lint/large_assignments/copy_into_fn.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ ignore-parallel-frontend post-monomorphization errors + #![feature(large_assignments)] #![move_size_limit = "1000"] #![deny(large_assignments)] diff --git a/tests/ui/lint/large_assignments/inline_mir.rs b/tests/ui/lint/large_assignments/inline_mir.rs index 68c5de4902f34..d16aae6ab145b 100644 --- a/tests/ui/lint/large_assignments/inline_mir.rs +++ b/tests/ui/lint/large_assignments/inline_mir.rs @@ -13,7 +13,7 @@ //! ``` //! //! We want the diagnostics to point to the relevant user code. -//@ ignore-parallel-frontend post-monomorphization errors + //@ build-fail //@ compile-flags: -Zmir-opt-level=1 -Zinline-mir diff --git a/tests/ui/lint/large_assignments/large_future.rs b/tests/ui/lint/large_assignments/large_future.rs index 1be66f16313bb..28c358bdbf086 100644 --- a/tests/ui/lint/large_assignments/large_future.rs +++ b/tests/ui/lint/large_assignments/large_future.rs @@ -5,7 +5,7 @@ //@ only-64bit //@ revisions: attribute option //@ [option]compile-flags: -Zmove-size-limit=1000 -//@ ignore-parallel-frontend post-monomorphization errors + //@ edition:2018 //@ compile-flags: -Zmir-opt-level=0 diff --git a/tests/ui/lint/large_assignments/move_in_generic_fn.rs b/tests/ui/lint/large_assignments/move_in_generic_fn.rs new file mode 100644 index 0000000000000..019ac7a5974a5 --- /dev/null +++ b/tests/ui/lint/large_assignments/move_in_generic_fn.rs @@ -0,0 +1,19 @@ +//@ build-fail +// +// When `large_assignments` is escalated to a hard error inside a generic function, the error must +// be attributed to the instantiation that triggered it, producing a "while instantiating" note. +// This exercises the post-monomorphization error bubbling out of the move check. +#![feature(large_assignments)] +#![move_size_limit = "1000"] +#![deny(large_assignments)] +#![allow(unused)] + +struct Data([u8; 9999]); + +fn main() { + instantiate::(); +} + +fn instantiate() { + let data = Data([100; 9999]); //~ ERROR large_assignments +} diff --git a/tests/ui/lint/large_assignments/move_in_generic_fn.stderr b/tests/ui/lint/large_assignments/move_in_generic_fn.stderr new file mode 100644 index 0000000000000..707c8ec249c24 --- /dev/null +++ b/tests/ui/lint/large_assignments/move_in_generic_fn.stderr @@ -0,0 +1,21 @@ +error: moving 9999 bytes + --> $DIR/move_in_generic_fn.rs:18:16 + | +LL | let data = Data([100; 9999]); + | ^^^^^^^^^^^^^^^^^ value moved from here + | + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` +note: the lint level is defined here + --> $DIR/move_in_generic_fn.rs:8:9 + | +LL | #![deny(large_assignments)] + | ^^^^^^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn instantiate::` + --> $DIR/move_in_generic_fn.rs:14:5 + | +LL | instantiate::(); + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/large_assignments/move_into_fn.rs b/tests/ui/lint/large_assignments/move_into_fn.rs index 1e793a082e3ea..b3b2160ca36e1 100644 --- a/tests/ui/lint/large_assignments/move_into_fn.rs +++ b/tests/ui/lint/large_assignments/move_into_fn.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ ignore-parallel-frontend post-monomorphization errors + #![feature(large_assignments)] #![move_size_limit = "1000"] #![deny(large_assignments)] diff --git a/tests/ui/simd/const-err-trumps-simd-err.rs b/tests/ui/simd/const-err-trumps-simd-err.rs index 282d5dabf72fa..33f0abb06f3ea 100644 --- a/tests/ui/simd/const-err-trumps-simd-err.rs +++ b/tests/ui/simd/const-err-trumps-simd-err.rs @@ -1,6 +1,6 @@ //@build-fail //@ dont-require-annotations: NOTE -//@ ignore-parallel-frontend post-monomorphization errors + //! Make sure that monomorphization-time const errors from `static_assert` take priority over the //! error from simd_extract. Basically this checks that if a const fails to evaluate in some //! function, we don't bother codegen'ing the function. diff --git a/tests/ui/structs/default-field-values/post-mono.rs b/tests/ui/structs/default-field-values/post-mono.rs index 57092083ca102..68dfa391bb485 100644 --- a/tests/ui/structs/default-field-values/post-mono.rs +++ b/tests/ui/structs/default-field-values/post-mono.rs @@ -1,6 +1,6 @@ //@ build-fail //@ revisions: direct indirect -//@ ignore-parallel-frontend post-monomorphization errors + #![feature(default_field_values)] struct Z {