Skip to content

Commit 7d20cc7

Browse files
committed
---
yaml --- r: 235117 b: refs/heads/stable c: 9099577 h: refs/heads/master i: 235115: 9cc6ac9 v: v3
1 parent 92da4a1 commit 7d20cc7

File tree

20 files changed

+203
-40
lines changed

20 files changed

+203
-40
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: ef85338175cb322fa07846d20eec91c2800a98e6
32+
refs/heads/stable: 909957793e7008e602079e8fd4c74c9bbda37341
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc/metadata/tydecode.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,9 +887,16 @@ fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
887887
}
888888
}
889889

890+
let region_bound_will_change = match next(st) {
891+
'y' => true,
892+
'n' => false,
893+
c => panic!("parse_ty: expected y/n not '{}'", c)
894+
};
895+
890896
return ty::ExistentialBounds { region_bound: region_bound,
891897
builtin_bounds: builtin_bounds,
892-
projection_bounds: projection_bounds };
898+
projection_bounds: projection_bounds,
899+
region_bound_will_change: region_bound_will_change };
893900
}
894901

895902
fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where

branches/stable/src/librustc/metadata/tyencode.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,8 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
390390
}
391391

392392
mywrite!(w, ".");
393+
394+
mywrite!(w, "{}", if bs.region_bound_will_change {'y'} else {'n'});
393395
}
394396

395397
pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,

branches/stable/src/librustc/middle/infer/bivariate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
4949

5050
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
5151

52+
fn will_change(&mut self, _: bool, _: bool) -> bool {
53+
// since we are not comparing regions, we don't care
54+
false
55+
}
56+
5257
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
5358
variance: ty::Variance,
5459
a: &T,

branches/stable/src/librustc/middle/infer/combine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub struct CombineFields<'a, 'tcx: 'a> {
5656
pub infcx: &'a InferCtxt<'a, 'tcx>,
5757
pub a_is_expected: bool,
5858
pub trace: TypeTrace<'tcx>,
59+
pub cause: Option<ty_relate::Cause>,
5960
}
6061

6162
pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,

branches/stable/src/librustc/middle/infer/equate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
3434

3535
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
3636

37+
fn will_change(&mut self, a: bool, b: bool) -> bool {
38+
// if either side changed from what it was, that could cause equality to fail
39+
a || b
40+
}
41+
3742
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
3843
_: ty::Variance,
3944
a: &T,

