Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NLL mentions lifetimes that are not included in printed span(s). #52973

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
use rustc::mir::Mir;
use rustc::ty::subst::{Substs, UnpackedKind};
use rustc::ty::{self, RegionVid, Ty, TyCtxt};
use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
use rustc::util::ppaux::with_highlight_region;
use rustc_errors::DiagnosticBuilder;
use syntax::ast::Name;
use syntax::ast::{Name, DUMMY_NODE_ID};
use syntax::symbol::keywords;
use syntax_pos::symbol::InternedString;

Expand Down Expand Up @@ -90,14 +90,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
diag: &mut DiagnosticBuilder<'_>,
) -> Option<InternedString> {
let error_region = self.to_error_region(fr)?;

debug!("give_region_a_name: error_region = {:?}", error_region);
match error_region {
ty::ReEarlyBound(ebr) => Some(ebr.name),
ty::ReEarlyBound(ebr) => {
self.highlight_named_span(tcx, error_region, &ebr.name, diag);
Some(ebr.name)
},

ty::ReStatic => Some(keywords::StaticLifetime.name().as_interned_str()),

ty::ReFree(free_region) => match free_region.bound_region {
ty::BoundRegion::BrNamed(_, name) => Some(name),
ty::BoundRegion::BrNamed(_, name) => {
self.highlight_named_span(tcx, error_region, &name, diag);
Some(name)
},

ty::BoundRegion::BrEnv => {
let closure_span = tcx.hir.span_if_local(mir_def_id).unwrap();
Expand All @@ -123,6 +130,45 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}

/// Highlight a named span to provide context for error messages that
/// mention that span, for example:
///
/// ```
/// |
/// | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
/// | -- -- lifetime `'b` defined here
/// | |
/// | lifetime `'a` defined here
/// |
/// | with_signature(cell, t, |cell, t| require(cell, t));
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must
/// | outlive `'a`
/// ```
fn highlight_named_span(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
error_region: &RegionKind,
name: &InternedString,
diag: &mut DiagnosticBuilder<'_>,
) {
let cm = tcx.sess.codemap();

let scope = error_region.free_region_binding_scope(tcx);
let node = tcx.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);

let mut sp = cm.def_span(tcx.hir.span(node));
if let Some(param) = tcx.hir.get_generics(scope).and_then(|generics| {
generics.get_named(name)
}) {
sp = param.span;
}

diag.span_label(
sp,
format!("lifetime `{}` defined here", name),
);
}

/// Find an argument that contains `fr` and label it with a fully
/// elaborated type, returning something like `'1`. Result looks
/// like:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ LL | self.x.iter().map(|a| a.0)
error: unsatisfied lifetime constraints
--> $DIR/static-return-lifetime-infered.rs:21:9
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| -- lifetime `'a` defined here
LL | self.x.iter().map(|a| a.0)
| ^^^^^^^^^^^^^ requires that `'a` must outlive `'static`

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issue-10291.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ LL | x //~ ERROR E0312
error: unsatisfied lifetime constraints
--> $DIR/issue-10291.rs:12:5
|
LL | fn test<'x>(x: &'x isize) {
| -- lifetime `'x` defined here
LL | drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/issue-52213.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ LL | match (&t,) { //~ ERROR cannot infer an appropriate lifetime
error: unsatisfied lifetime constraints
--> $DIR/issue-52213.rs:13:11
|
LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | match (&t,) { //~ ERROR cannot infer an appropriate lifetime
LL | ((u,),) => u,
| ^ requires that `'a` must outlive `'b`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ LL | &*x
error: unsatisfied lifetime constraints
--> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
|
LL | fn foo<'a>(x: &'a u32) -> &'static u32 {
| -- lifetime `'a` defined here
LL | &*x
| ^^^ requires that `'a` must outlive `'static`

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/nll/mir_check_cast_closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ LL | g
error: unsatisfied lifetime constraints
--> $DIR/mir_check_cast_closure.rs:16:28
|
LL | fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let g: fn(_, _) -> _ = |_x, y| y;
| ^^^^^^^^^ cast requires that `'b` must outlive `'a`

Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/nll/mir_check_cast_unsize.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/mir_check_cast_unsize.rs:17:46
|
LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
| ______________________________________________^
| ________--____________________________________^
| | |
| | lifetime `'a` defined here
LL | | //~^ ERROR unsatisfied lifetime constraints
LL | | x
LL | | //~^ WARNING not reporting region error due to nll
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-one-region-closure.rs:55:5
|
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down Expand Up @@ -101,6 +106,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-one-region-closure.rs:67:5
|
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down Expand Up @@ -150,6 +160,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-one-region-closure.rs:89:5
|
LL | fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-one-region-trait-bound-closure.rs:47:5
|
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down Expand Up @@ -91,6 +96,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-one-region-trait-bound-closure.rs:58:5
|
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down Expand Up @@ -131,6 +141,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-one-region-trait-bound-closure.rs:79:5
|
LL | fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ LL | | }
error: unsatisfied lifetime constraints
--> $DIR/projection-two-region-trait-bound-closure.rs:108:5
|
LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`

Expand Down