diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index cd506fabb55..b51ddf719cb 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -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, + 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", diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 9d8b2b709b7..667450c3f35 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -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, ) { 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, diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 158e8c7a992..c93c1848e25 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -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, + "...", + ); + } + } + _ => { } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index d2f6d626c9e..e0a8877a6ab 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -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> { + pub fn to_error_region(&self, r: RegionVid) -> Option> { if self.universal_regions.is_universal_region(r) { return self.definitions[r].external_name; } else { diff --git a/src/test/ui/nll/borrowed-universal-error-2.rs b/src/test/ui/nll/borrowed-universal-error-2.rs new file mode 100644 index 00000000000..da03a9fc39b --- /dev/null +++ b/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 or the MIT license +// , 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() {} diff --git a/src/test/ui/nll/borrowed-universal-error-2.stderr b/src/test/ui/nll/borrowed-universal-error-2.stderr new file mode 100644 index 00000000000..ff999a71e0f --- /dev/null +++ b/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" diff --git a/src/test/ui/nll/borrowed-universal-error.rs b/src/test/ui/nll/borrowed-universal-error.rs new file mode 100644 index 00000000000..fdc4c29071e --- /dev/null +++ b/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 or the MIT license +// , 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() {} diff --git a/src/test/ui/nll/borrowed-universal-error.stderr b/src/test/ui/nll/borrowed-universal-error.stderr new file mode 100644 index 00000000000..4a3d0c6d959 --- /dev/null +++ b/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" diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr index 316a918e4ee..1c545906893 100644 --- a/src/test/ui/nll/capture-ref-in-struct.stderr +++ b/src/test/ui/nll/capture-ref-in-struct.stderr @@ -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 diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr index 93a7bab3386..18ffdc58349 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr @@ -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 diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr index b6c1d808ff5..7b2b2f74872 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -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 diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr index 3cb6524f3b4..0a45603a42c 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -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 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index eb4d264bf82..21ed421fe96 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -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 diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.stderr index f7e85e4277b..c77e0772ce9 100644 --- a/src/test/ui/nll/return-ref-mut-issue-46557.stderr +++ b/src/test/ui/nll/return-ref-mut-issue-46557.stderr @@ -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