Skip to content

Commit

Permalink
Auto merge of #53124 - davidtwco:issue-52742, r=nikomatsakis
Browse files Browse the repository at this point in the history
region error messages involving impls are confusing

Part of #52742.

r? @nikomatsakis
  • Loading branch information
bors committed Aug 10, 2018
2 parents db1acaa + 31657c9 commit f6d43ed
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
ty::BrNamed(..) => true,
_ => false,
},
ty::ReEarlyBound(_) => true,
ty::ReEarlyBound(ebr) => ebr.has_name(),
_ => false,
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use std::{mem, ptr};
use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId};
use syntax::attr;
use syntax::ext::hygiene::Mark;
use syntax::symbol::{Symbol, LocalInternedString, InternedString};
use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
use syntax_pos::{DUMMY_SP, Span};

use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
Expand Down Expand Up @@ -825,6 +825,12 @@ impl ty::EarlyBoundRegion {
pub fn to_bound_region(&self) -> ty::BoundRegion {
ty::BoundRegion::BrNamed(self.def_id, self.name)
}

/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).
pub fn has_name(&self) -> bool {
self.name != keywords::UnderscoreLifetime.name().as_interned_str()
}
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!("give_region_a_name: error_region = {:?}", error_region);
match error_region {
ty::ReEarlyBound(ebr) => {
self.highlight_named_span(tcx, error_region, &ebr.name, diag);
Some(ebr.name)
if ebr.has_name() {
self.highlight_named_span(tcx, error_region, &ebr.name, diag);
Some(ebr.name)
} else {
None
}
},

ty::ReStatic => Some(keywords::StaticLifetime.name().as_interned_str()),
Expand Down Expand Up @@ -238,17 +242,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return Some(region_name);
}

let (_argument_name, argument_span) = self.get_argument_name_and_span_for_region(
mir, argument_index);

let region_name = self.synthesize_region_name(counter);

diag.span_label(
argument_span,
format!("lifetime `{}` appears in this argument", region_name,),
);

Some(region_name)
self.give_name_if_we_cannot_match_hir_ty(
infcx,
mir,
fr,
arg_ty,
counter,
diag,
)
}

fn give_name_if_we_can_match_hir_ty_from_argument(
Expand Down Expand Up @@ -366,14 +367,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {

search_stack.push((argument_ty, argument_hir_ty));

let mut closest_match: &hir::Ty = argument_hir_ty;

while let Some((ty, hir_ty)) = search_stack.pop() {
// While we search, also track the closet match.
if tcx.any_free_region_meets(&ty, |r| r.to_region_vid() == needle_fr) {
closest_match = hir_ty;
}

match (&ty.sty, &hir_ty.node) {
// Check if the `argument_ty` is `&'X ..` where `'X`
// is the region we are looking for -- if so, and we have a `&T`
Expand Down Expand Up @@ -448,13 +442,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}

let region_name = self.synthesize_region_name(counter);
diag.span_label(
closest_match.span,
format!("lifetime `{}` appears in this type", region_name),
);

return Some(region_name);
return None;
}

/// We've found an enum/struct/union type with the substitutions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex2b-push-no-existing-names.rs:16:5
|
LL | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
| -------- -------- lifetime `'1` appears in this type
| |
| lifetime `'2` appears in this type
| - - has type `Ref<'1, i32>`
| |
| has type `&mut std::vec::Vec<Ref<'2, i32>>`
LL | x.push(y); //~ ERROR lifetime mismatch
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-both-are-structs-2.rs:16:5
|
LL | fn foo(mut x: Ref, y: Ref) {
| --- --- lifetime `'1` appears in this type
| |
| lifetime `'2` appears in this type
| ----- - has type `Ref<'_, '1>`
| |
| has type `Ref<'_, '2>`
LL | x.b = y.b; //~ ERROR lifetime mismatch
| ^^^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-both-are-structs-3.rs:16:5
|
LL | fn foo(mut x: Ref) {
| ---
| |
| lifetime `'1` appears in this type
| lifetime `'2` appears in this type
| -----
| |
| has type `Ref<'_, '1>`
| has type `Ref<'2, '_>`
LL | x.a = x.b; //~ ERROR lifetime mismatch
| ^^^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-both-are-structs-4.rs:16:5
|
LL | fn foo(mut x: Ref) {
| ---
| |
| lifetime `'1` appears in this type
| lifetime `'2` appears in this type
| -----
| |
| has type `Ref<'_, '1>`
| has type `Ref<'2, '_>`
LL | x.a = x.b; //~ ERROR lifetime mismatch
| ^^^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-both-are-structs.rs:15:5
|
LL | fn foo(mut x: Vec<Ref>, y: Ref) {
| --- --- lifetime `'1` appears in this type
| |
| lifetime `'2` appears in this type
| ----- - has type `Ref<'1>`
| |
| has type `std::vec::Vec<Ref<'2>>`
LL | x.push(y); //~ ERROR lifetime mismatch
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:14:5
|
LL | fn foo(mut x: Ref, y: &u32) {
| --- - let's call the lifetime of this reference `'2`
| |
| lifetime `'1` appears in this type
| ----- - let's call the lifetime of this reference `'2`
| |
| has type `Ref<'_, '1>`
LL | y = x.b; //~ ERROR lifetime mismatch
| ^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-one-is-struct-3.rs:14:5
|
LL | fn foo(mut y: Ref, x: &u32) {
| --- - let's call the lifetime of this reference `'1`
| |
| lifetime `'2` appears in this type
| ----- - let's call the lifetime of this reference `'1`
| |
| has type `Ref<'_, '2>`
LL | y.b = x; //~ ERROR lifetime mismatch
| ^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:14:5
|
LL | fn foo(mut y: Ref, x: &u32) {
| --- - let's call the lifetime of this reference `'1`
| |
| lifetime `'2` appears in this type
| ----- - let's call the lifetime of this reference `'1`
| |
| has type `Ref<'_, '2>`
LL | y.b = x; //~ ERROR lifetime mismatch
| ^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
--> $DIR/ex3-both-anon-regions-one-is-struct.rs:17:5
|
LL | fn foo(mut x: Ref, y: &u32) {
| --- - let's call the lifetime of this reference `'1`
| |
| lifetime `'2` appears in this type
| ----- - let's call the lifetime of this reference `'1`
| |
| has type `Ref<'_, '2>`
LL | x.b = y; //~ ERROR lifetime mismatch
| ^^^^^^^ requires that `'1` must outlive `'2`

Expand Down
31 changes: 31 additions & 0 deletions src/test/ui/nll/issue-52742.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2012 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.

#![feature(nll)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

struct Foo<'a, 'b> {
x: &'a u32,
y: &'b u32,
}

struct Bar<'b> {
z: &'b u32
}

impl Foo<'_, '_> {
fn take_bar(&mut self, b: Bar<'_>) {
self.y = b.z
//~^ ERROR unsatisfied lifetime constraints
}
}

fn main() { }
12 changes: 12 additions & 0 deletions src/test/ui/nll/issue-52742.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: unsatisfied lifetime constraints
--> $DIR/issue-52742.rs:26:9
|
LL | fn take_bar(&mut self, b: Bar<'_>) {
| --------- -- let's call this `'1`
| |
| has type `&mut Foo<'_, '2>`
LL | self.y = b.z
| ^^^^^^^^^^^^ requires that `'1` must outlive `'2`

error: aborting due to previous error

0 comments on commit f6d43ed

Please sign in to comment.