branches/stable/src/librustc/middle/infer/error_reporting.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
593593
sub: Region,
594594
sup: Region) {
595595
match origin {
596-
infer::Subtype(trace) => {
596+
infer::Subtype(trace) |
597+
infer::DefaultExistentialBound(trace) => {
597598
let terr = ty::terr_regions_does_not_outlive(sup, sub);
598599
self.report_and_explain_type_error(trace, &terr);
599600
}
@@ -1569,7 +1570,8 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
15691570

15701571
fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
15711572
match *origin {
1572-
infer::Subtype(ref trace) => {
1573+
infer::Subtype(ref trace) |
1574+
infer::DefaultExistentialBound(ref trace) => {
15731575
let desc = match trace.origin {
15741576
infer::Misc(_) => {
15751577
"types are compatible"

branches/stable/src/librustc/middle/infer/glb.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {
3535

3636
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
3737

38+
fn will_change(&mut self, a: bool, b: bool) -> bool {
39+
// Hmm, so the result of GLB will still be a LB if one or both
40+
// sides change to 'static, but it may no longer be the GLB.
41+
// I'm going to go with `a || b` here to be conservative,
42+
// since the result of this operation may be affected, though
43+
// I think it would mostly be more accepting than before (since the result
44+
// would be a bigger region).
45+
a || b
46+
}
47+
3848
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
3949
variance: ty::Variance,
4050
a: &T,

branches/stable/src/librustc/middle/infer/lub.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {
3535

3636
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
3737

38+
fn will_change(&mut self, a: bool, b: bool) -> bool {
39+
// result will be 'static if a || b
40+
a || b
41+
}
42+
3843
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
3944
variance: ty::Variance,
4045
a: &T,

branches/stable/src/librustc/middle/infer/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ pub enum SubregionOrigin<'tcx> {
194194
// Arose from a subtyping relation
195195
Subtype(TypeTrace<'tcx>),
196196

197+
// Arose from a subtyping relation
198+
DefaultExistentialBound(TypeTrace<'tcx>),
199+
197200
// Stack-allocated closures cannot outlive innermost loop
198201
// or function so as to ensure we only require finite stack
199202
InfStackClosure(Span),
@@ -658,7 +661,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
658661
-> CombineFields<'a, 'tcx> {
659662
CombineFields {infcx: self,
660663
a_is_expected: a_is_expected,
661-
trace: trace}
664+
trace: trace,
665+
cause: None}
662666
}
663667

664668
// public so that it can be used from the rustc_driver unit tests
@@ -1464,6 +1468,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
14641468
pub fn span(&self) -> Span {
14651469
match *self {
14661470
Subtype(ref a) => a.span(),
1471+
DefaultExistentialBound(ref a) => a.span(),
14671472
InfStackClosure(a) => a,
14681473
InvokeClosure(a) => a,
14691474
DerefPointer(a) => a,

branches/stable/src/librustc/middle/infer/sub.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010

1111
use super::combine::{self, CombineFields};
1212
use super::higher_ranked::HigherRankedRelations;
13-
use super::Subtype;
13+
use super::SubregionOrigin;
1414
use super::type_variable::{SubtypeOf, SupertypeOf};
1515

1616
use middle::ty::{self, Ty};
1717
use middle::ty::TyVar;
18-
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
18+
use middle::ty_relate::{Cause, Relate, RelateResult, TypeRelation};
19+
use std::mem;
1920

2021
/// "Greatest lower bound" (common subtype)
2122
pub struct Sub<'a, 'tcx: 'a> {
22-
fields: CombineFields<'a, 'tcx>
23+
fields: CombineFields<'a, 'tcx>,
2324
}
2425

2526
impl<'a, 'tcx> Sub<'a, 'tcx> {
@@ -33,6 +34,25 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
3334
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.infcx.tcx }
3435
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
3536

37+
fn with_cause<F,R>(&mut self, cause: Cause, f: F) -> R
38+
where F: FnOnce(&mut Self) -> R
39+
{
40+
debug!("sub with_cause={:?}", cause);
41+
let old_cause = mem::replace(&mut self.fields.cause, Some(cause));
42+
let r = f(self);
43+
debug!("sub old_cause={:?}", old_cause);
44+
self.fields.cause = old_cause;
45+
r
46+
}
47+
48+
fn will_change(&mut self, a: bool, b: bool) -> bool {
49+
// if we have (Foo+'a) <: (Foo+'b), this requires that 'a:'b.
50+
// So if 'a becomes 'static, no additional errors can occur.
51+
// OTOH, if 'a stays the same, but 'b becomes 'static, we
52+
// could have a problem.
53+
!a && b
54+
}
55+
3656
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
3757
variance: ty::Variance,
3858
a: &T,
@@ -84,11 +104,14 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
84104
}
85105

86106
fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
87-
debug!("{}.regions({:?}, {:?})",
88-
self.tag(),
89-
a,
90-
b);
91-
let origin = Subtype(self.fields.trace.clone());
107+
debug!("{}.regions({:?}, {:?}) self.cause={:?}",
108+
self.tag(), a, b, self.fields.cause);
109+
let origin = match self.fields.cause {
110+
Some(Cause::ExistentialRegionBound(true)) =>
111+
SubregionOrigin::DefaultExistentialBound(self.fields.trace.clone()),
112+
_ =>
113+
SubregionOrigin::Subtype(self.fields.trace.clone()),
114+
};
92115
self.fields.infcx.region_vars.make_subregion(origin, a, b);
93116
Ok(a)
94117
}

branches/stable/src/librustc/middle/traits/select.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2445,6 +2445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24452445
region_bound: data_b.bounds.region_bound,
24462446
builtin_bounds: data_b.bounds.builtin_bounds,
24472447
projection_bounds: data_a.bounds.projection_bounds.clone(),
2448+
region_bound_will_change: data_b.bounds.region_bound_will_change,
24482449
};
24492450

24502451
let new_trait = tcx.mk_trait(data_a.principal.clone(), bounds);

branches/stable/src/librustc/middle/ty.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,11 @@ pub struct ExistentialBounds<'tcx> {
20552055
pub region_bound: ty::Region,
20562056
pub builtin_bounds: BuiltinBounds,
20572057
pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
2058+
2059+
// If true, this TyTrait used a "default bound" in the surface
2060+
// syntax. This makes no difference to the type system but is
2061+
// handy for error reporting.
2062+
pub region_bound_will_change: bool,
20582063
}
20592064

20602065
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]

branches/stable/src/librustc/middle/ty_fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,7 @@ pub fn super_fold_existential_bounds<'tcx, T: TypeFolder<'tcx>>(
728728
region_bound: bounds.region_bound.fold_with(this),
729729
builtin_bounds: bounds.builtin_bounds,
730730
projection_bounds: bounds.projection_bounds.fold_with(this),
731+
region_bound_will_change: bounds.region_bound_will_change,
731732
}
732733
}
733734

branches/stable/src/librustc/middle/ty_match.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Match<'a, 'tcx> {
4242
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.tcx }
4343
fn a_is_expected(&self) -> bool { true } // irrelevant
4444

45+
fn will_change(&mut self, _: bool, _: bool) -> bool {
46+
// we're ignoring regions in this code
47+
false
48+
}
49+
4550
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
4651
_: ty::Variance,
4752
a: &T,

branches/stable/src/librustc/middle/ty_relate/mod.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ use syntax::ast;
2222

2323
pub type RelateResult<'tcx, T> = Result<T, ty::type_err<'tcx>>;
2424

25+
#[derive(Clone, Debug)]
26+
pub enum Cause {
27+
ExistentialRegionBound(bool), // if true, this is a default, else explicit
28+
}
29+
2530
pub trait TypeRelation<'a,'tcx> : Sized {
2631
fn tcx(&self) -> &'a ty::ctxt<'tcx>;
2732

@@ -32,6 +37,19 @@ pub trait TypeRelation<'a,'tcx> : Sized {
3237
/// relation. Just affects error messages.
3338
fn a_is_expected(&self) -> bool;
3439

40+
fn with_cause<F,R>(&mut self, _cause: Cause, f: F) -> R
41+
where F: FnOnce(&mut Self) -> R
42+
{
43+
f(self)
44+
}
45+
46+
/// Hack for deciding whether the lifetime bound defaults change
47+
/// will be a breaking change or not. The bools indicate whether
48+
/// `a`/`b` have a default that will change to `'static`; the
49+
/// result is true if this will potentially affect the affect of
50+
/// relating `a` and `b`.
51+
fn will_change(&mut self, a: bool, b: bool) -> bool;
52+
3553
/// Generic relation routine suitable for most anything.
3654
fn relate<T:Relate<'a,'tcx>>(&mut self, a: &T, b: &T) -> RelateResult<'tcx, T> {
3755
Relate::relate(self, a, b)
@@ -366,14 +384,21 @@ impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ExistentialBounds<'tcx> {
366384
-> RelateResult<'tcx, ty::ExistentialBounds<'tcx>>
367385
where R: TypeRelation<'a,'tcx>
368386
{
369-
let r = try!(relation.relate_with_variance(ty::Contravariant,
370-
&a.region_bound,
371-
&b.region_bound));
387+
let will_change = relation.will_change(a.region_bound_will_change,
388+
b.region_bound_will_change);
389+
390+
let r =
391+
try!(relation.with_cause(
392+
Cause::ExistentialRegionBound(will_change),
393+
|relation| relation.relate_with_variance(ty::Contravariant,
394+
&a.region_bound,
395+
&b.region_bound)));
372396
let nb = try!(relation.relate(&a.builtin_bounds, &b.builtin_bounds));
373397
let pb = try!(relation.relate(&a.projection_bounds, &b.projection_bounds));
374398
Ok(ty::ExistentialBounds { region_bound: r,
375399
builtin_bounds: nb,
376-
projection_bounds: pb })
400+
projection_bounds: pb,
401+
region_bound_will_change: will_change })
377402
}
378403
}
379404

branches/stable/src/librustc/util/ppaux.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
299299
}
300300
}
301301

302+
if bounds.region_bound_will_change && tcx.sess.verbose() {
303+
components.push(format!("WILL-CHANGE"));
304+
}
305+
302306
Ok(())
303307
}
304308
}

branches/stable/src/librustc_trans/trans/common.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
8282
return t_norm;
8383
}
8484

85+
fn fold_existential_bounds(&mut self, s: &ty::ExistentialBounds<'tcx>)
86+
-> ty::ExistentialBounds<'tcx> {
87+
let mut s = ty_fold::super_fold_existential_bounds(self, s);
88+
89+
// this annoying flag messes up trans normalization
90+
s.region_bound_will_change = false;
91+
92+
s
93+
}
94+
8595
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
8696
where T : TypeFoldable<'tcx>
8797
{

0 commit comments

Comments
 (0)