summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/collect/item_bounds.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs76
1 files changed, 50 insertions, 26 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 9cf3ff65a..2e56d2463 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -3,8 +3,8 @@ use crate::astconv::AstConv;
use rustc_hir as hir;
use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{self, DefIdTree, TyCtxt};
-use rustc_span::def_id::DefId;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
/// For associated types we include both bounds written on the type
@@ -16,12 +16,12 @@ use rustc_span::Span;
/// `hr-associated-type-bound-1.rs`.
fn associated_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
- assoc_item_def_id: DefId,
+ assoc_item_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
let item_ty = tcx.mk_projection(
- assoc_item_def_id,
+ assoc_item_def_id.to_def_id(),
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
);
@@ -30,8 +30,8 @@ fn associated_type_bounds<'tcx>(
// Associated types are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
- let trait_def_id = tcx.parent(assoc_item_def_id);
- let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
+ let trait_def_id = tcx.local_parent(assoc_item_def_id);
+ let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
match pred.kind().skip_binder() {
@@ -45,7 +45,11 @@ fn associated_type_bounds<'tcx>(
});
let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent));
- debug!("associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id), all_bounds);
+ debug!(
+ "associated_type_bounds({}) = {:?}",
+ tcx.def_path_str(assoc_item_def_id.to_def_id()),
+ all_bounds
+ );
all_bounds
}
@@ -56,19 +60,12 @@ fn associated_type_bounds<'tcx>(
#[instrument(level = "trace", skip(tcx), ret)]
fn opaque_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
- opaque_def_id: DefId,
+ opaque_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
+ item_ty: Ty<'tcx>,
span: Span,
- in_trait: bool,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
ty::print::with_no_queries!({
- let substs = InternalSubsts::identity_for_item(tcx, opaque_def_id);
- let item_ty = if in_trait {
- tcx.mk_projection(opaque_def_id, substs)
- } else {
- tcx.mk_opaque(opaque_def_id, substs)
- };
-
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
// Opaque types are implicitly sized unless a `?Sized` bound is found
@@ -81,9 +78,31 @@ fn opaque_type_bounds<'tcx>(
pub(super) fn explicit_item_bounds(
tcx: TyCtxt<'_>,
- def_id: DefId,
+ def_id: LocalDefId,
) -> &'_ [(ty::Predicate<'_>, Span)] {
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+ match tcx.opt_rpitit_info(def_id.to_def_id()) {
+ // RPITIT's bounds are the same as opaque type bounds, but with
+ // a projection self type.
+ Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
+ let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
+ let opaque_ty = item.expect_opaque_ty();
+ return opaque_type_bounds(
+ tcx,
+ opaque_def_id.expect_local(),
+ opaque_ty.bounds,
+ tcx.mk_projection(
+ def_id.to_def_id(),
+ ty::InternalSubsts::identity_for_item(tcx, def_id),
+ ),
+ item.span,
+ );
+ }
+ // These should have been fed!
+ Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(),
+ None => {}
+ }
+
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
match tcx.hir().get(hir_id) {
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(bounds, _),
@@ -94,7 +113,15 @@ pub(super) fn explicit_item_bounds(
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
span,
..
- }) => opaque_type_bounds(tcx, def_id, bounds, *span, *in_trait),
+ }) => {
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
+ let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
+ tcx.mk_projection(def_id.to_def_id(), substs)
+ } else {
+ tcx.mk_opaque(def_id.to_def_id(), substs)
+ };
+ opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
+ }
_ => bug!("item_bounds called on {:?}", def_id),
}
}
@@ -103,12 +130,9 @@ pub(super) fn item_bounds(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> {
- let bounds = tcx.mk_predicates_from_iter(
- util::elaborate_predicates(
- tcx,
- tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound),
- )
- .map(|obligation| obligation.predicate),
- );
+ let bounds = tcx.mk_predicates_from_iter(util::elaborate(
+ tcx,
+ tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound),
+ ));
ty::EarlyBinder(bounds)
}