Skip to content

Commit

Permalink
Make explain borrow work for Universal lifetimes
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Mar 1, 2018
1 parent 834e392 commit ff7dca5
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 22 deletions.
33 changes: 27 additions & 6 deletions src/librustc/infer/error_reporting/mod.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/borrow_check/error_reporting.rs
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down
14 changes: 13 additions & 1 deletion src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
"...",
);
}
}

_ => {
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Expand Up @@ -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 {
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/nll/borrowed-universal-error-2.rs
@@ -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() {}
18 changes: 18 additions & 0 deletions src/test/ui/nll/borrowed-universal-error-2.stderr
@@ -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"
26 changes: 26 additions & 0 deletions src/test/ui/nll/borrowed-universal-error.rs
@@ -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() {}
18 changes: 18 additions & 0 deletions src/test/ui/nll/borrowed-universal-error.stderr
@@ -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"
2 changes: 0 additions & 2 deletions src/test/ui/nll/capture-ref-in-struct.stderr
Expand Up @@ -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

Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/nll/closure-requirements/escape-argument.stderr
Expand Up @@ -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

Expand Down
Expand Up @@ -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

Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
Expand Up @@ -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

Expand Down
Expand Up @@ -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

Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/nll/return-ref-mut-issue-46557.stderr
Expand Up @@ -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

Expand Down

0 comments on commit ff7dca5

Please sign in to comment.