Store relationships on Inherent
This commit is contained in:
parent
81ee6aebaa
commit
7fe472223e
9 changed files with 28 additions and 61 deletions
|
@ -196,8 +196,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
) -> FxHashMap<Ty<'tcx>, Ty<'tcx>> {
|
) -> FxHashMap<Ty<'tcx>, Ty<'tcx>> {
|
||||||
debug!("calculate_diverging_fallback({:?})", unsolved_variables);
|
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
|
// Construct a coercion graph where an edge `A -> B` indicates
|
||||||
// a type variable is that is coerced
|
// a type variable is that is coerced
|
||||||
let coercion_graph = self.create_coercion_graph();
|
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!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations());
|
||||||
debug!("relationships: {:#?}", relationships);
|
|
||||||
|
|
||||||
// For each diverging variable, figure out whether it can
|
// For each diverging variable, figure out whether it can
|
||||||
// reach a member of N. If so, it falls back to `()`. Else
|
// 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 };
|
let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };
|
||||||
|
|
||||||
for (vid, rel) in relationships.iter() {
|
for (vid, rel) in self.inh.relationships.borrow().iter() {
|
||||||
if self.root_var(*vid) == root_vid {
|
if self.infcx.root_var(*vid) == root_vid {
|
||||||
relationship.self_in_trait |= rel.self_in_trait;
|
relationship.self_in_trait |= rel.self_in_trait;
|
||||||
relationship.output |= rel.output;
|
relationship.output |= rel.output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::callee::DeferredCallResolution;
|
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 as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::HirIdMap;
|
use rustc_hir::HirIdMap;
|
||||||
|
@ -63,6 +63,8 @@ pub struct Inherited<'tcx> {
|
||||||
/// we record that type variable here. This is later used to inform
|
/// we record that type variable here. This is later used to inform
|
||||||
/// fallback. See the `fallback` module for details.
|
/// fallback. See the `fallback` module for details.
|
||||||
pub(super) diverging_type_vars: RefCell<FxHashSet<Ty<'tcx>>>,
|
pub(super) diverging_type_vars: RefCell<FxHashSet<Ty<'tcx>>>,
|
||||||
|
|
||||||
|
pub(super) relationships: RefCell<FxHashMap<ty::TyVid, ty::FoundRelationships>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Deref for Inherited<'tcx> {
|
impl<'tcx> Deref for Inherited<'tcx> {
|
||||||
|
@ -128,6 +130,7 @@ impl<'tcx> Inherited<'tcx> {
|
||||||
deferred_generator_interiors: RefCell::new(Vec::new()),
|
deferred_generator_interiors: RefCell::new(Vec::new()),
|
||||||
diverging_type_vars: RefCell::new(Default::default()),
|
diverging_type_vars: RefCell::new(Default::default()),
|
||||||
body_id,
|
body_id,
|
||||||
|
relationships: RefCell::new(Default::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +139,13 @@ impl<'tcx> Inherited<'tcx> {
|
||||||
if obligation.has_escaping_bound_vars() {
|
if obligation.has_escaping_bound_vars() {
|
||||||
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
|
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);
|
self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ mod method;
|
||||||
mod op;
|
mod op;
|
||||||
mod pat;
|
mod pat;
|
||||||
mod place_op;
|
mod place_op;
|
||||||
|
mod relationships;
|
||||||
mod rvalue_scopes;
|
mod rvalue_scopes;
|
||||||
mod upvar;
|
mod upvar;
|
||||||
mod writeback;
|
mod writeback;
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use crate::infer::InferCtxt;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
|
||||||
use crate::traits::PredicateObligation;
|
|
||||||
use rustc_infer::traits::TraitEngine;
|
|
||||||
use rustc_middle::ty;
|
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>(
|
pub fn update<'tcx>(
|
||||||
engine: &mut T,
|
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
|
relationships: &mut FxHashMap<ty::TyVid, ty::FoundRelationships>,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
) where
|
) {
|
||||||
T: TraitEngine<'tcx>,
|
|
||||||
{
|
|
||||||
// (*) binder skipped
|
// (*) binder skipped
|
||||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder()
|
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))
|
&& 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.
|
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||||
if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) && result.may_apply() {
|
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.
|
// we need to make it into one.
|
||||||
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {
|
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {
|
||||||
debug!("relationship: {:?}.output = true", vid);
|
debug!("relationship: {:?}.output = true", vid);
|
||||||
engine.relationships().entry(vid).or_default().output = true;
|
relationships.entry(vid).or_default().output = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
use crate::traits::Obligation;
|
use crate::traits::Obligation;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty};
|
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<FulfillmentError<'tcx>>;
|
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
|
||||||
|
|
||||||
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
|
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
|
||||||
|
|
||||||
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TraitEngineExt<'tcx> {
|
pub trait TraitEngineExt<'tcx> {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_infer::{
|
use rustc_infer::{
|
||||||
infer::InferCtxt,
|
infer::InferCtxt,
|
||||||
traits::{
|
traits::{
|
||||||
|
@ -8,7 +7,6 @@ use rustc_infer::{
|
||||||
SelectionError, TraitEngine,
|
SelectionError, TraitEngine,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_middle::ty;
|
|
||||||
|
|
||||||
use super::{search_graph, Certainty, EvalCtxt};
|
use super::{search_graph, Certainty, EvalCtxt};
|
||||||
|
|
||||||
|
@ -102,8 +100,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
||||||
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
||||||
self.obligations.clone()
|
self.obligations.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
|
|
||||||
unimplemented!("Should be moved out of `TraitEngine`")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,18 @@ use crate::traits::{
|
||||||
ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
|
ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
|
||||||
SelectionError, TraitEngine,
|
SelectionError, TraitEngine,
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_middle::ty::{self, TypeVisitable};
|
use rustc_middle::ty::TypeVisitable;
|
||||||
|
|
||||||
pub struct FulfillmentContext<'tcx> {
|
pub struct FulfillmentContext<'tcx> {
|
||||||
obligations: FxIndexSet<PredicateObligation<'tcx>>,
|
obligations: FxIndexSet<PredicateObligation<'tcx>>,
|
||||||
|
|
||||||
relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
|
|
||||||
|
|
||||||
usable_in_snapshot: bool,
|
usable_in_snapshot: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FulfillmentContext<'_> {
|
impl FulfillmentContext<'_> {
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
FulfillmentContext {
|
FulfillmentContext { obligations: FxIndexSet::default(), usable_in_snapshot: false }
|
||||||
obligations: FxIndexSet::default(),
|
|
||||||
relationships: FxHashMap::default(),
|
|
||||||
usable_in_snapshot: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_in_snapshot() -> Self {
|
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);
|
let obligation = infcx.resolve_vars_if_possible(obligation);
|
||||||
|
|
||||||
super::relationships::update(self, infcx, &obligation);
|
|
||||||
|
|
||||||
self.obligations.insert(obligation);
|
self.obligations.insert(obligation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +146,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||||
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
||||||
self.obligations.iter().cloned().collect()
|
self.obligations.iter().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
|
|
||||||
&mut self.relationships
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::infer::{InferCtxt, TyOrConstInferVar};
|
use crate::infer::{InferCtxt, TyOrConstInferVar};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_data_structures::obligation_forest::ProcessResult;
|
use rustc_data_structures::obligation_forest::ProcessResult;
|
||||||
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
||||||
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
||||||
|
@ -54,8 +53,6 @@ pub struct FulfillmentContext<'tcx> {
|
||||||
// fulfillment context.
|
// fulfillment context.
|
||||||
predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
|
predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
|
||||||
|
|
||||||
relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
|
|
||||||
|
|
||||||
// Is it OK to register obligations into this infcx inside
|
// Is it OK to register obligations into this infcx inside
|
||||||
// an infcx snapshot?
|
// an infcx snapshot?
|
||||||
//
|
//
|
||||||
|
@ -85,19 +82,11 @@ static_assert_size!(PendingPredicateObligation<'_>, 72);
|
||||||
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
||||||
/// Creates a new fulfillment context.
|
/// Creates a new fulfillment context.
|
||||||
pub(super) fn new() -> FulfillmentContext<'tcx> {
|
pub(super) fn new() -> FulfillmentContext<'tcx> {
|
||||||
FulfillmentContext {
|
FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: false }
|
||||||
predicates: ObligationForest::new(),
|
|
||||||
relationships: FxHashMap::default(),
|
|
||||||
usable_in_snapshot: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn new_in_snapshot() -> FulfillmentContext<'tcx> {
|
pub(super) fn new_in_snapshot() -> FulfillmentContext<'tcx> {
|
||||||
FulfillmentContext {
|
FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: true }
|
||||||
predicates: ObligationForest::new(),
|
|
||||||
relationships: FxHashMap::default(),
|
|
||||||
usable_in_snapshot: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to select obligations using `selcx`.
|
/// 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);
|
assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot);
|
||||||
|
|
||||||
super::relationships::update(self, infcx, &obligation);
|
|
||||||
|
|
||||||
self.predicates
|
self.predicates
|
||||||
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
|
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
|
||||||
}
|
}
|
||||||
|
@ -164,10 +151,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||||
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
||||||
self.predicates.map_pending_obligations(|o| o.obligation.clone())
|
self.predicates.map_pending_obligations(|o| o.obligation.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
|
|
||||||
&mut self.relationships
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FulfillProcessor<'a, 'tcx> {
|
struct FulfillProcessor<'a, 'tcx> {
|
||||||
|
|
|
@ -14,7 +14,6 @@ mod object_safety;
|
||||||
pub mod outlives_bounds;
|
pub mod outlives_bounds;
|
||||||
mod project;
|
mod project;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
pub(crate) mod relationships;
|
|
||||||
mod select;
|
mod select;
|
||||||
mod specialize;
|
mod specialize;
|
||||||
mod structural_match;
|
mod structural_match;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue