about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2018-08-06 21:15:15 +0200
committerDavid Wood <david@davidtw.co>2018-08-09 10:25:23 +0200
commit82b48277a2f2c7b52c937fa85bddd90f85fbf3e1 (patch)
tree4363d41ac99198ac6f82eb3406cf5361c7b77ce6
parent76b69a604ee0d70be1edfa2828c769dc1b148d13 (diff)
downloadrust-82b48277a2f2c7b52c937fa85bddd90f85fbf3e1.tar.gz
rust-82b48277a2f2c7b52c937fa85bddd90f85fbf3e1.zip
Correctly identify named early bound regions.
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--src/librustc/ty/mod.rs8
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs8
-rw-r--r--src/test/ui/nll/issue-52742.rs30
-rw-r--r--src/test/ui/nll/issue-52742.stderr12
5 files changed, 56 insertions, 4 deletions
diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index ca71b0aeed9..4e26a4178b9 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -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,
         }
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 4fda3bdca3d..d7e30b0ca71 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -51,7 +51,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;
@@ -824,6 +824,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)]
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index 8c2a5f19038..90edc7a60bd 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -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()),
diff --git a/src/test/ui/nll/issue-52742.rs b/src/test/ui/nll/issue-52742.rs
new file mode 100644
index 00000000000..84d06a1d20a
--- /dev/null
+++ b/src/test/ui/nll/issue-52742.rs
@@ -0,0 +1,30 @@
+// 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)]
+
+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() { }
diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr
new file mode 100644
index 00000000000..89c235c4e8f
--- /dev/null
+++ b/src/test/ui/nll/issue-52742.stderr
@@ -0,0 +1,12 @@
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-52742.rs:25:9
+   |
+LL |     fn take_bar(&mut self, b: Bar<'_>) {
+   |                 ---------         -- let's call this `'1`
+   |                 |
+   |                 lifetime `'2` appears in this type
+LL |         self.y = b.z
+   |         ^^^^^^^^^^^^ requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+