diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 6799514a4490d..12a8b8c6d7790 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -120,7 +120,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { fn in_return_place( &mut self, ccx: &'mir ConstCx<'mir, 'tcx>, - error_occured: Option, + tainted_by_errors: Option, ) -> ConstQualifs { // Find the `Return` terminator if one exists. // @@ -134,7 +134,9 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { .map(|(bb, _)| bb); let return_block = match return_block { - None => return qualifs::in_any_value_of_ty(ccx, ccx.body.return_ty(), error_occured), + None => { + return qualifs::in_any_value_of_ty(ccx, ccx.body.return_ty(), tainted_by_errors); + } Some(bb) => bb, }; @@ -166,7 +168,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { needs_non_const_drop: self.needs_non_const_drop(ccx, RETURN_PLACE, return_loc), has_mut_interior: self.has_mut_interior(ccx, RETURN_PLACE, return_loc), custom_eq, - error_occured, + tainted_by_errors, } } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 91610b15eb999..c3fa98b000f4a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -17,14 +17,14 @@ use super::ConstCx; pub fn in_any_value_of_ty<'tcx>( cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>, - error_occured: Option, + tainted_by_errors: Option, ) -> ConstQualifs { ConstQualifs { has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty), needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty), needs_non_const_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty), custom_eq: CustomEq::in_any_value_of_ty(cx, ty), - error_occured, + tainted_by_errors, } } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index ac282a5ecc82c..92d1f5bceefe4 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -974,6 +974,7 @@ pub fn promote_candidates<'tcx>( vec![], body.span, body.generator_kind(), + body.tainted_by_errors, ); let promoter = Promoter { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 33fb1e570b1c0..0688d7d2569f5 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -13,6 +13,7 @@ use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex}; +use rustc_errors::ErrorReported; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_hir::{self, GeneratorKind}; @@ -284,6 +285,8 @@ pub struct Body<'tcx> { predecessor_cache: PredecessorCache, is_cyclic: GraphIsCyclicCache, + + pub tainted_by_errors: Option, } impl<'tcx> Body<'tcx> { @@ -297,6 +300,7 @@ impl<'tcx> Body<'tcx> { var_debug_info: Vec>, span: Span, generator_kind: Option, + tainted_by_errors: Option, ) -> Self { // We need `arg_count` locals, and one for the return place. assert!( @@ -329,6 +333,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, predecessor_cache: PredecessorCache::new(), is_cyclic: GraphIsCyclicCache::new(), + tainted_by_errors, }; body.is_polymorphic = body.has_param_types_or_consts(); body @@ -356,6 +361,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, predecessor_cache: PredecessorCache::new(), is_cyclic: GraphIsCyclicCache::new(), + tainted_by_errors: None, }; body.is_polymorphic = body.has_param_types_or_consts(); body diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 5c22bfd09a396..6e2b060e7ddcf 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -228,7 +228,7 @@ pub struct ConstQualifs { pub needs_drop: bool, pub needs_non_const_drop: bool, pub custom_eq: bool, - pub error_occured: Option, + pub tainted_by_errors: Option, } /// After we borrow check a closure, we are left with various diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 1c5bc7860db2d..39efc006d9d0f 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -253,6 +253,7 @@ TrivialTypeFoldableAndLiftImpls! { crate::ty::UniverseIndex, crate::ty::Variance, ::rustc_span::Span, + ::rustc_errors::ErrorReported, } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 88d994e32fe0c..10807d4327643 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -104,8 +104,8 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ let span_with_body = span_with_body.unwrap_or_else(|| tcx.hir().span(id)); tcx.infer_ctxt().enter(|infcx| { - let body = if let Some(ErrorReported) = typeck_results.tainted_by_errors { - build::construct_error(&infcx, def, id, body_id, body_owner_kind) + let body = if let Some(error_reported) = typeck_results.tainted_by_errors { + build::construct_error(&infcx, def, id, body_id, body_owner_kind, error_reported) } else if body_owner_kind.is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) @@ -715,6 +715,7 @@ fn construct_error<'a, 'tcx>( hir_id: hir::HirId, body_id: hir::BodyId, body_owner_kind: hir::BodyOwnerKind, + err: ErrorReported, ) -> Body<'tcx> { let tcx = infcx.tcx; let span = tcx.hir().span(hir_id); @@ -769,6 +770,7 @@ fn construct_error<'a, 'tcx>( vec![], span, generator_kind, + Some(err), ); body.generator.as_mut().map(|gen| gen.yield_ty = Some(ty)); body @@ -857,6 +859,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info, self.fn_span, self.generator_kind, + self.typeck_results.tainted_by_errors, ) } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 98de64cd97c9c..0d314a109bac7 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -145,6 +145,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { Default::default(), body.span, body.generator_kind(), + body.tainted_by_errors, ); // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 991d10a8547ff..e7d5bab8fd9d4 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -252,8 +252,11 @@ fn mir_promoted<'tcx>( // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. // Also this means promotion can rely on all const checks having been done. - let _ = tcx.mir_const_qualif_opt_const_arg(def); + let const_qualifs = tcx.mir_const_qualif_opt_const_arg(def); let mut body = tcx.mir_const(def).steal(); + if let Some(error_reported) = const_qualifs.tainted_by_errors { + body.tainted_by_errors = Some(error_reported); + } let mut required_consts = Vec::new(); let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts); @@ -358,13 +361,7 @@ fn mir_drops_elaborated_and_const_checked<'tcx>( return tcx.mir_drops_elaborated_and_const_checked(def); } - // (Mir-)Borrowck uses `mir_promoted`, so we have to force it to - // execute before we can steal. - if let Some(param_did) = def.const_param_did { - tcx.ensure().mir_borrowck_const_arg((def.did, param_did)); - } else { - tcx.ensure().mir_borrowck(def.did); - } + let mir_borrowck = tcx.mir_borrowck_opt_const_arg(def); let is_fn_like = tcx.hir().get_by_def_id(def.did).fn_kind().is_some(); if is_fn_like { @@ -379,6 +376,9 @@ fn mir_drops_elaborated_and_const_checked<'tcx>( let (body, _) = tcx.mir_promoted(def); let mut body = body.steal(); + if let Some(error_reported) = mir_borrowck.tainted_by_errors { + body.tainted_by_errors = Some(error_reported); + } // IMPORTANT pm::run_passes(tcx, &mut body, &[&remove_false_edges::RemoveFalseEdges]); @@ -544,15 +544,13 @@ fn promoted_mir<'tcx>( return tcx.arena.alloc(IndexVec::new()); } - if let Some(param_did) = def.const_param_did { - tcx.ensure().mir_borrowck_const_arg((def.did, param_did)); - } else { - tcx.ensure().mir_borrowck(def.did); - } - let (_, promoted) = tcx.mir_promoted(def); - let mut promoted = promoted.steal(); + let tainted_by_errors = tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors; + let mut promoted = tcx.mir_promoted(def).1.steal(); for body in &mut promoted { + if let Some(error_reported) = tainted_by_errors { + body.tainted_by_errors = Some(error_reported); + } run_post_borrowck_cleanup_passes(tcx, body); } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 919171db39e31..a4927c467cfc3 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -235,6 +235,8 @@ fn new_body<'tcx>( vec![], span, None, + // FIXME(compiler-errors): is this correct? + None, ) }