diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 7eb12d380a7..992316edb63 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -447,14 +447,9 @@ fn provided_kind( handle_ty_args(has_default, &inf.to_ty()) } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - ty::Const::from_opt_const_arg_anon_const( - tcx, - ty::WithOptConstParam { - did: ct.value.def_id, - const_param_did: Some(param.def_id), - }, - ) - .into() + let did = ct.value.def_id; + tcx.feed_anon_const_type(did, tcx.type_of(param.def_id)); + ty::Const::from_anon_const(tcx, did).into() } (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { let ty = tcx diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 13a869caa8f..2b5af4bc81b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -420,9 +420,9 @@ pub fn const_arg_to_const( ast_c: &hir::AnonConst, param_def_id: DefId, ) -> ty::Const<'tcx> { - let const_def = - ty::WithOptConstParam { did: ast_c.def_id, const_param_did: Some(param_def_id) }; - let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def); + let did = ast_c.def_id; + self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id)); + let c = ty::Const::from_anon_const(self.tcx, did); self.register_wf_obligation( c.into(), self.tcx.hir().span(ast_c.hir_id), diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 49da78b18e2..b460fd7a8da 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -165,12 +165,8 @@ fn typeck_const_arg<'tcx>( } fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> { - if let Some(param_did) = tcx.opt_const_param_of(def_id) { - tcx.typeck_const_arg((def_id, param_did)) - } else { - let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); - typeck_with_fallback(tcx, def_id, fallback) - } + let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); + typeck_with_fallback(tcx, def_id, fallback) } /// Used only to get `TypeckResults` for type inference during error recovery. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f9d3ffc8f00..ef2452aba73 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -449,6 +449,14 @@ pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> { pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> { TyCtxtFeed { tcx: self, key: LOCAL_CRATE } } + + /// In order to break cycles involving `AnonConst`, we need to set the expected type by side + /// effect. However, we do not want this as a general capability, so this interface restricts + /// to the only allowed case. + pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder>) { + debug_assert_eq!(self.def_kind(key), DefKind::AnonConst); + TyCtxtFeed { tcx: self, key }.type_of(value) + } } impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1061c320793..8932900fc1c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1548,20 +1548,14 @@ 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)) + pub fn try_lookup(_: LocalDefId, _: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> { + None } /// 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 }); - } - } - + pub fn try_upgrade(self, _: TyCtxt<'_>) -> Option> { None } @@ -1570,7 +1564,7 @@ pub fn to_global(self) -> WithOptConstParam { } pub fn def_id_for_type_of(self) -> DefId { - if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() } + self.did.to_def_id() } } diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 97592cbc567..e46cfb8dd16 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -76,6 +76,9 @@ use std::path::PathBuf; use std::sync::Arc; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_query_system::ich::StableHashingContext; + #[derive(Default)] pub struct QuerySystem<'tcx> { pub arenas: QueryArenas<'tcx>, @@ -477,7 +480,7 @@ macro_rules! define_feedable { $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { $(#[$attr])* #[inline(always)] - pub fn $name(self, value: query_provided::$name<'tcx>) -> $V { + pub fn $name(self, value: query_provided::$name<'tcx>) { let key = self.key().into_query_param(); let tcx = self.tcx; @@ -485,13 +488,25 @@ pub fn $name(self, value: query_provided::$name<'tcx>) -> $V { let value = restore::<$V>(erased); let cache = &tcx.query_system.caches.$name; + let hasher: Option, &_) -> _> = hash_result!([$($modifiers)*]); match try_get_cached(tcx, cache, &key) { Some(old) => { let old = restore::<$V>(old); - bug!( - "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", - stringify!($name), - ) + if let Some(hasher) = hasher { + let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx| + (hasher(&mut hcx, &value), hasher(&mut hcx, &old)) + ); + assert_eq!( + old_hash, value_hash, + "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", + stringify!($name), + ) + } else { + bug!( + "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", + stringify!($name), + ) + } } None => { let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key); @@ -503,7 +518,6 @@ pub fn $name(self, value: query_provided::$name<'tcx>) -> $V { hash_result!([$($modifiers)*]), ); cache.complete(key, erased, dep_node_index); - value } } } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 47cd7af221d..35529ff8548 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -15,12 +15,6 @@ fn resolve_instance<'tcx>( key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, ) -> Result>, ErrorGuaranteed> { let (param_env, (did, substs)) = key.into_parts(); - if let Some(did) = did.as_local() { - if let Some(param_did) = tcx.opt_const_param_of(did) { - return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs))); - } - } - inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs))) }