Skip to content

Commit 1922041

Browse files
committed
change coercion to use target region if not LUB
1 parent 24bb607 commit 1922041

18 files changed

+53
-56
lines changed

src/librustc_typeck/check/coercion.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
166166
return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);
167167
}
168168

169-
ty::TyRef(_, mt_b) => {
170-
return self.coerce_borrowed_pointer(exprs, a, b, mt_b.mutbl);
169+
ty::TyRef(r_b, mt_b) => {
170+
return self.coerce_borrowed_pointer(exprs, a, b, r_b, mt_b.mutbl);
171171
}
172172

173173
_ => {}
@@ -199,6 +199,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
199199
exprs: &E,
200200
a: Ty<'tcx>,
201201
b: Ty<'tcx>,
202+
r_b: &'tcx ty::Region,
202203
mutbl_b: hir::Mutability)
203204
-> CoerceResult<'tcx>
204205
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
@@ -213,17 +214,28 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
213214
// to type check, we will construct the type that `&M*expr` would
214215
// yield.
215216

216-
match a.sty {
217-
ty::TyRef(_, mt_a) => {
217+
let (_r_a, _mutbl_a) = match a.sty {
218+
ty::TyRef(r_a, mt_a) => {
218219
try!(coerce_mutbls(mt_a.mutbl, mutbl_b));
220+
(r_a, mt_a.mutbl)
219221
}
220222
_ => return self.unify(a, b)
221-
}
223+
};
222224

223225
let span = self.origin.span();
224226
let coercion = Coercion(span);
225-
let r_borrow = self.fcx.infcx().next_region_var(coercion);
226-
let r_borrow = self.tcx().mk_region(r_borrow);
227+
let r_borrow = {
228+
// If are coercing from `&'a T` to `&'b U`, then we want to
229+
// reborrow the contents of `'a` for the lifetime `'b`
230+
// (which ought to be a sublifetime of `'a`).
231+
if !self.use_lub {
232+
r_b
233+
} else {
234+
// With LUB, we need more flexibility.
235+
let r_borrow = self.fcx.infcx().next_region_var(coercion);
236+
self.tcx().mk_region(r_borrow)
237+
}
238+
};
227239
let autoref = Some(AutoPtr(r_borrow, mutbl_b));
228240

229241
let lvalue_pref = LvaluePreference::from_mutbl(mutbl_b);

src/test/compile-fail/issue-10291.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
fn test<'x>(x: &'x isize) {
1212
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
1313
drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
14-
x
15-
//~^ ERROR cannot infer an appropriate lifetime
14+
x //~ ERROR E0312
1615
}));
1716
}
1817

src/test/compile-fail/issue-7573.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ impl CrateId {
2424
}
2525

2626
pub fn remove_package_from_database() {
27-
let mut lines_to_use: Vec<&CrateId> = Vec::new();
27+
let mut lines_to_use: Vec<&CrateId> = Vec::new(); //~ ERROR E0495
2828
let push_id = |installed_id: &CrateId| {
2929
lines_to_use.push(installed_id);
30-
//~^ ERROR cannot infer an appropriate lifetime for automatic coercion due to
31-
// conflicting requirements
3230
};
3331
list_database(push_id);
3432

src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ use std::marker::PhantomData;
1414

1515
struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> }
1616
fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) {
17-
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
17+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'a>(x: &'a Bar) -> (&'a i32, &'a i32, &'a i32)
1818
(x.bar, &x.baz, &x.baz)
19-
//~^ ERROR: cannot infer
20-
//~^^ ERROR: cannot infer
21-
//~^^^ ERROR: cannot infer
19+
//~^ ERROR E0312
20+
//~| ERROR cannot infer
21+
//~| ERROR cannot infer
2222
}
2323

