diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index b32fa2cda80129e2d59a2646e63af51eaea1476f..61d63f4623249c21886ee2e7e260c7c079168aee 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -59,7 +59,7 @@ CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, }; -use crate::ty::subst::SubstsRef; +use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 54f5103f736ec07875cb2174d5176415dbf0e1e8..86855cb0ef0c2c3e27be088b9b695c267b479c38 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -9,7 +9,7 @@ }; use crate::ty::query::queries; use crate::ty::query::QueryDescription; -use crate::ty::subst::SubstsRef; +use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; @@ -1114,9 +1114,9 @@ fn describe_as_module(def_id: DefId, tcx: TyCtxt<'_>) -> String { } /// Do not call this query directly: invoke `normalize_erasing_regions` instead. - query normalize_ty_after_erasing_regions( - goal: ParamEnvAnd<'tcx, Ty<'tcx>> - ) -> Ty<'tcx> { + query normalize_generic_arg_after_erasing_regions( + goal: ParamEnvAnd<'tcx, GenericArg<'tcx>> + ) -> GenericArg<'tcx> { desc { "normalizing `{:?}`", goal } } diff --git a/src/librustc/ty/normalize_erasing_regions.rs b/src/librustc/ty/normalize_erasing_regions.rs index cbaabd8e1f1373a2c4ae788a2ad36703ece93239..e49bf6f8e67dcbe069c97d97a86a7e405ebe8f03 100644 --- a/src/librustc/ty/normalize_erasing_regions.rs +++ b/src/librustc/ty/normalize_erasing_regions.rs @@ -4,8 +4,8 @@ //! //! The methods in this file use a `TypeFolder` to recursively process //! contents, invoking the underlying -//! `normalize_ty_after_erasing_regions` query for each type found -//! within. (This underlying query is what is cached.) +//! `normalize_generic_arg_after_erasing_regions` query for each type +//! or constant found within. (This underlying query is what is cached.) use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::subst::{Subst, SubstsRef}; @@ -94,6 +94,14 @@ fn tcx(&self) -> TyCtxt<'tcx> { } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.tcx.normalize_ty_after_erasing_regions(self.param_env.and(ty)) + self.tcx + .normalize_generic_arg_after_erasing_regions(self.param_env.and(ty.into())) + .expect_ty() + } + + fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + self.tcx + .normalize_generic_arg_after_erasing_regions(self.param_env.and(c.into())) + .expect_const() } } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 6073d3a545f6db9c7b6dbb12186e188518037a06..6be1f04efca2b5366a58cfc3de30e51447cebae0 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -5,7 +5,7 @@ use crate::traits; use crate::ty::fast_reject::SimplifiedType; use crate::ty::query::caches::DefaultCacheSelector; -use crate::ty::subst::SubstsRef; +use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_span::symbol::Symbol; @@ -194,6 +194,17 @@ fn default_span(&self, tcx: TyCtxt<'_>) -> Span { } } +impl<'tcx> Key for GenericArg<'tcx> { + type CacheSelector = DefaultCacheSelector; + + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for &'tcx ty::Const<'tcx> { type CacheSelector = DefaultCacheSelector; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 32ba13b1dbe9a5cfe2740383518400befde1ad28..1094eb49403463df6842377b5a05cb344423b173 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -31,7 +31,7 @@ use crate::traits::Clauses; use crate::traits::{self, Vtable}; use crate::ty::steal::Steal; -use crate::ty::subst::SubstsRef; +use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use crate::util::common::ErrorReported; diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index a3acc14856e1febbb4b168dfe7e0877d9d4690dc..0f4485a705046dff5d33017a6fd09b8edb99d338 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -128,6 +128,14 @@ pub fn expect_ty(self) -> Ty<'tcx> { _ => bug!("expected a type, but found another kind"), } } + + /// Unpack the `GenericArg` as a const when it is known certainly to be a const. + pub fn expect_const(self) -> &'tcx ty::Const<'tcx> { + match self.unpack() { + GenericArgKind::Const(c) => c, + _ => bug!("expected a const, but found another kind"), + } + } } impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 80f59aff69137a09d365b84d8dd8090cff769c1c..b3d75143c56392bf633d50f7cb2d0d3d44721579 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -150,7 +150,7 @@ pub struct PerfStats { /// Total number of values canonicalized queries constructed. pub queries_canonicalized: AtomicUsize, /// Number of times this query is invoked. - pub normalize_ty_after_erasing_regions: AtomicUsize, + pub normalize_generic_arg_after_erasing_regions: AtomicUsize, /// Number of times this query is invoked. pub normalize_projection_ty: AtomicUsize, } @@ -707,8 +707,8 @@ pub fn print_perf_stats(&self) { self.perf_stats.queries_canonicalized.load(Ordering::Relaxed) ); println!( - "normalize_ty_after_erasing_regions: {}", - self.perf_stats.normalize_ty_after_erasing_regions.load(Ordering::Relaxed) + "normalize_generic_arg_after_erasing_regions: {}", + self.perf_stats.normalize_generic_arg_after_erasing_regions.load(Ordering::Relaxed) ); println!( "normalize_projection_ty: {}", @@ -1080,7 +1080,7 @@ fn build_session_( symbol_hash_time: Lock::new(Duration::from_secs(0)), decode_def_path_tables_time: Lock::new(Duration::from_secs(0)), queries_canonicalized: AtomicUsize::new(0), - normalize_ty_after_erasing_regions: AtomicUsize::new(0), + normalize_generic_arg_after_erasing_regions: AtomicUsize::new(0), normalize_projection_ty: AtomicUsize::new(0), }, code_stats: Default::default(), diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs index c2fb237a05b5476783e59a5222aac5b728ceeadb..065cf38eb249075a3c9ac3b2407c6dbcc5d5aaa0 100644 --- a/src/librustc_traits/normalize_erasing_regions.rs +++ b/src/librustc_traits/normalize_erasing_regions.rs @@ -1,23 +1,24 @@ use rustc::traits::query::NoSolution; use rustc::ty::query::Providers; -use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; +use rustc::ty::subst::GenericArg; +use rustc::ty::{self, ParamEnvAnd, TyCtxt}; use rustc_infer::infer::TyCtxtInferExt; use rustc_trait_selection::traits::query::normalize::AtExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; use std::sync::atomic::Ordering; crate fn provide(p: &mut Providers<'_>) { - *p = Providers { normalize_ty_after_erasing_regions, ..*p }; + *p = Providers { normalize_generic_arg_after_erasing_regions, ..*p }; } -fn normalize_ty_after_erasing_regions<'tcx>( +fn normalize_generic_arg_after_erasing_regions<'tcx>( tcx: TyCtxt<'tcx>, - goal: ParamEnvAnd<'tcx, Ty<'tcx>>, -) -> Ty<'tcx> { - debug!("normalize_ty_after_erasing_regions(goal={:#?})", goal); + goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>, +) -> GenericArg<'tcx> { + debug!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal); let ParamEnvAnd { param_env, value } = goal; - tcx.sess.perf_stats.normalize_ty_after_erasing_regions.fetch_add(1, Ordering::Relaxed); + tcx.sess.perf_stats.normalize_generic_arg_after_erasing_regions.fetch_add(1, Ordering::Relaxed); tcx.infer_ctxt().enter(|infcx| { let cause = ObligationCause::dummy(); match infcx.at(&cause, param_env).normalize(&value) {