Skip to content

Commit 6c02699

Browse files
committed
For named lifetimes point only at method signature
When refering to named lifetime conflict, point only at the method's signature span instead of the entire method. When the expected and found sup and sub traces are the same, avoid redundant text.
1 parent ee06559 commit 6c02699

File tree

7 files changed

+150
-44
lines changed

7 files changed

+150
-44
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -175,25 +175,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
175175
ty::ReEarlyBound(_) |
176176
ty::ReFree(_) => {
177177
let scope = region.free_region_binding_scope(self);
178-
let prefix = match *region {
179-
ty::ReEarlyBound(ref br) => {
180-
format!("the lifetime {} as defined on", br.name)
181-
}
182-
ty::ReFree(ref fr) => {
183-
match fr.bound_region {
184-
ty::BrAnon(idx) => {
185-
format!("the anonymous lifetime #{} defined on", idx + 1)
186-
}
187-
ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
188-
_ => {
189-
format!("the lifetime {} as defined on",
190-
fr.bound_region)
191-
}
192-
}
193-
}
194-
_ => bug!()
195-
};
196-
197178
let node = self.hir.as_local_node_id(scope)
198179
.unwrap_or(DUMMY_NODE_ID);
199180
let unknown;
@@ -218,7 +199,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
218199
&unknown
219200
}
220201
};
221-
let (msg, opt_span) = explain_span(self, tag, self.hir.span(node));
202+
let (prefix, span) = match *region {
203+
ty::ReEarlyBound(ref br) => {
204+
(format!("the lifetime {} as defined on", br.name),
205+
self.sess.codemap().def_span(self.hir.span(node)))
206+
}
207+
ty::ReFree(ref fr) => {
208+
match fr.bound_region {
209+
ty::BrAnon(idx) => {
210+
(format!("the anonymous lifetime #{} defined on", idx + 1),
211+
self.hir.span(node))
212+
}
213+
ty::BrFresh(_) => ("an anonymous lifetime defined on".to_owned(),
214+
self.hir.span(node)),
215+
_ => (format!("the lifetime {} as defined on", fr.bound_region),
216+
self.sess.codemap().def_span(self.hir.span(node))),
217+
}
218+
}
219+
_ => bug!()
220+
};
221+
let (msg, opt_span) = explain_span(self, tag, span);
222222
(format!("{} {}", prefix, msg), opt_span)
223223
}
224224

@@ -1075,6 +1075,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10751075
sup_region,
10761076
"...");
10771077

1078+
match (&sup_origin, &sub_origin) {
1079+
(&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) => {
1080+
if let (Some((sup_expected, sup_found)),
1081+
Some((sub_expected, sub_found))) = (self.values_str(&sup_trace.values),
1082+
self.values_str(&sub_trace.values)) {
1083+
if sub_expected == sup_expected && sub_found == sup_found {
1084+
self.tcx.note_and_explain_region(
1085+
region_scope_tree,
1086+
&mut err,
1087+
"...but the lifetime must also be valid for ",
1088+
sub_region,
1089+
"...",
1090+
);
1091+
err.note(&format!("...so that the {}:\nexpected {}\n found {}",
1092+
sup_trace.cause.as_requirement_str(),
1093+
sup_expected.content(),
1094+
sup_found.content()));
1095+
err.emit();
1096+
return;
1097+
}
1098+
}
1099+
}
1100+
_ => {}
1101+
}
1102+
10781103
self.note_region_origin(&mut err, &sup_origin);
10791104

