Skip to content

Commit abe1cef

Browse files
committed
---
yaml --- r: 181626 b: refs/heads/snap-stage3 c: 2939e48 h: refs/heads/master v: v3
1 parent 9e00f06 commit abe1cef

File tree

13 files changed

+528
-133
lines changed

13 files changed

+528
-133
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 6c065fc8cb036785f61ff03e05c1563cbb2dd081
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 5511add74205d8547f98959b01e5053be2395723
4+
refs/heads/snap-stage3: 2939e483fd8a32d330c837725513b493fd457dc3
55
refs/heads/try: ccf8fedf1cffcb8f6f3581d53d220039e192fe77
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d

branches/snap-stage3/src/librustc/middle/infer/unify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ impl<K:UnifyKey> UnificationTable<K> {
212212
}
213213
}
214214

215-
impl<K> sv::SnapshotVecDelegate for Delegate<K> {
215+
impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
216216
type Value = VarValue<K>;
217217
type Undo = ();
218218

branches/snap-stage3/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector};
1616
use borrowck::move_data::*;
1717
use rustc::middle::expr_use_visitor as euv;
1818
use rustc::middle::mem_categorization as mc;
19-
use rustc::middle::mem_categorization::Typer;
2019
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
2120
use rustc::middle::ty;
2221
use rustc::util::ppaux::Repr;

branches/snap-stage3/src/librustc_borrowck/borrowck/gather_loans/move_error.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
use borrowck::BorrowckCtxt;
1212
use rustc::middle::mem_categorization as mc;
13-
use rustc::middle::mem_categorization::Typer;
1413
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
1514
use rustc::middle::ty;
1615
use rustc::util::ppaux::UserString;

branches/snap-stage3/src/librustc_typeck/check/implicator.rs

Lines changed: 160 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,73 @@
1111
// #![warn(deprecated_mode)]
1212

1313
use astconv::object_region_bounds;
14-
use middle::infer::GenericKind;
15-
use middle::subst::{ParamSpace, Subst, Substs};
16-
use middle::ty::{self, Ty};
17-
use middle::ty_fold::{TypeFolder};
14+
use middle::infer::{InferCtxt, GenericKind};
15+
use middle::subst::{Substs};
16+
use middle::traits;
17+
use middle::ty::{self, ToPolyTraitRef, Ty};
18+
use middle::ty_fold::{TypeFoldable, TypeFolder};
1819

20+
use std::rc::Rc;
1921
use syntax::ast;
22+
use syntax::codemap::Span;
2023

24+
use util::common::ErrorReported;
2125
use util::ppaux::Repr;
2226

2327
// Helper functions related to manipulating region types.
2428

2529
pub enum Implication<'tcx> {
2630
RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
2731
RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
32+
Predicate(ast::DefId, ty::Predicate<'tcx>),
2833
}
2934

3035
struct Implicator<'a, 'tcx: 'a> {
31-
tcx: &'a ty::ctxt<'tcx>,
36+
infcx: &'a InferCtxt<'a,'tcx>,
37+
closure_typer: &'a (ty::ClosureTyper<'tcx>+'a),
38+
body_id: ast::NodeId,
3239
stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
40+
span: Span,
3341
out: Vec<Implication<'tcx>>,
3442
}
3543

