Extract ImplSubject information
This commit is contained in:
parent
91b52148eb
commit
0cd03c917c
3 changed files with 50 additions and 37 deletions
|
@ -7,10 +7,10 @@ pub mod nested_filter;
|
||||||
pub mod place;
|
pub mod place;
|
||||||
|
|
||||||
use crate::ty::query::Providers;
|
use crate::ty::query::Providers;
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::{ImplSubject, TyCtxt};
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
use rustc_query_system::ich::StableHashingContext;
|
use rustc_query_system::ich::StableHashingContext;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
@ -54,6 +54,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn parent_module(self, id: HirId) -> LocalDefId {
|
pub fn parent_module(self, id: HirId) -> LocalDefId {
|
||||||
self.parent_module_from_def_id(id.owner)
|
self.parent_module_from_def_id(id.owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn impl_header(self, def_id: DefId) -> ImplSubject<'tcx> {
|
||||||
|
self.impl_trait_ref(def_id)
|
||||||
|
.map(ImplSubject::Trait)
|
||||||
|
.unwrap_or_else(|| ImplSubject::Inherent(self.type_of(def_id)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
|
|
|
@ -172,6 +172,12 @@ pub struct ImplHeader<'tcx> {
|
||||||
pub predicates: Vec<Predicate<'tcx>>,
|
pub predicates: Vec<Predicate<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ImplSubject<'tcx> {
|
||||||
|
Trait(TraitRef<'tcx>),
|
||||||
|
Inherent(Ty<'tcx>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Copy,
|
Copy,
|
||||||
Clone,
|
Clone,
|
||||||
|
|
|
@ -24,7 +24,7 @@ use rustc_middle::traits::specialization_graph::OverlapMode;
|
||||||
use rustc_middle::ty::fast_reject::{self, TreatParams};
|
use rustc_middle::ty::fast_reject::{self, TreatParams};
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::subst::Subst;
|
use rustc_middle::ty::subst::Subst;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -307,46 +307,47 @@ fn negative_impl<'cx, 'tcx>(
|
||||||
// create a parameter environment corresponding to a (placeholder) instantiation of impl1
|
// create a parameter environment corresponding to a (placeholder) instantiation of impl1
|
||||||
let impl1_env = tcx.param_env(impl1_def_id);
|
let impl1_env = tcx.param_env(impl1_def_id);
|
||||||
|
|
||||||
if let Some(impl1_trait_ref) = tcx.impl_trait_ref(impl1_def_id) {
|
match tcx.impl_header(impl1_def_id) {
|
||||||
// Normalize the trait reference. The WF rules ought to ensure
|
ImplSubject::Trait(impl1_trait_ref) => {
|
||||||
// that this always succeeds.
|
// Normalize the trait reference. The WF rules ought to ensure
|
||||||
let impl1_trait_ref = match traits::fully_normalize(
|
// that this always succeeds.
|
||||||
&infcx,
|
let impl1_trait_ref = match traits::fully_normalize(
|
||||||
FulfillmentContext::new(),
|
&infcx,
|
||||||
ObligationCause::dummy(),
|
FulfillmentContext::new(),
|
||||||
impl1_env,
|
ObligationCause::dummy(),
|
||||||
impl1_trait_ref,
|
impl1_env,
|
||||||
) {
|
impl1_trait_ref,
|
||||||
Ok(impl1_trait_ref) => impl1_trait_ref,
|
) {
|
||||||
Err(err) => {
|
Ok(impl1_trait_ref) => impl1_trait_ref,
|
||||||
bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err);
|
Err(err) => {
|
||||||
}
|
bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Attempt to prove that impl2 applies, given all of the above.
|
// Attempt to prove that impl2 applies, given all of the above.
|
||||||
let selcx = &mut SelectionContext::new(&infcx);
|
let selcx = &mut SelectionContext::new(&infcx);
|
||||||
let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id);
|
let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id);
|
||||||
let (impl2_trait_ref, obligations) =
|
let (impl2_trait_ref, obligations) =
|
||||||
impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs);
|
impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs);
|
||||||
|
|
||||||
!obligations_satisfiable(
|
!equate(
|
||||||
&infcx,
|
&infcx,
|
||||||
impl1_env,
|
impl1_env,
|
||||||
impl1_def_id,
|
impl1_def_id,
|
||||||
impl1_trait_ref,
|
impl1_trait_ref,
|
||||||
impl2_trait_ref,
|
impl2_trait_ref,
|
||||||
obligations,
|
obligations,
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
let ty1 = tcx.type_of(impl1_def_id);
|
ImplSubject::Inherent(ty1) => {
|
||||||
let ty2 = tcx.type_of(impl2_def_id);
|
let ty2 = tcx.type_of(impl2_def_id);
|
||||||
|
!equate(&infcx, impl1_env, impl1_def_id, ty1, ty2, iter::empty())
|
||||||
!obligations_satisfiable(&infcx, impl1_env, impl1_def_id, ty1, ty2, iter::empty())
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn obligations_satisfiable<'cx, 'tcx, T: Debug + ToTrace<'tcx>>(
|
fn equate<'cx, 'tcx, T: Debug + ToTrace<'tcx>>(
|
||||||
infcx: &InferCtxt<'cx, 'tcx>,
|
infcx: &InferCtxt<'cx, 'tcx>,
|
||||||
impl1_env: ty::ParamEnv<'tcx>,
|
impl1_env: ty::ParamEnv<'tcx>,
|
||||||
impl1_def_id: DefId,
|
impl1_def_id: DefId,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue