2 use crate::astconv
::{AstConv, SizedByDefault}
;
4 use rustc_infer
::traits
::util
;
5 use rustc_middle
::ty
::subst
::InternalSubsts
;
6 use rustc_middle
::ty
::{self, TyCtxt}
;
7 use rustc_span
::def_id
::DefId
;
10 /// For associated types we include both bounds written on the type
11 /// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
13 /// Note that this filtering is done with the items identity substs to
14 /// simplify checking that these bounds are met in impls. This means that
15 /// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
16 /// `hr-associated-type-bound-1.rs`.
17 fn associated_type_bounds
<'tcx
>(
19 assoc_item_def_id
: DefId
,
20 bounds
: &'tcx
[hir
::GenericBound
<'tcx
>],
22 ) -> &'tcx
[(ty
::Predicate
<'tcx
>, Span
)] {
23 let item_ty
= tcx
.mk_projection(
25 InternalSubsts
::identity_for_item(tcx
, assoc_item_def_id
),
28 let bounds
= <dyn AstConv
<'_
>>::compute_bounds(
29 &ItemCtxt
::new(tcx
, assoc_item_def_id
),
36 let trait_def_id
= tcx
.associated_item(assoc_item_def_id
).container
.id();
37 let trait_predicates
= tcx
.trait_explicit_predicates_and_bounds(trait_def_id
.expect_local());
39 let bounds_from_parent
= trait_predicates
.predicates
.iter().copied().filter(|(pred
, _
)| {
40 match pred
.kind().skip_binder() {
41 ty
::PredicateKind
::Trait(tr
) => tr
.self_ty() == item_ty
,
42 ty
::PredicateKind
::Projection(proj
) => proj
.projection_ty
.self_ty() == item_ty
,
43 ty
::PredicateKind
::TypeOutlives(outlives
) => outlives
.0 == item_ty
,
50 .alloc_from_iter(bounds
.predicates(tcx
, item_ty
).into_iter().chain(bounds_from_parent
));
51 debug
!("associated_type_bounds({}) = {:?}", tcx
.def_path_str(assoc_item_def_id
), all_bounds
);
55 /// Opaque types don't inherit bounds from their parent: for return position
56 /// impl trait it isn't possible to write a suitable predicate on the
57 /// containing function and for type-alias impl trait we don't have a backwards
58 /// compatibility issue.
59 fn opaque_type_bounds
<'tcx
>(
62 bounds
: &'tcx
[hir
::GenericBound
<'tcx
>],
64 ) -> &'tcx
[(ty
::Predicate
<'tcx
>, Span
)] {
65 ty
::print
::with_no_queries(|| {
67 tcx
.mk_opaque(opaque_def_id
, InternalSubsts
::identity_for_item(tcx
, opaque_def_id
));
69 let bounds
= <dyn AstConv
<'_
>>::compute_bounds(
70 &ItemCtxt
::new(tcx
, opaque_def_id
),
76 .predicates(tcx
, item_ty
);
78 debug
!("opaque_type_bounds({}) = {:?}", tcx
.def_path_str(opaque_def_id
), bounds
);
80 tcx
.arena
.alloc_slice(&bounds
)
84 pub(super) fn explicit_item_bounds(
87 ) -> &'_
[(ty
::Predicate
<'_
>, Span
)] {
88 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
89 match tcx
.hir().get(hir_id
) {
90 hir
::Node
::TraitItem(hir
::TraitItem
{
91 kind
: hir
::TraitItemKind
::Type(bounds
, _
),
94 }) => associated_type_bounds(tcx
, def_id
, bounds
, *span
),
95 hir
::Node
::Item(hir
::Item
{
96 kind
: hir
::ItemKind
::OpaqueTy(hir
::OpaqueTy { bounds, .. }
),
99 }) => opaque_type_bounds(tcx
, def_id
, bounds
, *span
),
100 _
=> bug
!("item_bounds called on {:?}", def_id
),
104 pub(super) fn item_bounds(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> &'_ ty
::List
<ty
::Predicate
<'_
>> {
106 util
::elaborate_predicates(
108 tcx
.explicit_item_bounds(def_id
).iter().map(|&(bound
, _span
)| bound
),
110 .map(|obligation
| obligation
.predicate
),