3644
/// This routine computes the well-formedness constraints that must hold for the type `ty` to
3745
/// appear in a context with lifetime `outer_region`
38-
pub fn implications<'tcx>(
39-
tcx: &ty::ctxt<'tcx>,
46+
pub fn implications<'a,'tcx>(
47+
infcx: &'a InferCtxt<'a,'tcx>,
48+
closure_typer: &ty::ClosureTyper<'tcx>,
49+
body_id: ast::NodeId,
4050
ty: Ty<'tcx>,
41-
outer_region: ty::Region)
51+
outer_region: ty::Region,
52+
span: Span)
4253
-> Vec<Implication<'tcx>>
4354
{
55+
debug!("implications(body_id={}, ty={}, outer_region={})",
56+
body_id,
57+
ty.repr(closure_typer.tcx()),
58+
outer_region.repr(closure_typer.tcx()));
59+
4460
let mut stack = Vec::new();
4561
stack.push((outer_region, None));
46-
let mut wf = Implicator { tcx: tcx,
47-
stack: stack,
48-
out: Vec::new() };
62+
let mut wf = Implicator { closure_typer: closure_typer,
63+
infcx: infcx,
64+
body_id: body_id,
65+
span: span,
66+
stack: stack,
67+
out: Vec::new() };
4968
wf.accumulate_from_ty(ty);
69+
debug!("implications: out={}", wf.out.repr(closure_typer.tcx()));
5070
wf.out
5171
}
5272

5373
impl<'a, 'tcx> Implicator<'a, 'tcx> {
74+
fn tcx(&self) -> &'a ty::ctxt<'tcx> {
75+
self.infcx.tcx
76+
}
77+
5478
fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
5579
debug!("accumulate_from_ty(ty={})",
56-
ty.repr(self.tcx));
80+
ty.repr(self.tcx()));
5781

5882
match ty.sty {
5983
ty::ty_bool |
@@ -94,13 +118,13 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
94118

95119
ty::ty_trait(ref t) => {
96120
let required_region_bounds =
97-
object_region_bounds(self.tcx, &t.principal, t.bounds.builtin_bounds);
121+
object_region_bounds(self.tcx(), &t.principal, t.bounds.builtin_bounds);
98122
self.accumulate_from_object_ty(ty, t.bounds.region_bound, required_region_bounds)
99123
}
100124

101125
ty::ty_enum(def_id, substs) |
102126
ty::ty_struct(def_id, substs) => {
103-
let item_scheme = ty::lookup_item_type(self.tcx, def_id);
127+
let item_scheme = ty::lookup_item_type(self.tcx(), def_id);
104128
self.accumulate_from_adt(ty, def_id, &item_scheme.generics, substs)
105129
}
106130

@@ -139,9 +163,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
139163
}
140164

