Skip to content

Commit ff7dca5

Browse files
committed
Make explain borrow work for Universal lifetimes
1 parent 834e392 commit ff7dca5

14 files changed

+127
-22
lines changed

src/librustc/infer/error_reporting/mod.rs

+27-6
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
165165
);
166166
}
167167
};
168-
let message = format!("{}{}{}", prefix, description, suffix);
169-
if let Some(span) = span {
170-
err.span_note(span, &message);
171-
} else {
172-
err.note(&message);
173-
}
168+
169+
TyCtxt::emit_msg_span(err, prefix, description, span, suffix);
170+
}
171+
172+
pub fn note_and_explain_free_region(self,
173+
err: &mut DiagnosticBuilder,
174+
prefix: &str,
175+
region: ty::Region<'tcx>,
176+
suffix: &str) {
177+
let (description, span) = self.msg_span_from_free_region(region);
178+
179+
180+
TyCtxt::emit_msg_span(err, prefix, description, span, suffix);
174181
}
175182

176183
fn msg_span_from_free_region(self,
@@ -224,6 +231,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
224231
(format!("{} {}", prefix, msg), opt_span)
225232
}
226233

234+
fn emit_msg_span(err: &mut DiagnosticBuilder,
235+
prefix: &str,
236+
description: String,
237+
span: Option<Span>,
238+
suffix: &str) {
239+
let message = format!("{}{}{}", prefix, description, suffix);
240+
241+
if let Some(span) = span {
242+
err.span_note(span, &message);
243+
} else {
244+
err.note(&message);
245+
}
246+
}
247+
227248
fn item_scope_tag(item: &hir::Item) -> &'static str {
228249
match item.node {
229250
hir::ItemImpl(..) => "impl",

src/librustc_mir/borrow_check/error_reporting.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
233233
context: Context,
234234
(place, span): (&Place<'tcx>, Span),
235235
gen_borrow_kind: BorrowKind,
236-
issued_borrow: &BorrowData,
236+
issued_borrow: &BorrowData<'tcx>,
237237
end_issued_loan_span: Option<Span>,
238238
) {
239239
let issued_span = self.retrieve_borrow_span(issued_borrow);
@@ -574,7 +574,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
574574
&mut self,
575575
context: Context,
576576
(place, span): (&Place<'tcx>, Span),
577-
loan: &BorrowData,
577+
loan: &BorrowData<'tcx>,
578578
) {
579579
let mut err = self.tcx.cannot_assign_to_borrowed(
580580
span,

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
2121
pub(in borrow_check) fn explain_why_borrow_contains_point(
2222
&self,
2323
context: Context,
24-
borrow: &BorrowData<'_>,
24+
borrow: &BorrowData<'tcx>,
2525
err: &mut DiagnosticBuilder<'_>,
2626
) {
2727
if let Some(regioncx) = &self.nonlexical_regioncx {
@@ -70,6 +70,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
7070
}
7171
}
7272

73+
Cause::UniversalRegion(region_vid) => {
74+
if let Some(region) = regioncx.to_error_region(region_vid) {
75+
76+
self.tcx.note_and_explain_free_region(
77+
err,
78+
"borrowed value must be valid for ",
79+
region,
80+
"...",
81+
);
82+
}
83+
}
84+
7385
_ => {
7486
}
7587
}

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
588588
/// existentially bound, then we check its inferred value and try
589589
/// to find a good name from that. Returns `None` if we can't find
590590
/// one (e.g., this is just some random part of the CFG).
591-
fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
591+
pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
592592
if self.universal_regions.is_universal_region(r) {
593593
return self.definitions[r].external_name;
594594
} else {
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+
// compile-flags: -Znll-dump-cause
12+
13+
#![feature(nll)]
14+
#![allow(warnings)]
15+
16+
fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
17+
let v = 22;
18+
&v
19+
//~^ ERROR `v` does not live long enough [E0597]
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0597]: `v` does not live long enough
2+
--> $DIR/borrowed-universal-error-2.rs:18:5
3+
|
4+
LL | &v
5+
| ^^ borrowed value does not live long enough
6+
LL | //~^ ERROR `v` does not live long enough [E0597]
7+
LL | }
8+
| - borrowed value only lives until here
9+
|
10+
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 16:1...
11+
--> $DIR/borrowed-universal-error-2.rs:16:1
12+
|
13+
LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: aborting due to previous error
17+
18+
If you want more information on this error, try using "rustc --explain E0597"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
// compile-flags: -Znll-dump-cause
12+
13+
#![feature(nll)]
14+
#![allow(warnings)]
15+
16+
fn gimme(x: &(u32,)) -> &u32 {
17+
&x.0
18+
}
19+
20+
fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
21+
let v = 22;
22+
gimme(&(v,))
23+
//~^ ERROR borrowed value does not live long enough [E0597]
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0597]: borrowed value does not live long enough
2+
--> $DIR/borrowed-universal-error.rs:22:12
3+
|
4+
LL | gimme(&(v,))
5+
| ^^^^ temporary value does not live long enough
6+
LL | //~^ ERROR borrowed value does not live long enough [E0597]
7+
LL | }
8+
| - temporary value only lives until here
9+
|
10+
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 20:1...
11+
--> $DIR/borrowed-universal-error.rs:20:1
12+
|
13+
LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: aborting due to previous error
17+
18+
If you want more information on this error, try using "rustc --explain E0597"

src/test/ui/nll/capture-ref-in-struct.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ LL | }
99
LL |
1010
LL | deref(p);
1111
| - borrow later used here
12-
|
13-
= note: borrowed value must be valid for lifetime '_#5r...
1412

1513
error: aborting due to previous error
1614

src/test/ui/nll/closure-requirements/escape-argument.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ LL | }
3434
LL |
3535
LL | deref(p);
3636
| - borrow later used here
37-
|
38-
= note: borrowed value must be valid for lifetime '_#6r...
3937

4038
error: aborting due to previous error
4139

src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ LL | }
6161
LL |
6262
LL | deref(p);
6363
| - borrow later used here
64-
|
65-
= note: borrowed value must be valid for lifetime '_#4r...
6664

6765
error: aborting due to previous error
6866

src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ LL | }
3838
LL |
3939
LL | deref(p);
4040
| - borrow later used here
41-
|
42-
= note: borrowed value must be valid for lifetime '_#4r...
4341

4442
error: aborting due to previous error
4543

src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ LL | let cell = Cell::new(&a);
7878
...
7979
LL | }
8080
| - borrowed value only lives until here
81-
|
82-
= note: borrowed value must be valid for lifetime '_#2r...
8381

8482
error: aborting due to 2 previous errors
8583

src/test/ui/nll/return-ref-mut-issue-46557.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ LL | let ref mut x = 1234543; //~ ERROR borrowed value does not live long en
66
LL | x
77
LL | }
88
| - temporary value only lives until here
9-
|
10-
= note: borrowed value must be valid for lifetime '_#2r...
119

1210
error: aborting due to previous error
1311

0 commit comments

Comments
 (0)