about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-03 01:26:56 +0000
committerbors <bors@rust-lang.org>2018-02-03 01:26:56 +0000
commit6c15dffc43d86c316e3d6bf9f9ffd48d8b5f4a3e (patch)
tree40f2aac56b2262ce76ed9eeb9e30b123b4f9ca1d /src/test/ui
parent616b66dca25a67321b1654e5a65acc6337d63cf4 (diff)
parent67696be160cc35ba5e54086a42225d9c1f81b275 (diff)
Auto merge of #47791 - estebank:mismatched-trait-impl, r=nikomatsakis
Tweak presentation on lifetime trait mismatch

 - On trait/impl method discrepancy, add label pointing at trait signature.
 - Point only at method definition when referring to named lifetimes on lifetime mismatch.
 - When the sub and sup expectations are the same, tweak the output to avoid repeated spans.

Fix #30790, CC #18759.
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/associated-const-impl-wrong-lifetime.stderr7
-rw-r--r--src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs58
-rw-r--r--src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr48
-rw-r--r--src/test/ui/closure-expected-type/expect-region-supply-region.stderr20
-rw-r--r--src/test/ui/impl-trait/trait_type.stderr4
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs22
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr22
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr31
-rw-r--r--src/test/ui/issue-27942.stderr20
-rw-r--r--src/test/ui/issue-37884.stderr10
-rw-r--r--src/test/ui/issue-46472.stderr16
-rw-r--r--src/test/ui/static-lifetime.stderr2
12 files changed, 177 insertions, 83 deletions
diff --git a/src/test/ui/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const-impl-wrong-lifetime.stderr
index a7aee9b19f1..ab0e1003a9e 100644
--- a/src/test/ui/associated-const-impl-wrong-lifetime.stderr
+++ b/src/test/ui/associated-const-impl-wrong-lifetime.stderr
@@ -9,11 +9,8 @@ error[E0308]: mismatched types
 note: the lifetime 'a as defined on the impl at 17:1...
   --> $DIR/associated-const-impl-wrong-lifetime.rs:17:1
    |
-17 | / impl<'a> Foo for &'a () {
-18 | |     const NAME: &'a str = "unit";
-19 | |     //~^ ERROR mismatched types [E0308]
-20 | | }
-   | |_^
+17 | impl<'a> Foo for &'a () {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...does not necessarily outlive the static lifetime
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs
new file mode 100644
index 00000000000..617de2c5dfe
--- /dev/null
+++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs
@@ -0,0 +1,58 @@
+// Copyright 2014 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.
+
+// Check that explicit region bounds are allowed on the various
+// nominal types (but not on other types) and that they are type
+// checked.
+
+struct Inv<'a> { // invariant w/r/t 'a
+    x: &'a mut &'a isize
+}
+
+pub trait Foo<'a, 't> {
+    fn no_bound<'b>(self, b: Inv<'b>);
+    fn has_bound<'b:'a>(self, b: Inv<'b>);
+    fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
+    fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
+    fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
+}
+
+impl<'a, 't> Foo<'a, 't> for &'a isize {
+    fn no_bound<'b:'a>(self, b: Inv<'b>) {
+        //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
+    }
+
+    fn has_bound<'b>(self, b: Inv<'b>) {
+        //~^ ERROR lifetime parameters or bounds on method `has_bound` do not match
+    }
+
+    fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+        //~^ ERROR method not compatible with trait
+        //
+        // Note: This is a terrible error message. It is caused
+        // because, in the trait, 'b is early bound, and in the impl,
+        // 'c is early bound, so -- after substitution -- the
+        // lifetimes themselves look isomorphic.  We fail because the
+        // lifetimes that appear in the types are in the wrong
+        // order. This should really be fixed by keeping more
+        // information about the lifetime declarations in the trait so
+        // that we can compare better to the impl, even in cross-crate
+        // cases.
+    }
+
+    fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
+    }
+
+    fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
+        //~^ ERROR E0276
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
new file mode 100644
index 00000000000..e8323247af9
--- /dev/null
+++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
@@ -0,0 +1,48 @@
+error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:28:5
+   |
+20 |     fn no_bound<'b>(self, b: Inv<'b>);
+   |     ---------------------------------- lifetimes in impl do not match this method in trait
+...
+28 |     fn no_bound<'b:'a>(self, b: Inv<'b>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
+
+error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:32:5
+   |
+21 |     fn has_bound<'b:'a>(self, b: Inv<'b>);
+   |     -------------------------------------- lifetimes in impl do not match this method in trait
+...
+32 |     fn has_bound<'b>(self, b: Inv<'b>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
+
+error[E0308]: method not compatible with trait
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
+   |
+36 |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |
+   = note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
+              found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
+note: the lifetime 'c as defined on the method body at 36:5...
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
+   |
+36 |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 36:5
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
+   |
+36 |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:53:5
+   |
+24 |     fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
+   |     ------------------------------------------------------- definition of `another_bound` from trait
+...
+53 |     fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr
index ebb1e561e57..5c612522d9a 100644
--- a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr
+++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr
@@ -41,14 +41,8 @@ note: the anonymous lifetime #2 defined on the body at 47:29...
 note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1
   --> $DIR/expect-region-supply-region.rs:42:1
    |
-42 | / fn expect_bound_supply_named<'x>() {
-43 | |     let mut f: Option<&u32> = None;
-44 | |
-45 | |     // Here we give a type annotation that `x` should be free. We get
-...  |
-54 | |     });
-55 | | }
-   | |_^
+42 | fn expect_bound_supply_named<'x>() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/expect-region-supply-region.rs:47:33
@@ -61,14 +55,8 @@ error[E0308]: mismatched types
 note: the lifetime 'x as defined on the function body at 42:1...
   --> $DIR/expect-region-supply-region.rs:42:1
    |
