Skip to content

Commit 9099577

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 ef85338 commit 9099577

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
@@ -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"

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

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)