Skip to content

Commit 6a229cb

Browse files
author
toidiu
committed
Implement inferring outlives requirements for references, structs, enum, union, and projection types. added a feature gate and tests for these scenarios.
1 parent 9afed64 commit 6a229cb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1415
-21
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ __pycache__/
8383
/src/libstd_unicode/UnicodeData.txt
8484
/stage[0-9]+/
8585
/target
86+
target/
8687
/test/
8788
/tmp/
8889
TAGS

src/librustc/dep_graph/dep_node.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ define_dep_nodes!( <'tcx>
500500
[] GenericsOfItem(DefId),
501501
[] PredicatesOfItem(DefId),
502502
[] InferredOutlivesOf(DefId),
503+
[] InferredOutlivesCrate(CrateNum),
503504
[] SuperPredicatesOfItem(DefId),
504505
[] TraitDefOfItem(DefId),
505506
[] AdtDefOfItem(DefId),

src/librustc/ich/impls_ty.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,20 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::CrateVariancesMap {
11001100
}
11011101
}
11021102

1103+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::CratePredicatesMap<'gcx> {
1104+
fn hash_stable<W: StableHasherResult>(&self,
1105+
hcx: &mut StableHashingContext<'a>,
1106+
hasher: &mut StableHasher<W>) {
1107+
let ty::CratePredicatesMap {
1108+
ref predicates,
1109+
// This is just an irrelevant helper value.
1110+
empty_predicate: _,
1111+
} = *self;
1112+
1113+
predicates.hash_stable(hcx, hasher);
1114+
}
1115+
}
1116+
11031117
impl_stable_hash_for!(struct ty::AssociatedItem {
11041118
def_id,
11051119
name,

src/librustc/ty/maps/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
155155
}
156156
}
157157

158+
impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
159+
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
160+
format!("computing the inferred outlives predicates for items in this crate")
161+
}
162+
}
163+
158164
impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
159165
fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
160166
format!("generating MIR shim for `{}`",

src/librustc/ty/maps/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ define_maps! { <'tcx>
102102
/// associated generics and predicates.
103103
[] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
104104
[] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
105+
[] fn explicit_predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
105106

106107
/// Maps from the def-id of a trait to the list of
107108
/// super-predicates. This is a subset of the full list of
@@ -139,7 +140,11 @@ define_maps! { <'tcx>
139140
[] fn variances_of: ItemVariances(DefId) -> Lrc<Vec<ty::Variance>>,
140141

141142
/// Maps from def-id of a type to its (inferred) outlives.
142-
[] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Vec<ty::Predicate<'tcx>>,
143+
[] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,
144+
145+
/// Maps from def-id of a type to its (inferred) outlives.
146+
[] fn inferred_outlives_crate: InferredOutlivesCrate(CrateNum)
147+
-> Lrc<ty::CratePredicatesMap<'tcx>>,
143148

144149
/// Maps from an impl/trait def-id to a list of the def-ids of its items
145150
[] fn associated_item_def_ids: AssociatedItemDefIds(DefId) -> Lrc<Vec<DefId>>,

src/librustc/ty/maps/plumbing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
10071007
DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
10081008
DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
10091009
DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
1010+
DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
10101011
DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
10111012
DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
10121013
DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }

src/librustc/ty/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,22 @@ pub enum Predicate<'tcx> {
956956
ConstEvaluatable(DefId, &'tcx Substs<'tcx>),
957957
}
958958

959+
/// The crate outlives map is computed during typeck and contains the
960+
/// outlives of every item in the local crate. You should not use it
961+
/// directly, because to do so will make your pass dependent on the
962+
/// HIR of every item in the local crate. Instead, use
963+
/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
964+
/// item.
965+
pub struct CratePredicatesMap<'tcx> {
966+
/// For each struct with outlive bounds, maps to a vector of the
967+
/// predicate of its outlive bounds. If an item has no outlives
968+
/// bounds, it will have no entry.
969+
pub predicates: FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,
970+
971+
/// An empty vector, useful for cloning.
972+
pub empty_predicate: Lrc<Vec<ty::Predicate<'tcx>>>,
973+
}
974+
959975
impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
960976
fn as_ref(&self) -> &Predicate<'tcx> {
961977
self

src/librustc_typeck/collect.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub fn provide(providers: &mut Providers) {
6464
type_of,
6565
generics_of,
6666
predicates_of,
67+
explicit_predicates_of,
6768
super_predicates_of,
6869
type_param_predicates,
6970
trait_def,
@@ -1296,13 +1297,17 @@ fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12961297
def_id: DefId)
12971298
-> ty::GenericPredicates<'tcx> {
12981299
let explicit = explicit_predicates_of(tcx, def_id);
1300+
let predicates = if tcx.sess.features_untracked().infer_outlives_requirements {
1301+
[&explicit.predicates[..], &tcx.inferred_outlives_of(def_id)[..]].concat()
1302+
} else { explicit.predicates };
1303+
12991304
ty::GenericPredicates {
13001305
parent: explicit.parent,
1301-
predicates: [&explicit.predicates[..], &tcx.inferred_outlives_of(def_id)[..]].concat()
1306+
predicates: predicates,
13021307
}
13031308
}
13041309

1305-
fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1310+
pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
13061311
def_id: DefId)
13071312
-> ty::GenericPredicates<'tcx> {
13081313
use rustc::hir::map::*;

src/librustc_typeck/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4840,11 +4840,11 @@ register_diagnostics! {
48404840
E0588, // packed type cannot transitively contain a `[repr(align)]` type
48414841
E0592, // duplicate definitions with name `{}`
48424842
// E0613, // Removed (merged with E0609)
4843-
E0640, // infer outlives
48444843
E0627, // yield statement outside of generator literal
48454844
E0632, // cannot provide explicit type parameters when `impl Trait` is used in
48464845
// argument position.
48474846
E0634, // type has conflicting packed representaton hints
4847+
E0640, // infer outlives requirements
48484848
E0641, // cannot cast to/from a pointer with an unknown kind
48494849
E0645, // trait aliases not finished
48504850
E0907, // type inside generator must be known in this context

src/librustc_typeck/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ This API is completely unstable and subject to change.
8282
#![feature(slice_patterns)]
8383
#![feature(slice_sort_by_cached_key)]
8484
#![feature(dyn_trait)]
85+
#![feature(underscore_lifetimes)]
8586

8687
#[macro_use] extern crate log;
8788
#[macro_use] extern crate syntax;

0 commit comments

Comments
 (0)