Skip to content

Commit ebf0c83

Browse files
committed
Merge pull request #26829 from nikomatsakis/better-object-defaults-warn-beta
Better object defaults warn beta
2 parents 18adf62 + b229195 commit ebf0c83

30 files changed

+481
-90
lines changed

src/librustc/diagnostics.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,42 @@ static mut FOO: Option<Box<usize>> = None;
995995
// error: mutable statics are not allowed to have destructors
996996
static mut BAR: Option<Vec<i32>> = None;
997997
```
998+
"##,
999+
1000+
E0398: r##"
1001+
In Rust 1.3, the default object lifetime bounds are expected to
1002+
change, as described in RFC #1156 [1]. You are getting a warning
1003+
because the compiler thinks it is possible that this change will cause
1004+
a compilation error in your code. It is possible, though unlikely,
1005+
that this is a false alarm.
1006+
1007+
The heart of the change is that where `&'a Box<SomeTrait>` used to
1008+
default to `&'a Box<SomeTrait+'a>`, it now defaults to `&'a
1009+
Box<SomeTrait+'static>` (here, `SomeTrait` is the name of some trait
1010+
type). Note that the only types which are affected are references to
1011+
boxes, like `&Box<SomeTrait>` or `&[Box<SomeTrait>]`. More common
1012+
types like `&SomeTrait` or `Box<SomeTrait>` are unaffected.
1013+
1014+
To silence this warning, edit your code to use an explicit bound.
1015+
Most of the time, this means that you will want to change the
1016+
signature of a function that you are calling. For example, if
1017+
the error is reported on a call like `foo(x)`, and `foo` is
1018+
defined as follows:
1019+
1020+
```
1021+
fn foo(arg: &Box<SomeTrait>) { ... }
1022+
```
1023+
1024+
you might change it to:
1025+
1026+
```
1027+
fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
1028+
```
1029+
1030+
This explicitly states that you expect the trait object `SomeTrait` to
1031+
contain references (with a maximum lifetime of `'a`).
1032+
1033+
[1]: https://github.com/rust-lang/rfcs/pull/1156
9981034
"##
9991035

10001036
}

src/librustc/metadata/tydecode.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -843,15 +843,15 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
843843

844844
fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
845845
conv: &mut F)
846-
-> Option<ty::ObjectLifetimeDefault>
846+
-> ty::ObjectLifetimeDefault
847847
where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
848848
{
849849
match next(st) {
850-
'n' => None,
851-
'a' => Some(ty::ObjectLifetimeDefault::Ambiguous),
850+
'a' => ty::ObjectLifetimeDefault::Ambiguous,
851+
'b' => ty::ObjectLifetimeDefault::BaseDefault,
852852
's' => {
853853
let region = parse_region_(st, conv);
854-
Some(ty::ObjectLifetimeDefault::Specific(region))
854+
ty::ObjectLifetimeDefault::Specific(region)
855855
}
856856
_ => panic!("parse_object_lifetime_default: bad input")
857857
}
@@ -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: 6 additions & 4 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,
@@ -414,12 +416,12 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
414416

415417
fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
416418
cx: &ctxt<'a, 'tcx>,
417-
default: Option<ty::ObjectLifetimeDefault>)
419+
default: ty::ObjectLifetimeDefault)
418420
{
419421
match default {
420-
None => mywrite!(w, "n"),
421-
Some(ty::ObjectLifetimeDefault::Ambiguous) => mywrite!(w, "a"),
422-
Some(ty::ObjectLifetimeDefault::Specific(r)) => {
422+
ty::ObjectLifetimeDefault::Ambiguous => mywrite!(w, "a"),
423+
ty::ObjectLifetimeDefault::BaseDefault => mywrite!(w, "b"),
424+
ty::ObjectLifetimeDefault::Specific(r) => {
423425
mywrite!(w, "s");
424426
enc_region(w, cx, r);
425427
}

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,

0 commit comments

Comments
 (0)