add projection_ty_from_predicates query

This commit is contained in:
csmoe 2020-08-27 12:09:34 +08:00
parent 8ee206a80d
commit 7cfcefd1fb
5 changed files with 31 additions and 32 deletions

View file

@ -1574,17 +1574,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.unwrap()
.def_id;
let mut projection_ty = None;
for (predicate, _) in self.tcx.predicates_of(def_id).predicates {
if let ty::PredicateAtom::Projection(projection_predicate) =
predicate.skip_binders()
{
if item_def_id == projection_predicate.projection_ty.item_def_id {
projection_ty = Some(projection_predicate.projection_ty);
break;
}
}
}
let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
if let Some(projection_ty) = projection_ty {
let projection_query = self.canonicalize_query(
&ParamEnvAnd { param_env: self.tcx.param_env(def_id), value: projection_ty },

View file

@ -173,6 +173,10 @@ rustc_queries! {
desc { |tcx| "finding projection predicates for `{}`", tcx.def_path_str(key) }
}
query projection_ty_from_predicates(key: (DefId, DefId)) -> Option<ty::ProjectionTy<'tcx>> {
desc { |tcx| "finding projection type inside predicates of `{}`", tcx.def_path_str(key.0) }
}
query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> {
desc { "looking up the native libraries of a linked crate" }
}

View file

@ -1523,15 +1523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let item_def_id =
self.tcx.associated_items(future_trait).in_definition_order().next().unwrap().def_id;
let mut projection_ty = None;
for (predicate, _) in self.tcx.predicates_of(def_id).predicates {
if let ty::PredicateAtom::Projection(projection_predicate) = predicate.skip_binders() {
if item_def_id == projection_predicate.projection_ty.item_def_id {
projection_ty = Some(projection_predicate.projection_ty);
break;
}
}
}
let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
debug!("suggest_await_on_field_access: projection_ty={:?}", projection_ty);
let cause = self.misc(expr.span);

View file

@ -870,7 +870,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call: &hir::Expr<'_>,
span: Span,
) {
if let ty::Opaque(def_id, _substs) = ty.kind {
if let ty::Opaque(def_id, _) = ty.kind {
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
// Future::Output
let item_def_id = self
@ -881,17 +881,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap()
.def_id;
let mut projection_ty = None;
for (predicate, _) in self.tcx.predicates_of(def_id).predicates {
if let ty::PredicateAtom::Projection(projection_predicate) =
predicate.skip_binders()
{
if item_def_id == projection_predicate.projection_ty.item_def_id {
projection_ty = Some(projection_predicate.projection_ty);
break;
}
}
}
let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
let cause = self.misc(span);
let mut selcx = SelectionContext::new(&self.infcx);
let mut obligations = vec![];

View file

@ -70,6 +70,7 @@ pub fn provide(providers: &mut Providers) {
generics_of,
predicates_of,
predicates_defined_on,
projection_ty_from_predicates,
explicit_predicates_of,
super_predicates_of,
type_param_predicates,
@ -2051,6 +2052,28 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
result
}
fn projection_ty_from_predicates(
tcx: TyCtxt<'tcx>,
key: (
// ty_def_id
DefId,
// def_id of `N` in `<T as Trait>::N`
DefId,
),
) -> Option<ty::ProjectionTy<'tcx>> {
let (ty_def_id, item_def_id) = key;
let mut projection_ty = None;
for (predicate, _) in tcx.predicates_of(ty_def_id).predicates {
if let ty::PredicateAtom::Projection(projection_predicate) = predicate.skip_binders() {
if item_def_id == projection_predicate.projection_ty.item_def_id {
projection_ty = Some(projection_predicate.projection_ty);
break;
}
}
}
projection_ty
}
fn trait_associated_item_predicates(
tcx: TyCtxt<'tcx>,
def_id: DefId,