diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 51a353c013241..5316649d0e28a 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1617,12 +1617,33 @@ pub struct WithOptConstParam { impl WithOptConstParam { /// Creates a new `WithOptConstParam` setting `const_param_did` to `None`. + #[inline(always)] pub fn unknown(did: T) -> WithOptConstParam { WithOptConstParam { did, const_param_did: None } } } impl WithOptConstParam { + /// Returns `Some((did, param_did))` if `def_id` is a const argument, + /// `None` otherwise. + #[inline(always)] + pub fn try_lookup(did: LocalDefId, tcx: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> { + tcx.opt_const_param_of(did).map(|param_did| (did, param_did)) + } + + /// In case `self` is unknown but `self.did` is a const argument, this returns + /// a `WithOptConstParam` with the correct `const_param_did`. + #[inline(always)] + pub fn try_upgrade(self, tcx: TyCtxt<'_>) -> Option> { + if self.const_param_did.is_none() { + if let const_param_did @ Some(_) = tcx.opt_const_param_of(self.did) { + return Some(WithOptConstParam { did: self.did, const_param_did }); + } + } + + None + } + pub fn to_global(self) -> WithOptConstParam { WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 1972b7149d569..76cc03fa60909 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -88,7 +88,13 @@ const DEREF_PROJECTION: &[PlaceElem<'_>; 1] = &[ProjectionElem::Deref]; pub fn provide(providers: &mut Providers) { *providers = Providers { - mir_borrowck: |tcx, did| mir_borrowck(tcx, ty::WithOptConstParam::unknown(did)), + mir_borrowck: |tcx, did| { + if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) { + tcx.mir_borrowck_const_arg(def) + } else { + mir_borrowck(tcx, ty::WithOptConstParam::unknown(did)) + } + }, mir_borrowck_const_arg: |tcx, (did, param_did)| { mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) }, @@ -100,12 +106,6 @@ fn mir_borrowck<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> &'tcx BorrowCheckResult<'tcx> { - if def.const_param_did.is_none() { - if let Some(param_did) = tcx.opt_const_param_of(def.did) { - return tcx.mir_borrowck_const_arg((def.did, param_did)); - } - } - let (input_body, promoted) = tcx.mir_validated(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 81d7ac0892622..9c06e173bcd57 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -439,7 +439,11 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { unsafety_check_result: |tcx, def_id| { - unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id)) + if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { + tcx.unsafety_check_result_for_const_arg(def) + } else { + unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id)) + } }, unsafety_check_result_for_const_arg: |tcx, (did, param_did)| { unsafety_check_result( @@ -499,12 +503,6 @@ fn unsafety_check_result<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> &'tcx UnsafetyCheckResult { - if def.const_param_did.is_none() { - if let Some(param_did) = tcx.opt_const_param_of(def.did) { - return tcx.unsafety_check_result_for_const_arg((def.did, param_did)); - } - } - debug!("unsafety_violations({:?})", def); // N.B., this borrow is valid because all the consumers of diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 51a9e76e762eb..283e4b289f286 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -48,8 +48,13 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { mir_keys, mir_const, - mir_const_qualif: |tcx, did| { - mir_const_qualif(tcx, ty::WithOptConstParam::unknown(did.expect_local())) + mir_const_qualif: |tcx, def_id| { + let def_id = def_id.expect_local(); + if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { + tcx.mir_const_qualif_const_arg(def) + } else { + mir_const_qualif(tcx, ty::WithOptConstParam::unknown(def_id)) + } }, mir_const_qualif_const_arg: |tcx, (did, param_did)| { mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) @@ -60,7 +65,12 @@ pub(crate) fn provide(providers: &mut Providers) { optimized_mir_of_const_arg, is_mir_available, promoted_mir: |tcx, def_id| { - promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id.expect_local())) + let def_id = def_id.expect_local(); + if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { + tcx.promoted_mir_of_const_arg(def) + } else { + promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id)) + } }, promoted_mir_of_const_arg: |tcx, (did, param_did)| { promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) @@ -221,12 +231,6 @@ pub fn run_passes( } fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> ConstQualifs { - if def.const_param_did.is_none() { - if let Some(param_did) = tcx.opt_const_param_of(def.did) { - return tcx.mir_const_qualif_const_arg((def.did, param_did)); - } - } - let const_kind = tcx.hir().body_const_context(def.did); // No need to const-check a non-const `fn`. @@ -266,10 +270,8 @@ fn mir_const<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> &'tcx Steal> { - if def.const_param_did.is_none() { - if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) { - return tcx.mir_const(ty::WithOptConstParam { const_param_did, ..def }); - } + if let Some(def) = def.try_upgrade(tcx) { + return tcx.mir_const(def); } // Unsafety check uses the raw mir, so make sure it is run. @@ -312,10 +314,8 @@ fn mir_validated( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> (&'tcx Steal>, &'tcx Steal>>) { - if def.const_param_did.is_none() { - if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) { - return tcx.mir_validated(ty::WithOptConstParam { const_param_did, ..def }); - } + if let Some(def) = def.try_upgrade(tcx) { + return tcx.mir_validated(def); } // Ensure that we compute the `mir_const_qualif` for constants at @@ -357,13 +357,8 @@ fn mir_drops_elaborated_and_const_checked<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> &'tcx Steal> { - if def.const_param_did.is_none() { - if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) { - return tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam { - const_param_did, - ..def - }); - } + if let Some(def) = def.try_upgrade(tcx) { + return tcx.mir_drops_elaborated_and_const_checked(def); } // (Mir-)Borrowck uses `mir_validated`, so we have to force it to @@ -490,8 +485,8 @@ fn run_optimization_passes<'tcx>( fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx Body<'tcx> { let did = did.expect_local(); - if let Some(param_did) = tcx.opt_const_param_of(did) { - tcx.optimized_mir_of_const_arg((did, param_did)) + if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) { + tcx.optimized_mir_of_const_arg(def) } else { tcx.arena.alloc(inner_optimized_mir(tcx, ty::WithOptConstParam::unknown(did))) } @@ -528,12 +523,6 @@ fn promoted_mir<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> &'tcx IndexVec> { - if def.const_param_did.is_none() { - if let Some(param_did) = tcx.opt_const_param_of(def.did) { - return tcx.promoted_mir_of_const_arg((def.did, param_did)); - } - } - if tcx.is_constructor(def.did.to_def_id()) { return tcx.arena.alloc(IndexVec::new()); } diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index eb47195c06278..1e677f3d2aba8 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -25,10 +25,8 @@ crate fn mir_built<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> &'tcx ty::steal::Steal> { - if def.const_param_did.is_none() { - if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) { - return tcx.mir_built(ty::WithOptConstParam { const_param_did, ..def }); - } + if let Some(def) = def.try_upgrade(tcx) { + return tcx.mir_built(def); } tcx.alloc_steal_mir(mir_build(tcx, def))