]>
git.proxmox.com Git - rustc.git/blob - compiler/rustc_typeck/src/collect/item_bounds.rs
2 use crate::astconv
::AstConv
;
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 ast_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 icx
= ItemCtxt
::new(tcx
, assoc_item_def_id
);
29 let mut bounds
= <dyn AstConv
<'_
>>::compute_bounds(&icx
, item_ty
, ast_bounds
);
30 // Associated types are implicitly sized unless a `?Sized` bound is found
31 <dyn AstConv
<'_
>>::add_implicitly_sized(&icx
, &mut bounds
, ast_bounds
, None
, span
);
33 let trait_def_id
= tcx
.associated_item(assoc_item_def_id
).container
.id();
34 let trait_predicates
= tcx
.trait_explicit_predicates_and_bounds(trait_def_id
.expect_local());
36 let bounds_from_parent
= trait_predicates
.predicates
.iter().copied().filter(|(pred
, _
)| {
37 match pred
.kind().skip_binder() {
38 ty
::PredicateKind
::Trait(tr
) => tr
.self_ty() == item_ty
,
39 ty
::PredicateKind
::Projection(proj
) => proj
.projection_ty
.self_ty() == item_ty
,
40 ty
::PredicateKind
::TypeOutlives(outlives
) => outlives
.0 == item_ty
,
47 .alloc_from_iter(bounds
.predicates(tcx
, item_ty
).into_iter().chain(bounds_from_parent
));
48 debug
!("associated_type_bounds({}) = {:?}", tcx
.def_path_str(assoc_item_def_id
), all_bounds
);
52 /// Opaque types don't inherit bounds from their parent: for return position
53 /// impl trait it isn't possible to write a suitable predicate on the
54 /// containing function and for type-alias impl trait we don't have a backwards
55 /// compatibility issue.
56 fn opaque_type_bounds
<'tcx
>(
59 ast_bounds
: &'tcx
[hir
::GenericBound
<'tcx
>],
61 ) -> &'tcx
[(ty
::Predicate
<'tcx
>, Span
)] {
62 ty
::print
::with_no_queries
!({
64 tcx
.mk_opaque(opaque_def_id
, InternalSubsts
::identity_for_item(tcx
, opaque_def_id
));
66 let icx
= ItemCtxt
::new(tcx
, opaque_def_id
);
67 let mut bounds
= <dyn AstConv
<'_
>>::compute_bounds(&icx
, item_ty
, ast_bounds
);
68 // Opaque types are implicitly sized unless a `?Sized` bound is found
69 <dyn AstConv
<'_
>>::add_implicitly_sized(&icx
, &mut bounds
, ast_bounds
, None
, span
);
70 tcx
.arena
.alloc_from_iter(bounds
.predicates(tcx
, item_ty
))
74 pub(super) fn explicit_item_bounds(
77 ) -> &'_
[(ty
::Predicate
<'_
>, Span
)] {
78 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
79 match tcx
.hir().get(hir_id
) {
80 hir
::Node
::TraitItem(hir
::TraitItem
{
81 kind
: hir
::TraitItemKind
::Type(bounds
, _
),
84 }) => associated_type_bounds(tcx
, def_id
, bounds
, *span
),
85 hir
::Node
::Item(hir
::Item
{
86 kind
: hir
::ItemKind
::OpaqueTy(hir
::OpaqueTy { bounds, .. }
),
89 }) => opaque_type_bounds(tcx
, def_id
, bounds
, *span
),
90 _
=> bug
!("item_bounds called on {:?}", def_id
),
94 pub(super) fn item_bounds(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> &'_ ty
::List
<ty
::Predicate
<'_
>> {
96 util
::elaborate_predicates(
98 tcx
.explicit_item_bounds(def_id
).iter().map(|&(bound
, _span
)| bound
),
100 .map(|obligation
| obligation
.predicate
),