diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 50625af0adf..18bf2a7beaa 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -556,6 +556,14 @@ rustc_queries! { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } cache_on_disk_if { true } } + query typeck_tables_of_const_arg( + key: ty::WithOptParam + ) -> &'tcx ty::TypeckTables<'tcx> { + desc { + |tcx| "type-checking the potential const argument `{}`", + tcx.def_path_str(key.did.to_def_id()), + } + } query diagnostic_only_typeck_tables_of(key: LocalDefId) -> &'tcx ty::TypeckTables<'tcx> { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } cache_on_disk_if { true } diff --git a/src/librustc_middle/ty/query/keys.rs b/src/librustc_middle/ty/query/keys.rs index 5fc99173761..ad205e1f83b 100644 --- a/src/librustc_middle/ty/query/keys.rs +++ b/src/librustc_middle/ty/query/keys.rs @@ -105,6 +105,17 @@ impl Key for DefId { } } +impl Key for ty::WithOptParam { + type CacheSelector = DefaultCacheSelector; + + fn query_crate(&self) -> CrateNum { + self.did.query_crate() + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.did.default_span(tcx) + } +} + impl Key for (DefId, DefId) { type CacheSelector = DefaultCacheSelector; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 56f751e000b..4f792a07cc6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -764,6 +764,7 @@ pub fn provide(providers: &mut Providers) { method::provide(providers); *providers = Providers { typeck_item_bodies, + typeck_tables_of_const_arg, typeck_tables_of, diagnostic_only_typeck_tables_of, has_typeck_tables, @@ -955,9 +956,25 @@ where val.fold_with(&mut FixupFolder { tcx }) } +fn typeck_tables_of_const_arg<'tcx>( + tcx: TyCtxt<'tcx>, + def: ty::WithOptParam, +) -> &ty::TypeckTables<'tcx> { + if let Some(param_did) = def.param_did { + let fallback = move || tcx.type_of(param_did); + typeck_tables_of_with_fallback(tcx, def.did, fallback) + } else { + tcx.typeck_tables_of(def.did) + } +} + fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> { - let fallback = move || tcx.type_of(def_id.to_def_id()); - typeck_tables_of_with_fallback(tcx, def_id, fallback) + if let param_did @ Some(_) = tcx.opt_const_param_of(def_id) { + tcx.typeck_tables_of_const_arg(ty::WithOptParam { did: def_id, param_did }) + } else { + let fallback = move || tcx.type_of(def_id.to_def_id()); + typeck_tables_of_with_fallback(tcx, def_id, fallback) + } } /// Used only to get `TypeckTables` for type inference during error recovery.