From 7fe472223e4bcdd960d73e323979d15168ce4e39 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 25 Nov 2022 18:18:03 -0300 Subject: [PATCH] Store relationships on Inherent --- compiler/rustc_hir_typeck/src/fallback.rs | 7 ++----- compiler/rustc_hir_typeck/src/inherited.rs | 12 ++++++++++- compiler/rustc_hir_typeck/src/lib.rs | 1 + .../src}/relationships.rs | 20 ++++++++---------- compiler/rustc_infer/src/traits/engine.rs | 3 --- .../src/solve/fulfill.rs | 6 ------ .../src/traits/chalk_fulfill.rs | 18 +++------------- .../src/traits/fulfill.rs | 21 ++----------------- .../rustc_trait_selection/src/traits/mod.rs | 1 - 9 files changed, 28 insertions(+), 61 deletions(-) rename compiler/{rustc_trait_selection/src/traits => rustc_hir_typeck/src}/relationships.rs (77%) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 1015cea74b3..4ef32023e7d 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -196,8 +196,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> { ) -> FxHashMap, Ty<'tcx>> { debug!("calculate_diverging_fallback({:?})", unsolved_variables); - let relationships = self.fulfillment_cx.borrow_mut().relationships().clone(); - // Construct a coercion graph where an edge `A -> B` indicates // a type variable is that is coerced let coercion_graph = self.create_coercion_graph(); @@ -282,7 +280,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> { ); debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations()); - debug!("relationships: {:#?}", relationships); // For each diverging variable, figure out whether it can // reach a member of N. If so, it falls back to `()`. Else @@ -298,8 +295,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false }; - for (vid, rel) in relationships.iter() { - if self.root_var(*vid) == root_vid { + for (vid, rel) in self.inh.relationships.borrow().iter() { + if self.infcx.root_var(*vid) == root_vid { relationship.self_in_trait |= rel.self_in_trait; relationship.output |= rel.output; } diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index b33e7b8d68c..f5b6578a9d3 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -1,6 +1,6 @@ use super::callee::DeferredCallResolution; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::HirIdMap; @@ -63,6 +63,8 @@ pub struct Inherited<'tcx> { /// we record that type variable here. This is later used to inform /// fallback. See the `fallback` module for details. pub(super) diverging_type_vars: RefCell>>, + + pub(super) relationships: RefCell>, } impl<'tcx> Deref for Inherited<'tcx> { @@ -128,6 +130,7 @@ impl<'tcx> Inherited<'tcx> { deferred_generator_interiors: RefCell::new(Vec::new()), diverging_type_vars: RefCell::new(Default::default()), body_id, + relationships: RefCell::new(Default::default()), } } @@ -136,6 +139,13 @@ impl<'tcx> Inherited<'tcx> { if obligation.has_escaping_bound_vars() { span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation); } + + super::relationships::update( + &self.infcx, + &mut self.relationships.borrow_mut(), + &obligation, + ); + self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation); } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 7ddf9eaa4d8..54fd03d6493 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -40,6 +40,7 @@ mod method; mod op; mod pat; mod place_op; +mod relationships; mod rvalue_scopes; mod upvar; mod writeback; diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_hir_typeck/src/relationships.rs similarity index 77% rename from compiler/rustc_trait_selection/src/traits/relationships.rs rename to compiler/rustc_hir_typeck/src/relationships.rs index 34b5fc4891e..66aba084974 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_hir_typeck/src/relationships.rs @@ -1,16 +1,14 @@ -use crate::infer::InferCtxt; -use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::PredicateObligation; -use rustc_infer::traits::TraitEngine; +use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty; +use rustc_trait_selection::infer::InferCtxt; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; +use rustc_trait_selection::traits::PredicateObligation; -pub(crate) fn update<'tcx, T>( - engine: &mut T, +pub fn update<'tcx>( infcx: &InferCtxt<'tcx>, + relationships: &mut FxHashMap, obligation: &PredicateObligation<'tcx>, -) where - T: TraitEngine<'tcx>, -{ +) { // (*) binder skipped if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder() && let Some(ty) = infcx.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| infcx.root_var(t)) @@ -31,7 +29,7 @@ pub(crate) fn update<'tcx, T>( ); // Don't report overflow errors. Otherwise equivalent to may_hold. if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) && result.may_apply() { - engine.relationships().entry(ty).or_default().self_in_trait = true; + relationships.entry(ty).or_default().self_in_trait = true; } } @@ -42,7 +40,7 @@ pub(crate) fn update<'tcx, T>( // we need to make it into one. if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) { debug!("relationship: {:?}.output = true", vid); - engine.relationships().entry(vid).or_default().output = true; + relationships.entry(vid).or_default().output = true; } } } diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index d3519f4b37b..fcde00056cb 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -1,6 +1,5 @@ use crate::infer::InferCtxt; use crate::traits::Obligation; -use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, ToPredicate, Ty}; @@ -42,8 +41,6 @@ pub trait TraitEngine<'tcx>: 'tcx { fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec>; fn pending_obligations(&self) -> Vec>; - - fn relationships(&mut self) -> &mut FxHashMap; } pub trait TraitEngineExt<'tcx> { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index a6240666ed4..40b9bedc84f 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -1,6 +1,5 @@ use std::mem; -use rustc_data_structures::fx::FxHashMap; use rustc_infer::{ infer::InferCtxt, traits::{ @@ -8,7 +7,6 @@ use rustc_infer::{ SelectionError, TraitEngine, }, }; -use rustc_middle::ty; use super::{search_graph, Certainty, EvalCtxt}; @@ -102,8 +100,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { fn pending_obligations(&self) -> Vec> { self.obligations.clone() } - - fn relationships(&mut self) -> &mut FxHashMap { - unimplemented!("Should be moved out of `TraitEngine`") - } } diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index e8895052353..61d09189798 100644 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs @@ -7,24 +7,18 @@ use crate::traits::{ ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, PredicateObligation, SelectionError, TraitEngine, }; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; -use rustc_middle::ty::{self, TypeVisitable}; +use rustc_data_structures::fx::FxIndexSet; +use rustc_middle::ty::TypeVisitable; pub struct FulfillmentContext<'tcx> { obligations: FxIndexSet>, - relationships: FxHashMap, - usable_in_snapshot: bool, } impl FulfillmentContext<'_> { pub(super) fn new() -> Self { - FulfillmentContext { - obligations: FxIndexSet::default(), - relationships: FxHashMap::default(), - usable_in_snapshot: false, - } + FulfillmentContext { obligations: FxIndexSet::default(), usable_in_snapshot: false } } pub(crate) fn new_in_snapshot() -> Self { @@ -43,8 +37,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { } let obligation = infcx.resolve_vars_if_possible(obligation); - super::relationships::update(self, infcx, &obligation); - self.obligations.insert(obligation); } @@ -154,8 +146,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { fn pending_obligations(&self) -> Vec> { self.obligations.iter().cloned().collect() } - - fn relationships(&mut self) -> &mut FxHashMap { - &mut self.relationships - } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 76a755ed9e0..5a58d37e183 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,5 +1,4 @@ use crate::infer::{InferCtxt, TyOrConstInferVar}; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; @@ -54,8 +53,6 @@ pub struct FulfillmentContext<'tcx> { // fulfillment context. predicates: ObligationForest>, - relationships: FxHashMap, - // Is it OK to register obligations into this infcx inside // an infcx snapshot? // @@ -85,19 +82,11 @@ static_assert_size!(PendingPredicateObligation<'_>, 72); impl<'a, 'tcx> FulfillmentContext<'tcx> { /// Creates a new fulfillment context. pub(super) fn new() -> FulfillmentContext<'tcx> { - FulfillmentContext { - predicates: ObligationForest::new(), - relationships: FxHashMap::default(), - usable_in_snapshot: false, - } + FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: false } } pub(super) fn new_in_snapshot() -> FulfillmentContext<'tcx> { - FulfillmentContext { - predicates: ObligationForest::new(), - relationships: FxHashMap::default(), - usable_in_snapshot: true, - } + FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: true } } /// Attempts to select obligations using `selcx`. @@ -139,8 +128,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot); - super::relationships::update(self, infcx, &obligation); - self.predicates .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] }); } @@ -164,10 +151,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { fn pending_obligations(&self) -> Vec> { self.predicates.map_pending_obligations(|o| o.obligation.clone()) } - - fn relationships(&mut self) -> &mut FxHashMap { - &mut self.relationships - } } struct FulfillProcessor<'a, 'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index f036a311d46..3c640cdc503 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -14,7 +14,6 @@ mod object_safety; pub mod outlives_bounds; mod project; pub mod query; -pub(crate) mod relationships; mod select; mod specialize; mod structural_match;