Skip to content

Commit 840e774

Browse files
committed
Add a boolean flag to ExistentialBounds tracking whether the
region-bound is expected to change in Rust 1.3, but don't use it for anything in this commit. Note that this is not a "significant" part of the type (it's not part of the formal model) so we have to normalize this away or trans starts to get confused because two equal types wind up with distinct LLVM types.
1 parent 2be6107 commit 840e774

File tree

19 files changed

+202
-39
lines changed

19 files changed

+202
-39
lines changed

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

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,

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,

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>,

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,

src/librustc/middle/infer/error_reporting.rs

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

16051606
fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
16061607
match *origin {
1607-
infer::Subtype(ref trace) => {
1608+
infer::Subtype(ref trace) |
1609+
infer::DefaultExistentialBound(ref trace) => {
16081610
let desc = match trace.origin {
16091611
infer::Misc(_) => {
16101612
"types are compatible"

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,

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,

src/librustc/middle/infer/mod.rs

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

176+
// Arose from a subtyping relation
177+
DefaultExistentialBound(TypeTrace<'tcx>),
178+
176179
// Stack-allocated closures cannot outlive innermost loop
177180
// or function so as to ensure we only require finite stack
178181
InfStackClosure(Span),
@@ -472,7 +475,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
472475
-> CombineFields<'a, 'tcx> {
473476
CombineFields {infcx: self,
474477
a_is_expected: a_is_expected,
475-
trace: trace}
478+
trace: trace,
479+
cause: None}
476480
}
477481

478482
// public so that it can be used from the rustc_driver unit tests
@@ -1125,6 +1129,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
11251129
pub fn span(&self) -> Span {
11261130
match *self {
11271131
Subtype(ref a) => a.span(),
1132+
DefaultExistentialBound(ref a) => a.span(),
11281133
InfStackClosure(a) => a,
11291134
InvokeClosure(a) => a,
11301135
DerefPointer(a) => a,

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
}

0 commit comments

Comments
 (0)