about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Nielens <tim.nielens@gmail.com>2020-09-08 22:22:23 +0200
committerTim Nielens <tim.nielens@gmail.com>2020-09-09 10:08:45 +0200
commitc8e9e52303da6dff4bc5cc4db3021d608fca6c70 (patch)
tree7cc9074e69ca04922b4153f2608a6e74982ea63f
parenta60e5de90c7370d4fb3e6561d3cb55495cda2e2a (diff)
downloadrust-c8e9e52303da6dff4bc5cc4db3021d608fca6c70.tar.gz
rust-c8e9e52303da6dff4bc5cc4db3021d608fca6c70.zip
needless-lifetime / add test cases for nested elision sites
-rw-r--r--tests/ui/needless_lifetimes.rs68
-rw-r--r--tests/ui/needless_lifetimes.stderr32
2 files changed, 90 insertions, 10 deletions
diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs
index bc725a645ac..548c5929c61 100644
--- a/tests/ui/needless_lifetimes.rs
+++ b/tests/ui/needless_lifetimes.rs
@@ -259,36 +259,86 @@ mod issue4291 {
     }
 }
 
+mod issue2944 {
+    trait Foo {}
+    struct Bar {}
+    struct Baz<'a> {
+        bar: &'a Bar,
+    }
+
+    impl<'a> Foo for Baz<'a> {}
+    impl Bar {
+        fn baz<'a>(&'a self) -> impl Foo + 'a {
+            Baz { bar: self }
+        }
+    }
+}
+
 mod nested_elision_sites {
-    // Don't lint these cases, they cause FPs.
-    // The lint does not support nested elision sites.
+    // issue #issue2944
 
-    fn nested_fn_trait_bound<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {
+    // closure trait bounds subject to nested elision
+    // don't lint because they refer to outer lifetimes
+    fn trait_fn<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {
         move || i
     }
-
-    fn nested_fn_mut_trait_bound<'a>(i: &'a i32) -> impl FnMut() -> &'a i32 {
+    fn trait_fn_mut<'a>(i: &'a i32) -> impl FnMut() -> &'a i32 {
+        move || i
+    }
+    fn trait_fn_once<'a>(i: &'a i32) -> impl FnOnce() -> &'a i32 {
         move || i
     }
 
-    fn nested_fn_once_trait_bound<'a>(i: &'a i32) -> impl FnOnce() -> &'a i32 {
+    // don't lint
+    fn impl_trait_in_input_position<'a>(f: impl Fn() -> &'a i32) -> &'a i32 {
+        f()
+    }
+    fn impl_trait_in_output_position<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {
         move || i
     }
+    // lint
+    fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 {
+        f(i)
+    }
+    fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
+        f(i)
+    }
 
-    fn nested_generic_fn_trait_bound<'a, T: Fn() -> &'a i32>(f: T) -> &'a i32 {
+    // don't lint
+    fn generics_not_elidable<'a, T: Fn() -> &'a i32>(f: T) -> &'a i32 {
         f()
     }
+    // lint
+    fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
+        f(i)
+    }
 
-    fn nested_where_clause_fn_trait_bound<'a, T>(f: T) -> &'a i32
+    // don't lint
+    fn where_clause_not_elidable<'a, T>(f: T) -> &'a i32
     where
         T: Fn() -> &'a i32,
     {
         f()
     }
+    // lint
+    fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
+    where
+        T: Fn(&i32) -> &i32,
+    {
+        f(i)
+    }
 
-    fn nested_pointer_fn<'a>(_: &'a i32) -> fn(&'a i32) -> &'a i32 {
+    // don't lint
+    fn pointer_fn_in_input_position<'a>(f: fn(&'a i32) -> &'a i32, i: &'a i32) -> &'a i32 {
+        f(i)
+    }
+    fn pointer_fn_in_output_position<'a>(_: &'a i32) -> fn(&'a i32) -> &'a i32 {
         |i| i
     }
+    // lint
+    fn pointer_fn_elidable<'a>(f: fn(&i32) -> &i32, i: &'a i32) -> &'a i32 {
+        f(i)
+    }
 }
 
 fn main() {}
diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr
index d3a360ed8b5..ac38ab8effd 100644
--- a/tests/ui/needless_lifetimes.stderr
+++ b/tests/ui/needless_lifetimes.stderr
@@ -102,5 +102,35 @@ error: explicit lifetimes given in parameter types where they could be elided (o
 LL |         fn needless_lt<'a>(_x: &'a u8) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:271:9
+   |
+LL |         fn baz<'a>(&'a self) -> impl Foo + 'a {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:300:5
+   |
+LL |     fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:303:5
+   |
+LL |     fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:312:5
+   |
+LL |     fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:324:5
+   |
+LL |     fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 22 previous errors