1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
14 use rustc::ty::query::Providers;
15 use rustc::ty::subst::UnpackedKind;
16 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
17 use rustc_data_structures::sync::Lrc;
21 /// Code to write unit test for outlives.
25 pub fn provide(providers: &mut Providers) {
26 *providers = Providers {
28 inferred_outlives_crate,
33 fn inferred_outlives_of<'a, 'tcx>(
34 tcx: TyCtxt<'a, 'tcx, 'tcx>,
36 ) -> Lrc<Vec<ty::Predicate<'tcx>>> {
39 .as_local_node_id(item_def_id)
40 .expect("expected local def-id");
42 match tcx.hir.get(id) {
43 Node::Item(item) => match item.node {
44 hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
45 let crate_map = tcx.inferred_outlives_crate(LOCAL_CRATE);
47 let predicates = crate_map
50 .unwrap_or(&crate_map.empty_predicate)
53 if tcx.has_attr(item_def_id, "rustc_outlives") {
54 let mut pred: Vec<String> = predicates
56 .map(|out_pred| match out_pred {
57 ty::Predicate::RegionOutlives(p) => p.to_string(),
58 ty::Predicate::TypeOutlives(p) => p.to_string(),
59 err => bug!("unexpected predicate {:?}", err),
63 let span = tcx.def_span(item_def_id);
64 let mut err = tcx.sess.struct_span_err(span, "rustc_outlives");
71 debug!("inferred_outlives_of({:?}) = {:?}", item_def_id, predicates);
76 _ => Lrc::new(Vec::new()),
79 _ => Lrc::new(Vec::new()),
83 fn inferred_outlives_crate<'tcx>(
84 tcx: TyCtxt<'_, 'tcx, 'tcx>,
86 ) -> Lrc<CratePredicatesMap<'tcx>> {
87 assert_eq!(crate_num, LOCAL_CRATE);
89 // Compute a map from each struct/enum/union S to the **explicit**
90 // outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote.
91 // Typically there won't be many of these, except in older code where
92 // they were mandatory. Nonetheless, we have to ensure that every such
93 // predicate is satisfied, so they form a kind of base set of requirements
96 // Compute the inferred predicates
97 let mut exp_map = explicit::ExplicitPredicatesMap::new();
99 let global_inferred_outlives = implicit_infer::infer_predicates(tcx, &mut exp_map);
101 // Convert the inferred predicates into the "collected" form the
102 // global data structure expects.
104 // FIXME -- consider correcting impedance mismatch in some way,
105 // probably by updating the global data structure.
106 let predicates = global_inferred_outlives
108 .map(|(&def_id, set)| {
109 let vec: Vec<ty::Predicate<'tcx>> = set
112 |ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
113 UnpackedKind::Type(ty1) => ty::Predicate::TypeOutlives(ty::Binder::bind(
114 ty::OutlivesPredicate(ty1, region2),
116 UnpackedKind::Lifetime(region1) => ty::Predicate::RegionOutlives(
117 ty::Binder::bind(ty::OutlivesPredicate(region1, region2)),
121 (def_id, Lrc::new(vec))
124 let empty_predicate = Lrc::new(Vec::new());
126 Lrc::new(ty::CratePredicatesMap {