-42 | / fn expect_bound_supply_named<'x>() {
-43 | |     let mut f: Option<&u32> = None;
-44 | |
-45 | |     // Here we give a type annotation that `x` should be free. We get
-...  |
-54 | |     });
-55 | | }
-   | |_^
+42 | fn expect_bound_supply_named<'x>() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29
   --> $DIR/expect-region-supply-region.rs:47:29
    |
diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr
index 7a0d01a8ec2..1417c71ca12 100644
--- a/src/test/ui/impl-trait/trait_type.stderr
+++ b/src/test/ui/impl-trait/trait_type.stderr
@@ -2,7 +2,7 @@ error[E0053]: method `fmt` has an incompatible type for trait
   --> $DIR/trait_type.rs:17:4
    |
 17 |    fn fmt(&self, x: &str) -> () { }
-   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
    |
    = note: expected type `fn(&MyType, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
               found type `fn(&MyType, &str)`
@@ -19,7 +19,7 @@ error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in th
   --> $DIR/trait_type.rs:27:4
    |
 27 |    fn fmt() -> () { }
-   |    ^^^^^^^^^^^^^^^^^^ expected `&self` in impl
+   |    ^^^^^^^^^^^^^^ expected `&self` in impl
    |
    = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
 
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
new file mode 100644
index 00000000000..f845762cefd
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-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.
+
+use std::ops::Deref;
+trait Trait {}
+
+struct Struct;
+
+impl Deref for Struct {
+    type Target = Trait;
+    fn deref(&self) -> &Trait {
+        unimplemented!();
+    }
+}
+//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
new file mode 100644
index 00000000000..7aab31eb909
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
@@ -0,0 +1,22 @@
+error[E0601]: main function not found
+
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
+  --> $DIR/mismatched_trait_impl-2.rs:18:5
+   |
+18 |     fn deref(&self) -> &Trait {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 18:5...
+  --> $DIR/mismatched_trait_impl-2.rs:18:5
+   |
+18 | /     fn deref(&self) -> &Trait {
+19 | |         unimplemented!();
+20 | |     }
+   | |_____^
+   = note: ...but the lifetime must also be valid for the static lifetime...
+   = note: ...so that the method type is compatible with trait:
+           expected fn(&Struct) -> &Trait + 'static
+              found fn(&Struct) -> &Trait
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
index e96f7181a6d..fd6be01da9f 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
@@ -1,10 +1,8 @@
 error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
   --> $DIR/mismatched_trait_impl.rs:19:5
    |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
+19 |     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 19:5...
   --> $DIR/mismatched_trait_impl.rs:19:5
@@ -13,27 +11,14 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th
 20 | |         x
 21 | |     }
    | |_____^
-note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32)
-  --> $DIR/mismatched_trait_impl.rs:19:5
-   |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
-note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5...
+note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 19:5...
   --> $DIR/mismatched_trait_impl.rs:19:5
    |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
-note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32)
-  --> $DIR/mismatched_trait_impl.rs:19:5
-   |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
+19 |     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the method type is compatible with trait:
+           expected fn(&i32, &'a u32, &u32) -> &'a u32
+              found fn(&i32, &u32, &u32) -> &u32
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-27942.stderr b/src/test/ui/issue-27942.stderr
index b580b8e7313..b24544743d8 100644
--- a/src/test/ui/issue-27942.stderr
+++ b/src/test/ui/issue-27942.stderr
@@ -14,14 +14,8 @@ note: the anonymous lifetime #1 defined on the method body at 15:5...
 note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 13:1
   --> $DIR/issue-27942.rs:13:1
    |
-13 | / pub trait Buffer<'a, R: Resources<'a>> {
-14 | |
-15 | |     fn select(&self) -> BufferViewHandle<R>;
-16 | |     //~^ ERROR mismatched types
-...  |
-19 | |     //~| lifetime mismatch
-20 | | }
-   | |_^
+13 | pub trait Buffer<'a, R: Resources<'a>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-27942.rs:15:5
@@ -34,14 +28,8 @@ error[E0308]: mismatched types
 note: the lifetime 'a as defined on the trait at 13:1...
   --> $DIR/issue-27942.rs:13:1
    |
-13 | / pub trait Buffer<'a, R: Resources<'a>> {
-14 | |
-15 | |     fn select(&self) -> BufferViewHandle<R>;
-16 | |     //~^ ERROR mismatched types
-...  |
-19 | |     //~| lifetime mismatch
-20 | | }
-   | |_^
+13 | pub trait Buffer<'a, R: Resources<'a>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 15:5
   --> $DIR/issue-27942.rs:15:5
    |
diff --git a/src/test/ui/issue-37884.stderr b/src/test/ui/issue-37884.stderr
index 439b123975f..c4ad232ae7e 100644
--- a/src/test/ui/issue-37884.stderr
+++ b/src/test/ui/issue-37884.stderr
@@ -24,14 +24,8 @@ note: the anonymous lifetime #1 defined on the method body at 16:5...
 note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:1
   --> $DIR/issue-37884.rs:13:1
    |
-13 | / impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
-14 | |
-15 | |     type Item = &'a mut T;
-16 | |     fn next(&'a mut self) -> Option<Self::Item>
-...  |
-21 | |     }
-22 | | }
-   | |_^
+13 | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-46472.stderr b/src/test/ui/issue-46472.stderr
index 2f332a7a558..7b5cce218e9 100644
--- a/src/test/ui/issue-46472.stderr
+++ b/src/test/ui/issue-46472.stderr
@@ -10,12 +10,8 @@ error[E0597]: borrowed value does not live long enough (Ast)
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
   --> $DIR/issue-46472.rs:13:1
    |
-13 | / fn bar<'a>() -> &'a mut u32 {
-14 | |     &mut 4
-15 | |     //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
-16 | |     //~| ERROR borrowed value does not live long enough (Mir) [E0597]
-17 | | }
-   | |_^
+13 | fn bar<'a>() -> &'a mut u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0597]: borrowed value does not live long enough (Mir)
   --> $DIR/issue-46472.rs:14:10
@@ -29,12 +25,8 @@ error[E0597]: borrowed value does not live long enough (Mir)
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
   --> $DIR/issue-46472.rs:13:1
    |
-13 | / fn bar<'a>() -> &'a mut u32 {
-14 | |     &mut 4
-15 | |     //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
-16 | |     //~| ERROR borrowed value does not live long enough (Mir) [E0597]
-17 | | }
-   | |_^
+13 | fn bar<'a>() -> &'a mut u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr
index a99dbf21e54..24ba27b27ad 100644
--- a/src/test/ui/static-lifetime.stderr
+++ b/src/test/ui/static-lifetime.stderr
@@ -8,7 +8,7 @@ note: lifetime parameter instantiated with the lifetime 'a as defined on the imp
   --> $DIR/static-lifetime.rs:13:1
    |
 13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error: aborting due to previous error