2424
fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&'a i32, &'a i32, &'a i32) {
25-
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'c>(x: &'a Bar<'a, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
25+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'b, 'c>(x: &'a Bar<'a, 'b, 'c>) -> (&'a i32, &'a i32, &'a i32)
2626
(x.bar, &x.baz, &x.baz)
27-
//~^ ERROR: cannot infer
28-
//~^^ ERROR: cannot infer
29-
//~^^^ ERROR: cannot infer
27+
//~^ ERROR E0312
28+
//~| ERROR cannot infer
29+
//~| ERROR cannot infer
3030
}
3131

3232
fn main() { }

src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ struct Cat<'x, T> { cat: &'x isize, t: T }
3939
struct Dog<'y> { dog: &'y isize }
4040

4141
fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x isize {
42-
//~^ HELP: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x isize
43-
x.t.dog //~ ERROR: cannot infer
42+
x.t.dog //~ ERROR E0312
4443
}
4544

4645
struct Baz<'x> {
@@ -49,11 +48,8 @@ struct Baz<'x> {
4948

5049
impl<'a> Baz<'a> {
5150
fn baz2<'b>(&self, x: &isize) -> (&'b isize, &'b isize) {
52-
//~^ HELP: parameter as shown: fn baz2<'b>(&self, x: &'b isize) -> (&'a isize, &'a isize)
53-
// The lifetime that gets assigned to `x` seems somewhat random.
54-
// I have disabled this test for the time being. --pcwalton
55-
(self.bar, x) //~ ERROR: cannot infer
56-
//~^ ERROR: cannot infer
51+
(self.bar, x) //~ ERROR E0312
52+
//~^ ERROR E0312
5753
}
5854
}
5955

src/test/compile-fail/lub-if.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
3535
"(none)"
3636
} else {
3737
let s: &'a str = maybestr.as_ref().unwrap();
38-
s //~ ERROR cannot infer an appropriate lifetime for automatic coercion due to conflicting
38+
s //~ ERROR E0312
3939
}
4040
}
4141

4242
pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
4343
if maybestr.is_some() {
4444
let s: &'a str = maybestr.as_ref().unwrap();
45-
s //~ ERROR cannot infer an appropriate lifetime for automatic coercion due to conflicting
45+
s //~ ERROR E0312
4646
} else {
4747
"(none)"
4848
}

src/test/compile-fail/lub-match.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
3737
None => "(none)",
3838
Some(ref s) => {
3939
let s: &'a str = s;
40-
s
41-
//~^ ERROR cannot infer an appropriate lifetime
40+
s //~ ERROR E0312
4241
}
4342
}
4443
}
@@ -47,8 +46,7 @@ pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
4746
match *maybestr {
4847
Some(ref s) => {
4948
let s: &'a str = s;
50-
s
51-
//~^ ERROR cannot infer an appropriate lifetime
49+
s //~ ERROR E0312
5250
}
5351
None => "(none)",
5452
}

src/test/compile-fail/object-lifetime-default-mybox.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
3434
b: &'b MyBox<SomeTrait>)
3535
-> &'b MyBox<SomeTrait>
3636
{
37-
a
38-
//~^ ERROR cannot infer
37+
a //~ ERROR E0312
3938
}
4039

4140
fn load2<'a>(ss: &MyBox<SomeTrait+'a>) -> MyBox<SomeTrait+'a> {

src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a {
1515

1616
fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
1717
// Illegal now because there is no `'b:'a` declaration.
18-
*x = *y; //~ ERROR cannot infer
18+
*x = *y; //~ ERROR E0312
1919
}
2020

2121
fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {

src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where
1616

1717
fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
1818
// Illegal now because there is no `'b:'a` declaration.
19-
*x = *y; //~ ERROR cannot infer
20-
*z = *y; //~ ERROR cannot infer
19+
*x = *y; //~ ERROR E0312
20+
*z = *y; //~ ERROR E0312
2121
}
2222