141165
ty::ty_open(_) => {
142-
self.tcx.sess.bug(
166+
self.tcx().sess.bug(
143167
&format!("Unexpected type encountered while doing wf check: {}",
144-
ty.repr(self.tcx))[]);
168+
ty.repr(self.tcx()))[]);
145169
}
146170
}
147171
}
@@ -225,103 +249,113 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
225249
fn accumulate_from_adt(&mut self,
226250
ty: Ty<'tcx>,
227251
def_id: ast::DefId,
228-
generics: &ty::Generics<'tcx>,
252+
_generics: &ty::Generics<'tcx>,
229253
substs: &Substs<'tcx>)
230254
{
231-
// The generic declarations from the type, appropriately
232-
// substituted for the actual substitutions.
233-
let generics = generics.subst(self.tcx, substs);
234-
235-
// Variance of each type/region parameter.
236-
let variances = ty::item_variances(self.tcx, def_id);
237-
238-
for &space in &ParamSpace::all() {
239-
let region_params = substs.regions().get_slice(space);
240-
let region_variances = variances.regions.get_slice(space);
241-
let region_param_defs = generics.regions.get_slice(space);
242-
assert_eq!(region_params.len(), region_variances.len());
243-
for (&region_param, (&region_variance, region_param_def)) in
244-
region_params.iter().zip(
245-
region_variances.iter().zip(
246-
region_param_defs.iter()))
247-
{
248-
match region_variance {
249-
ty::Covariant | ty::Bivariant => {
250-
// Ignore covariant or bivariant region
251-
// parameters. To understand why, consider a
252-
// struct `Foo<'a>`. If `Foo` contains any
253-
// references with lifetime `'a`, then `'a` must
254-
// be at least contravariant (and possibly
255-
// invariant). The only way to have a covariant
256-
// result is if `Foo` contains only a field with a
257-
// type like `fn() -> &'a T`; i.e., a bare
258-
// function that can produce a reference of
259-
// lifetime `'a`. In this case, there is no
260-
// *actual data* with lifetime `'a` that is
261-
// reachable. (Presumably this bare function is
262-
// really returning static data.)
263-
}
264-
265-
ty::Contravariant | ty::Invariant => {
266-
// If the parameter is contravariant or
267-
// invariant, there may indeed be reachable
268-
// data with this lifetime. See other case for
269-
// more details.
270-
self.push_region_constraint_from_top(region_param);
255+
let predicates =
256+
ty::lookup_predicates(self.tcx(), def_id).instantiate(self.tcx(), substs);
257+
let predicates = match self.fully_normalize(&predicates) {
258+
Ok(predicates) => predicates,
259+
Err(ErrorReported) => { return; }
260+
};
261+
262+
for predicate in predicates.predicates.as_slice() {
263+
match *predicate {
264+
ty::Predicate::Trait(ref data) => {
265+
self.accumulate_from_assoc_types_transitive(data);
266+
}
267+
ty::Predicate::Equate(..) => { }
268+
ty::Predicate::Projection(..) => { }
269+
ty::Predicate::RegionOutlives(ref data) => {
270+
match ty::no_late_bound_regions(self.tcx(), data) {
271+
None => { }
272+
Some(ty::OutlivesPredicate(r_a, r_b)) => {
273+
self.push_sub_region_constraint(Some(ty), r_b, r_a);
274+
}
271275
}
272276
}
273-
274-
for &region_bound in &region_param_def.bounds {
275-
// The type declared a constraint like
276-
//
277-
// 'b : 'a
278-
//
279-
// which means that `'a <= 'b` (after
280-
// substitution). So take the region we
281-
// substituted for `'a` (`region_bound`) and make
282-
// it a subregion of the region we substituted
283-
// `'b` (`region_param`).
284-
self.push_sub_region_constraint(
285-
Some(ty), region_bound, region_param);
277+
ty::Predicate::TypeOutlives(ref data) => {
278+
match ty::no_late_bound_regions(self.tcx(), data) {
279+
None => { }
280+
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
281+
self.stack.push((r_b, Some(ty)));
282+
self.accumulate_from_ty(ty_a);
283+
self.stack.pop().unwrap();
284+
}
285+
}
286286
}
287287
}
288+
}
288289

289-
let types = substs.types.get_slice(space);
290-
let type_variances = variances.types.get_slice(space);
291-
let type_param_defs = generics.types.get_slice(space);
292-
assert_eq!(types.len(), type_variances.len());
293-
for (&type_param_ty, (&variance, type_param_def)) in
294-
types.iter().zip(
295-
type_variances.iter().zip(
296-
type_param_defs.iter()))
297-
{
298-
debug!("type_param_ty={} variance={}",
299-
type_param_ty.repr(self.tcx),
300-
variance.repr(self.tcx));
301-
302-
match variance {
303-
ty::Contravariant | ty::Bivariant => {
304-
// As above, except that in this it is a
305-
// *contravariant* reference that indices that no
306-
// actual data of type T is reachable.
307-
}
290+
let obligations = predicates.predicates
291+
.into_iter()
292+
.map(|pred| Implication::Predicate(def_id, pred));
293+
self.out.extend(obligations);
308294

309-
ty::Covariant | ty::Invariant => {
310-
self.accumulate_from_ty(type_param_ty);
311-
}
295+
let variances = ty::item_variances(self.tcx(), def_id);
296+
297+
for (&region, &variance) in substs.regions().iter().zip(variances.regions.iter()) {
298+
match variance {
299+
ty::Contravariant | ty::Invariant => {
300+
// If any data with this lifetime is reachable
301+
// within, it must be at least contravariant.
302+
self.push_region_constraint_from_top(region)
312303
}
304+
ty::Covariant | ty::Bivariant => { }
305+
}
306+
}
313307

314-
// Inspect bounds on this type parameter for any
315-
// region bounds.
316-
for &r in &type_param_def.bounds.region_bounds {
317-
self.stack.push((r, Some(ty)));
318-
self.accumulate_from_ty(type_param_ty);
319-
self.stack.pop().unwrap();
308+
for (&ty, &variance) in substs.types.iter().zip(variances.types.iter()) {
309+
match variance {
310+
ty::Covariant | ty::Invariant => {
311+
// If any data of this type is reachable within,
312+
// it must be at least covariant.
313+
self.accumulate_from_ty(ty);
320314
}
315+
ty::Contravariant | ty::Bivariant => { }
321316
}
322317
}
323318
}
324319

320+
/// Given that there is a requirement that `Foo<X> : 'a`, where
321+
/// `Foo` is declared like `struct Foo<T> where T : SomeTrait`,
322+
/// this code finds all the associated types defined in
323+
/// `SomeTrait` (and supertraits) and adds a requirement that `<X
324+
/// as SomeTrait>::N : 'a` (where `N` is some associated type
325+
/// defined in `SomeTrait`). This rule only applies to
326+
/// trait-bounds that are not higher-ranked, because we cannot
327+
/// project out of a HRTB. This rule helps code using associated
328+
/// types to compile, see Issue #22246 for an example.
329+
fn accumulate_from_assoc_types_transitive(&mut self,
330+
data: &ty::PolyTraitPredicate<'tcx>)
331+
{
332+
for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
333+
match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) {
334+
Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
335+
None => { }
336+
}
337+
}
338+
}
339+
340+
fn accumulate_from_assoc_types(&mut self,
341+
trait_ref: Rc<ty::TraitRef<'tcx>>)
342+
{
343+
let trait_def_id = trait_ref.def_id;
344+
let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
345+
let assoc_type_projections: Vec<_> =
346+
trait_def.associated_type_names
347+
.iter()
348+
.map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name))
349+
.collect();
350+
let tys = match self.fully_normalize(&assoc_type_projections) {
351+
Ok(tys) => { tys }
352+
Err(ErrorReported) => { return; }
353+
};
354+
for ty in tys {
355+
self.accumulate_from_ty(ty);
356+
}
357+
}
358+
325359
fn accumulate_from_object_ty(&mut self,
326360
ty: Ty<'tcx>,
327361
region_bound: ty::Region,
@@ -373,6 +407,28 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
373407
self.out.push(Implication::RegionSubRegion(Some(ty), r_d, r_c));
374408
}
375409
}
410+
411+
fn fully_normalize<T>(&self, value: &T) -> Result<T,ErrorReported>
412+
where T : TypeFoldable<'tcx> + ty::HasProjectionTypes + Clone + Repr<'tcx>
413+
{
414+
let value =
415+
traits::fully_normalize(self.infcx,
416+
self.closure_typer,
417+
traits::ObligationCause::misc(self.span, self.body_id),
418+
value);
419+
match value {
420+
Ok(value) => Ok(value),
421+
Err(errors) => {
422+
// I don't like reporting these errors here, but I
423+
// don't know where else to report them just now. And
424+
// I don't really expect errors to arise here
425+
// frequently. I guess the best option would be to
426+
// propagate them out.
427+
traits::report_fulfillment_errors(self.infcx, &errors);
428+
Err(ErrorReported)
429+
}
430+
}
431+
}
376432
}
377433

378434
impl<'tcx> Repr<'tcx> for Implication<'tcx> {
@@ -389,6 +445,12 @@ impl<'tcx> Repr<'tcx> for Implication<'tcx> {
389445
r.repr(tcx),
390446
p.repr(tcx))
391447
}
448+
449+
Implication::Predicate(ref def_id, ref p) => {
450+
format!("Predicate({}, {})",
451+
def_id.repr(tcx),
452+
p.repr(tcx))
453+
}
392454
}
393455
}
394456
}

0 commit comments

Comments
 (0)