3 use rustc
::hir
::def_id
::{CrateNum, DefId, LOCAL_CRATE}
;
4 use rustc
::ty
::query
::Providers
;
5 use rustc
::ty
::subst
::UnpackedKind
;
6 use rustc
::ty
::{self, CratePredicatesMap, TyCtxt}
;
7 use syntax
::symbol
::sym
;
11 /// Code to write unit test for outlives.
15 pub fn provide(providers
: &mut Providers
<'_
>) {
16 *providers
= Providers
{
18 inferred_outlives_crate
,
23 fn inferred_outlives_of
<'tcx
>(
26 ) -> &'tcx
[ty
::Predicate
<'tcx
>] {
29 .as_local_hir_id(item_def_id
)
30 .expect("expected local def-id");
32 match tcx
.hir().get(id
) {
33 Node
::Item(item
) => match item
.node
{
34 hir
::ItemKind
::Struct(..) | hir
::ItemKind
::Enum(..) | hir
::ItemKind
::Union(..) => {
35 let crate_map
= tcx
.inferred_outlives_crate(LOCAL_CRATE
);
37 let predicates
= crate_map
43 if tcx
.has_attr(item_def_id
, sym
::rustc_outlives
) {
44 let mut pred
: Vec
<String
> = predicates
46 .map(|out_pred
| match out_pred
{
47 ty
::Predicate
::RegionOutlives(p
) => p
.to_string(),
48 ty
::Predicate
::TypeOutlives(p
) => p
.to_string(),
49 err
=> bug
!("unexpected predicate {:?}", err
),
53 let span
= tcx
.def_span(item_def_id
);
54 let mut err
= tcx
.sess
.struct_span_err(span
, "rustc_outlives");
61 debug
!("inferred_outlives_of({:?}) = {:?}", item_def_id
, predicates
);
73 fn inferred_outlives_crate
<'tcx
>(
76 ) -> &'tcx CratePredicatesMap
<'tcx
> {
77 assert_eq
!(crate_num
, LOCAL_CRATE
);
79 // Compute a map from each struct/enum/union S to the **explicit**
80 // outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote.
81 // Typically there won't be many of these, except in older code where
82 // they were mandatory. Nonetheless, we have to ensure that every such
83 // predicate is satisfied, so they form a kind of base set of requirements
86 // Compute the inferred predicates
87 let mut exp_map
= explicit
::ExplicitPredicatesMap
::new();
89 let global_inferred_outlives
= implicit_infer
::infer_predicates(tcx
, &mut exp_map
);
91 // Convert the inferred predicates into the "collected" form the
92 // global data structure expects.
94 // FIXME -- consider correcting impedance mismatch in some way,
95 // probably by updating the global data structure.
96 let predicates
= global_inferred_outlives
98 .map(|(&def_id
, set
)| {
99 let predicates
= tcx
.arena
.alloc_from_iter(set
102 |ty
::OutlivesPredicate(kind1
, region2
)| match kind1
.unpack() {
103 UnpackedKind
::Type(ty1
) => {
104 Some(ty
::Predicate
::TypeOutlives(ty
::Binder
::bind(
105 ty
::OutlivesPredicate(ty1
, region2
)
108 UnpackedKind
::Lifetime(region1
) => {
109 Some(ty
::Predicate
::RegionOutlives(
110 ty
::Binder
::bind(ty
::OutlivesPredicate(region1
, region2
))
113 UnpackedKind
::Const(_
) => {
114 // Generic consts don't impose any constraints.
119 (def_id
, &*predicates
)
122 tcx
.arena
.alloc(ty
::CratePredicatesMap
{