2323
fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {

src/test/compile-fail/regions-early-bound-error-method.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ impl<'a> GetRef<'a> for Box<'a> {
2828
impl<'a> Box<'a> {
2929
fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
3030
g2.get()
31-
//~^ ERROR cannot infer an appropriate lifetime for automatic coercion due to
32-
//~| ERROR mismatched types
31+
//~^ ERROR mismatched types
3332
//~| expected `&'a isize`
3433
//~| found `&'b isize`
3534
//~| lifetime mismatch

src/test/compile-fail/regions-early-bound-error.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@ impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> {
2727

2828
fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
2929
g1.get()
30-
//~^ ERROR cannot infer an appropriate lifetime for automatic coercion due to
31-
//~| ERROR mismatched types
32-
//~| expected `&'b isize`
33-
//~| found `&'a isize`
34-
//~| lifetime mismatch
30+
//~^ ERROR mismatched types
3531
}
3632

3733
fn main() {

src/test/compile-fail/regions-glb-free-free.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ mod argparse {
2222

2323
impl<'a> Flag<'a> {
2424
pub fn set_desc(self, s: &str) -> Flag<'a> {
25-
Flag {
25+
Flag { //~ ERROR cannot infer
2626
name: self.name,
27-
desc: s, //~ ERROR cannot infer an appropriate lifetime for automatic coercion due t
27+
desc: s,
2828
max_count: self.max_count,
2929
value: self.value
3030
}

src/test/compile-fail/regions-lifetime-bounds-on-fns.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) {
1515

1616
fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
1717
// Illegal now because there is no `'b:'a` declaration.
18-
*x = *y; //~ ERROR cannot infer
18+
*x = *y; //~ ERROR E0312
1919
}
2020

2121
fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
2222
// Here we try to call `foo` but do not know that `'a` and `'b` are
2323
// related as required.
24-
a(x, y); //~ ERROR cannot infer
24+
a(x, y); //~ ERROR E0495
2525
}
2626

2727
fn d() {

src/test/compile-fail/regions-nested-fns.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ fn ignore<T>(t: T) {}
1414

1515
fn nested<'x>(x: &'x isize) {
1616
let y = 3;
17-
let mut ay = &y;
17+
let mut ay = &y; //~ ERROR E0495
1818

1919
ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
20-
ay = x; //~ ERROR cannot infer
20+
ay = x;
2121
ay = &y;
2222
ay = z;
2323
}));
2424

2525
ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
26-
if false { return x; } //~ ERROR cannot infer an appropriate lifetime for automatic
26+
if false { return x; } //~ ERROR E0312
2727
if false { return ay; }
2828
return z;
2929
}));

src/test/compile-fail/regions-static-bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn static_id<'a,'b>(t: &'a ()) -> &'static ()
1313
fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
1414
where 'a: 'b, 'b: 'static { t }
1515
fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
16-
t //~ ERROR cannot infer an appropriate lifetime
16+
t //~ ERROR E0312
1717
}
1818

1919
fn error(u: &(), v: &()) {

src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ fn doit<T,F>(val: T, f: &F)
2424

2525
pub fn main() {
2626
doit(0, &|x, y| {
27-
x.set(y); //~ ERROR cannot infer
27+
x.set(y); //~ ERROR E0312
2828
});
2929
}

src/test/compile-fail/wf-static-method.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct Evil<'a, 'b: 'a>(Option<&'a &'b ()>);
2424
impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
2525
fn make_me() -> Self { }
2626
fn static_evil(u: &'b u32) -> &'a u32 {
27-
u //~ ERROR cannot infer an appropriate lifetime
27+
u //~ ERROR E0312
2828
}
2929
}
3030

@@ -40,7 +40,7 @@ impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
4040

4141
impl<'a, 'b> Evil<'a, 'b> {
4242
fn inherent_evil(u: &'b u32) -> &'a u32 {
43-
u //~ ERROR cannot infer an appropriate lifetime
43+
u //~ ERROR E0312
4444
}
4545
}
4646

0 commit comments

Comments
 (0)