10801105
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
2+
--> $DIR/regions-bound-missing-bound-in-impl.rs:28:5
3+
|
4+
28 | / fn no_bound<'b:'a>(self, b: Inv<'b>) {
5+
29 | | //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
6+
30 | | }
7+
| |_____^ lifetimes do not match trait
8+
9+
error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
10+
--> $DIR/regions-bound-missing-bound-in-impl.rs:32:5
11+
|
12+
32 | / fn has_bound<'b>(self, b: Inv<'b>) {
13+
33 | | //~^ ERROR lifetime parameters or bounds on method `has_bound` do not match
14+
34 | | }
15+
| |_____^ lifetimes do not match trait
16+
17+
error[E0308]: method not compatible with trait
18+
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
19+
|
20+
36 | / fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
21+
37 | | //~^ ERROR method not compatible with trait
22+
38 | | //
23+
39 | | // Note: This is a terrible error message. It is caused
24+
... |
25+
47 | | // cases.
26+
48 | | }
27+
| |_____^ lifetime mismatch
28+
|
29+
= note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
30+
found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
31+
note: the lifetime 'c as defined on the method body at 36:5...
32+
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
33+
|
34+
36 | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 36:5
37+
--> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
38+
|
39+
36 | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
40+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
42+
error[E0276]: impl has stricter requirements than trait
43+
--> $DIR/regions-bound-missing-bound-in-impl.rs:53:5
44+
|
45+
24 | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
46+
| ------------------------------------------------------- definition of `another_bound` from trait
47+
...
48+
53 | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't`
50+
51+
error: aborting due to 4 previous errors
52+

src/test/ui/closure-expected-type/expect-region-supply-region.stderr

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,8 @@ note: the anonymous lifetime #2 defined on the body at 47:29...
4141
note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1
4242
--> $DIR/expect-region-supply-region.rs:42:1
4343
|
44-
42 | / fn expect_bound_supply_named<'x>() {
45-
43 | | let mut f: Option<&u32> = None;
46-
44 | |
47-
45 | | // Here we give a type annotation that `x` should be free. We get
48-
... |
49-
54 | | });
50-
55 | | }
51-
| |_^
44+
42 | fn expect_bound_supply_named<'x>() {
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5246

5347
error[E0308]: mismatched types
5448
--> $DIR/expect-region-supply-region.rs:47:33
@@ -61,14 +55,8 @@ error[E0308]: mismatched types
6155
note: the lifetime 'x as defined on the function body at 42:1...
6256
--> $DIR/expect-region-supply-region.rs:42:1
6357
|
64-
42 | / fn expect_bound_supply_named<'x>() {
65-
43 | | let mut f: Option<&u32> = None;
66-
44 | |
67-
45 | | // Here we give a type annotation that `x` should be free. We get
68-
... |
69-
54 | | });
70-
55 | | }
71-
| |_^
58+
42 | fn expect_bound_supply_named<'x>() {
59+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7260
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29
7361
--> $DIR/expect-region-supply-region.rs:47:29
7462
|
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::ops::Deref;
12+
trait Trait {}
13+
14+
struct Struct;
15+
16+
impl Deref for Struct {
17+
type Target = Trait;
18+
fn deref(&self) -> &Trait {
19+
unimplemented!();
20+
}
21+
}
22+
//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0601]: main function not found
2+
3+
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
4+
--> $DIR/mismatched_trait_impl-2.rs:18:5
5+
|
6+
18 | / fn deref(&self) -> &Trait {
7+
19 | | unimplemented!();
8+
20 | | }
9+
| |_____^
10+
|
11+
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 18:5...
12+
--> $DIR/mismatched_trait_impl-2.rs:18:5
13+
|
14+
18 | / fn deref(&self) -> &Trait {
15+
19 | | unimplemented!();
16+
20 | | }
17+
| |_____^
18+
= note: ...but the lifetime must also be valid for the static lifetime...
19+
= note: ...so that the method type is compatible with trait:
20+
expected fn(&Struct) -> &Trait + 'static
21+
found fn(&Struct) -> &Trait
22+
23+
error: aborting due to 2 previous errors
24+

src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th
1313
20 | | x
1414
21 | | }
1515
| |_____^
16-
= note: ...so that the method type is compatible with trait:
17-
expected fn(&i32, &'a u32, &u32) -> &'a u32
18-
found fn(&i32, &u32, &u32) -> &u32
19-
note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5...
16+
note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 19:5...
2017
--> $DIR/mismatched_trait_impl.rs:19:5
2118
|
22-
19 | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
23-
20 | | x
24-
21 | | }
25-
| |_____^
19+
19 | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2621
= note: ...so that the method type is compatible with trait:
2722
expected fn(&i32, &'a u32, &u32) -> &'a u32
2823
found fn(&i32, &u32, &u32) -> &u32

0 commit comments

Comments
 (0)