Make explain borrow work for Universal lifetimes

This commit is contained in:
Santiago Pastorino 2018-03-01 11:56:43 -03:00
parent 834e39289d
commit ff7dca50a4
No known key found for this signature in database
GPG Key ID: 88C941CDA1D46432
14 changed files with 127 additions and 22 deletions

View File

@ -165,12 +165,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
);
}
};
let message = format!("{}{}{}", prefix, description, suffix);
if let Some(span) = span {
err.span_note(span, &message);
} else {
err.note(&message);
}
TyCtxt::emit_msg_span(err, prefix, description, span, suffix);
}
pub fn note_and_explain_free_region(self,
err: &mut DiagnosticBuilder,
prefix: &str,
region: ty::Region<'tcx>,
suffix: &str) {
let (description, span) = self.msg_span_from_free_region(region);
TyCtxt::emit_msg_span(err, prefix, description, span, suffix);
}
fn msg_span_from_free_region(self,
@ -224,6 +231,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
(format!("{} {}", prefix, msg), opt_span)
}
fn emit_msg_span(err: &mut DiagnosticBuilder,
prefix: &str,
description: String,
span: Option<Span>,
suffix: &str) {
let message = format!("{}{}{}", prefix, description, suffix);
if let Some(span) = span {
err.span_note(span, &message);
} else {
err.note(&message);
}
}
fn item_scope_tag(item: &hir::Item) -> &'static str {
match item.node {
hir::ItemImpl(..) => "impl",

View File

@ -233,7 +233,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
context: Context,
(place, span): (&Place<'tcx>, Span),
gen_borrow_kind: BorrowKind,
issued_borrow: &BorrowData,
issued_borrow: &BorrowData<'tcx>,
end_issued_loan_span: Option<Span>,
) {
let issued_span = self.retrieve_borrow_span(issued_borrow);
@ -574,7 +574,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
&mut self,
context: Context,
(place, span): (&Place<'tcx>, Span),
loan: &BorrowData,
loan: &BorrowData<'tcx>,
) {
let mut err = self.tcx.cannot_assign_to_borrowed(
span,

View File

@ -21,7 +21,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
pub(in borrow_check) fn explain_why_borrow_contains_point(
&self,
context: Context,
borrow: &BorrowData<'_>,
borrow: &BorrowData<'tcx>,
err: &mut DiagnosticBuilder<'_>,
) {
if let Some(regioncx) = &self.nonlexical_regioncx {
@ -70,6 +70,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
}
Cause::UniversalRegion(region_vid) => {
if let Some(region) = regioncx.to_error_region(region_vid) {
self.tcx.note_and_explain_free_region(
err,
"borrowed value must be valid for ",
region,
"...",
);
}
}
_ => {
}
}

View File

@ -588,7 +588,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// existentially bound, then we check its inferred value and try
/// to find a good name from that. Returns `None` if we can't find
/// one (e.g., this is just some random part of the CFG).
fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
if self.universal_regions.is_universal_region(r) {
return self.definitions[r].external_name;
} else {

View File

@ -0,0 +1,22 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -Znll-dump-cause
#![feature(nll)]
#![allow(warnings)]
fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
let v = 22;
&v
//~^ ERROR `v` does not live long enough [E0597]
}
fn main() {}

View File

@ -0,0 +1,18 @@
error[E0597]: `v` does not live long enough
--> $DIR/borrowed-universal-error-2.rs:18:5
|
LL | &v
| ^^ borrowed value does not live long enough
LL | //~^ ERROR `v` does not live long enough [E0597]
LL | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 16:1...
--> $DIR/borrowed-universal-error-2.rs:16:1
|
LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
If you want more information on this error, try using "rustc --explain E0597"

View File

@ -0,0 +1,26 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -Znll-dump-cause
#![feature(nll)]
#![allow(warnings)]
fn gimme(x: &(u32,)) -> &u32 {
&x.0
}
fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
let v = 22;
gimme(&(v,))
//~^ ERROR borrowed value does not live long enough [E0597]
}
fn main() {}

View File

@ -0,0 +1,18 @@
error[E0597]: borrowed value does not live long enough
--> $DIR/borrowed-universal-error.rs:22:12
|
LL | gimme(&(v,))
| ^^^^ temporary value does not live long enough
LL | //~^ ERROR borrowed value does not live long enough [E0597]
LL | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 20:1...
--> $DIR/borrowed-universal-error.rs:20:1
|
LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
If you want more information on this error, try using "rustc --explain E0597"

View File

@ -9,8 +9,6 @@ LL | }
LL |
LL | deref(p);
| - borrow later used here
|
= note: borrowed value must be valid for lifetime '_#5r...
error: aborting due to previous error

View File

@ -34,8 +34,6 @@ LL | }
LL |
LL | deref(p);
| - borrow later used here
|
= note: borrowed value must be valid for lifetime '_#6r...
error: aborting due to previous error

View File

@ -61,8 +61,6 @@ LL | }
LL |
LL | deref(p);
| - borrow later used here
|
= note: borrowed value must be valid for lifetime '_#4r...
error: aborting due to previous error

View File

@ -38,8 +38,6 @@ LL | }
LL |
LL | deref(p);
| - borrow later used here
|
= note: borrowed value must be valid for lifetime '_#4r...
error: aborting due to previous error

View File

@ -78,8 +78,6 @@ LL | let cell = Cell::new(&a);
...
LL | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for lifetime '_#2r...
error: aborting due to 2 previous errors

View File

@ -6,8 +6,6 @@ LL | let ref mut x = 1234543; //~ ERROR borrowed value does not live long en
LL | x
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for lifetime '_#2r...
error: aborting due to previous error