about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-27 01:01:58 +0000
committerbors <bors@rust-lang.org>2022-04-27 01:01:58 +0000
commit99b70ee230a363220d97148d567f07366d7ea4e0 (patch)
tree5c9df8d245757383f2ee1c52162320d91dc98d09 /src/test
parenta7197189cd0e3a86d1b661d1dceb8bdff021d0b8 (diff)
parentc0ed53c0dab14b9000abe4e6c9e86918d8c48224 (diff)
downloadrust-99b70ee230a363220d97148d567f07366d7ea4e0.tar.gz
rust-99b70ee230a363220d97148d567f07366d7ea4e0.zip
Auto merge of #96459 - Dylan-DPC:rollup-de6ud9d, r=Dylan-DPC
Rollup of 6 pull requests

Successful merges:

 - #92569 (Improve Error Messaging for Unconstructed Structs and Enum Variants in Generic Contexts)
 - #96370 (Cleanup `report_method_error` a bit)
 - #96383 (Fix erased region escaping into wfcheck due to #95395)
 - #96385 (Recover most `impl Trait` and `dyn Trait` lifetime bound suggestions under NLL)
 - #96410 (rustdoc: do not write `{{root}}` in `pub use ::foo` docs)
 - #96430 (Fix handling of `!` in rustdoc search)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src/test')
-rw-r--r--src/test/rustdoc-js-std/parser-errors.js20
-rw-r--r--src/test/rustdoc-js-std/parser-ident.js93
-rw-r--r--src/test/rustdoc-js-std/parser-returned.js23
-rw-r--r--src/test/rustdoc/issue-95873.rs2
-rw-r--r--src/test/rustdoc/issue-96381.rs16
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err.rs6
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err.stderr6
-rw-r--r--src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr6
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr36
-rw-r--r--src/test/ui/issues/issue-16922.nll.stderr5
-rw-r--r--src/test/ui/issues/issue-29124.stderr12
-rw-r--r--src/test/ui/issues/issue-57362-1.stderr5
-rw-r--r--src/test/ui/nll/mir_check_cast_unsize.stderr5
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr5
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr23
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-2.nll.stderr9
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-4.nll.stderr9
-rw-r--r--src/test/ui/regions/regions-proc-bound-capture.nll.stderr9
-rw-r--r--src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr22
-rw-r--r--src/test/ui/typeck/issue-87181/empty-tuple-method.rs14
-rw-r--r--src/test/ui/typeck/issue-87181/empty-tuple-method.stderr16
-rw-r--r--src/test/ui/typeck/issue-87181/enum-variant.rs16
-rw-r--r--src/test/ui/typeck/issue-87181/enum-variant.stderr16
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-field.rs14
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-field.stderr16
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-method.rs14
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-method.stderr16
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr6
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr5
29 files changed, 421 insertions, 24 deletions
diff --git a/src/test/rustdoc-js-std/parser-errors.js b/src/test/rustdoc-js-std/parser-errors.js
index 779ab867c12..dc42031e05f 100644
--- a/src/test/rustdoc-js-std/parser-errors.js
+++ b/src/test/rustdoc-js-std/parser-errors.js
@@ -35,6 +35,8 @@ const QUERY = [
     "a,:",
     "  a<>  :",
     "mod : :",
+    "a!a",
+    "a!!",
 ];
 
 const PARSED = [
@@ -362,4 +364,22 @@ const PARSED = [
         userQuery: "mod : :",
         error: 'Unexpected `:`',
     },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "a!a",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a!a",
+        error: '`!` can only be at the end of an ident',
+    },
+    {
+        elems: [],
+        foundElems: 0,
+        original: "a!!",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a!!",
+        error: 'Cannot have more than one `!` in an ident',
+    },
 ];
diff --git a/src/test/rustdoc-js-std/parser-ident.js b/src/test/rustdoc-js-std/parser-ident.js
new file mode 100644
index 00000000000..4b5ab01ac76
--- /dev/null
+++ b/src/test/rustdoc-js-std/parser-ident.js
@@ -0,0 +1,93 @@
+const QUERY = [
+    "R<!>",
+    "!",
+    "a!",
+    "a!::b",
+    "a!::b!",
+];
+
+const PARSED = [
+    {
+        elems: [{
+            name: "r",
+            fullPath: ["r"],
+            pathWithoutLast: [],
+            pathLast: "r",
+            generics: [
+                {
+                    name: "!",
+                    fullPath: ["!"],
+                    pathWithoutLast: [],
+                    pathLast: "!",
+                    generics: [],
+                },
+            ],
+        }],
+        foundElems: 1,
+        original: "R<!>",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "r<!>",
+        error: null,
+    },
+    {
+        elems: [{
+            name: "!",
+            fullPath: ["!"],
+            pathWithoutLast: [],
+            pathLast: "!",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "!",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "!",
+        error: null,
+    },
+    {
+        elems: [{
+            name: "a!",
+            fullPath: ["a!"],
+            pathWithoutLast: [],
+            pathLast: "a!",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "a!",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a!",
+        error: null,
+    },
+    {
+        elems: [{
+            name: "a!::b",
+            fullPath: ["a!", "b"],
+            pathWithoutLast: ["a!"],
+            pathLast: "b",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "a!::b",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a!::b",
+        error: null,
+    },
+    {
+        elems: [{
+            name: "a!::b!",
+            fullPath: ["a!", "b!"],
+            pathWithoutLast: ["a!"],
+            pathLast: "b!",
+            generics: [],
+        }],
+        foundElems: 1,
+        original: "a!::b!",
+        returned: [],
+        typeFilter: -1,
+        userQuery: "a!::b!",
+        error: null,
+    },
+];
diff --git a/src/test/rustdoc-js-std/parser-returned.js b/src/test/rustdoc-js-std/parser-returned.js
index b45466aa940..6fce17dcabd 100644
--- a/src/test/rustdoc-js-std/parser-returned.js
+++ b/src/test/rustdoc-js-std/parser-returned.js
@@ -1,4 +1,10 @@
-const QUERY = ['-> F<P>', '-> P', '->,a', 'aaaaa->a'];
+const QUERY = [
+    "-> F<P>",
+    "-> P",
+    "->,a",
+    "aaaaa->a",
+    "-> !",
+];
 
 const PARSED = [
     {
@@ -75,4 +81,19 @@ const PARSED = [
         userQuery: "aaaaa->a",
         error: null,
     },
+    {
+        elems: [],
+        foundElems: 1,
+        original: "-> !",
+        returned: [{
+            name: "!",
+            fullPath: ["!"],
+            pathWithoutLast: [],
+            pathLast: "!",
+            generics: [],
+        }],
+        typeFilter: -1,
+        userQuery: "-> !",
+        error: null,
+    },
 ];
diff --git a/src/test/rustdoc/issue-95873.rs b/src/test/rustdoc/issue-95873.rs
new file mode 100644
index 00000000000..ff33fb63a0b
--- /dev/null
+++ b/src/test/rustdoc/issue-95873.rs
@@ -0,0 +1,2 @@
+// @has issue_95873/index.html "//*[@class='item-left import-item']" "pub use ::std as x;"
+pub use ::std as x;
diff --git a/src/test/rustdoc/issue-96381.rs b/src/test/rustdoc/issue-96381.rs
new file mode 100644
index 00000000000..f0f123f85a0
--- /dev/null
+++ b/src/test/rustdoc/issue-96381.rs
@@ -0,0 +1,16 @@
+// should-fail
+
+#![allow(unused)]
+
+trait Foo<T>: Sized {
+    fn bar(i: i32, t: T, s: &Self) -> (T, i32);
+}
+
+impl Foo<usize> for () {
+    fn bar(i: _, t: _, s: _) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+        (1, 2)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/functions-closures/fn-help-with-err.rs b/src/test/ui/functions-closures/fn-help-with-err.rs
index f8a81af786f..3d2bcb8ad35 100644
--- a/src/test/ui/functions-closures/fn-help-with-err.rs
+++ b/src/test/ui/functions-closures/fn-help-with-err.rs
@@ -3,14 +3,14 @@ fn main() {
     let arc = std::sync::Arc::new(oops);
     //~^ ERROR cannot find value `oops` in this scope
     //~| NOTE not found
-    // The error "note: `arc` is a function, perhaps you wish to call it" MUST NOT appear.
+    // The error "note: this is a function, perhaps you wish to call it" MUST NOT appear.
     arc.blablabla();
     //~^ ERROR no method named `blablabla`
     //~| NOTE method not found
     let arc2 = std::sync::Arc::new(|| 1);
-    // The error "note: `arc2` is a function, perhaps you wish to call it" SHOULD appear
+    // The error "note: this is a function, perhaps you wish to call it" SHOULD appear
     arc2.blablabla();
     //~^ ERROR no method named `blablabla`
     //~| NOTE method not found
-    //~| NOTE `arc2` is a function, perhaps you wish to call it
+    //~| NOTE this is a function, perhaps you wish to call it
 }
diff --git a/src/test/ui/functions-closures/fn-help-with-err.stderr b/src/test/ui/functions-closures/fn-help-with-err.stderr
index 4d6b3282ad9..3e42cb1fb6e 100644
--- a/src/test/ui/functions-closures/fn-help-with-err.stderr
+++ b/src/test/ui/functions-closures/fn-help-with-err.stderr
@@ -14,9 +14,9 @@ error[E0599]: no method named `blablabla` found for struct `Arc<[closure@$DIR/fn
   --> $DIR/fn-help-with-err.rs:12:10
    |
 LL |     arc2.blablabla();
-   |          ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>`
-   |
-   = note: `arc2` is a function, perhaps you wish to call it
+   |     ---- ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>`
+   |     |
+   |     this is a function, perhaps you wish to call it
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr
index 9cf8ff76c87..66cffa9e36c 100644
--- a/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr
+++ b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr
@@ -24,10 +24,14 @@ LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send
 LL |     x
    |     ^ returning this value requires that `'b` must outlive `'static`
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'b`, add `'b` as a bound
+help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'b` lifetime bound
    |
 LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b {
    |                                                                                  ++++
+help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'b` lifetime bound
+   |
+LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> {
+   |                                                                                 ++++
 
 error: implementation of `Hrtb` is not general enough
   --> $DIR/issue-88236-2.rs:20:5
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
index 0059f729bae..5a190649b63 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -32,7 +32,14 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               |
    |               let's call the lifetime of this reference `'1`
    |
-   = help: consider replacing `'1` with `'static`
+help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x`
+   |
+LL | fn elided2(x: &i32) -> impl Copy + '_ { x }
+   |                                    ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x }
+   |               ~~~~~~~~~~~~
 
 error: lifetime may not live long enough
   --> $DIR/must_outlive_least_region_or_bound.rs:11:55
@@ -40,7 +47,14 @@ error: lifetime may not live long enough
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |              -- lifetime `'a` defined here            ^ returning this value requires that `'a` must outlive `'static`
    |
-   = help: consider replacing `'a` with `'static`
+help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x`
+   |
+LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x }
+   |                                             ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x }
+   |                     ~~~~~~~~~~~~
 
 error[E0621]: explicit lifetime required in the type of `x`
   --> $DIR/must_outlive_least_region_or_bound.rs:13:41
@@ -57,6 +71,15 @@ LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |               -                                       ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
    |               |
    |               let's call the lifetime of this reference `'1`
+   |
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
+   |                                       ++++
+help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
+   |                                                    ++++
 
 error: lifetime may not live long enough
   --> $DIR/must_outlive_least_region_or_bound.rs:29:69
@@ -64,7 +87,14 @@ error: lifetime may not live long enough
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |               -- lifetime `'a` defined here                         ^ returning this value requires that `'a` must outlive `'static`
    |
-   = help: consider replacing `'a` with `'static`
+help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x`
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x }
+   |                                                           ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |                      ~~~~~~~~~~~~
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/must_outlive_least_region_or_bound.rs:34:5
diff --git a/src/test/ui/issues/issue-16922.nll.stderr b/src/test/ui/issues/issue-16922.nll.stderr
index 7f4f5b22eb3..9d9f32a97c0 100644
--- a/src/test/ui/issues/issue-16922.nll.stderr
+++ b/src/test/ui/issues/issue-16922.nll.stderr
@@ -5,6 +5,11 @@ LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
    |                       - let's call the lifetime of this reference `'1`
 LL |     Box::new(value) as Box<dyn Any>
    |     ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> {
+   |                                          ++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr
index 42d89cd01a4..c5d2ec08409 100644
--- a/src/test/ui/issues/issue-29124.stderr
+++ b/src/test/ui/issues/issue-29124.stderr
@@ -2,17 +2,17 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in
   --> $DIR/issue-29124.rs:15:15
    |
 LL |     Obj::func.x();
-   |               ^ method not found in `fn() -> Ret {Obj::func}`
-   |
-   = note: `Obj::func` is a function, perhaps you wish to call it
+   |     --------- ^ method not found in `fn() -> Ret {Obj::func}`
+   |     |
+   |     this is a function, perhaps you wish to call it
 
 error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope
   --> $DIR/issue-29124.rs:17:10
    |
 LL |     func.x();
-   |          ^ method not found in `fn() -> Ret {func}`
-   |
-   = note: `func` is a function, perhaps you wish to call it
+   |     ---- ^ method not found in `fn() -> Ret {func}`
+   |     |
+   |     this is a function, perhaps you wish to call it
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr
index 5c611cd43d3..8e19f14009a 100644
--- a/src/test/ui/issues/issue-57362-1.stderr
+++ b/src/test/ui/issues/issue-57362-1.stderr
@@ -2,9 +2,10 @@ error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current
   --> $DIR/issue-57362-1.rs:20:7
    |
 LL |     a.f();
-   |       ^ method not found in `fn(&u8)`
+   |     - ^ method not found in `fn(&u8)`
+   |     |
+   |     this is a function, perhaps you wish to call it
    |
-   = note: `a` is a function, perhaps you wish to call it
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `Trait` defines an item `f`, perhaps you need to implement it
   --> $DIR/issue-57362-1.rs:8:1
diff --git a/src/test/ui/nll/mir_check_cast_unsize.stderr b/src/test/ui/nll/mir_check_cast_unsize.stderr
index 364d6c17ea7..8d02ef71d1b 100644
--- a/src/test/ui/nll/mir_check_cast_unsize.stderr
+++ b/src/test/ui/nll/mir_check_cast_unsize.stderr
@@ -5,6 +5,11 @@ LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
    |        -- lifetime `'a` defined here
 LL |     x
    |     ^ returning this value requires that `'a` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
+   |
+LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug + 'a {
+   |                                              ++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
index ae02c58d080..43695a7511d 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
@@ -6,6 +6,11 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
 ...
 LL |     ss.r
    |     ^^^^ returning this value requires that `'1` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
+   |                                                   ++++
 
 error[E0507]: cannot move out of `ss.r` which is behind a mutable reference
   --> $DIR/object-lifetime-default-from-box-error.rs:18:5
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
index 4d72724586e..724b06ce8b1 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
@@ -5,6 +5,15 @@ LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
    |         - let's call the lifetime of this reference `'1`
 LL |     let x: Box<dyn Foo + 'static> = Box::new(v);
    |            ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
+   |
+LL | fn a(v: &[u8]) -> Box<dyn Foo + '_> {
+   |                                 ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn a(v: &'static [u8]) -> Box<dyn Foo + 'static> {
+   |         ~~~~~~~~~~~~~
 
 error: lifetime may not live long enough
   --> $DIR/region-object-lifetime-in-coercion.rs:19:5
@@ -13,6 +22,15 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
    |         - let's call the lifetime of this reference `'1`
 LL |     Box::new(v)
    |     ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
+   |
+LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> {
+   |                                 ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn b(v: &'static [u8]) -> Box<dyn Foo + 'static> {
+   |         ~~~~~~~~~~~~~
 
 error: lifetime may not live long enough
   --> $DIR/region-object-lifetime-in-coercion.rs:27:5
@@ -22,6 +40,11 @@ LL | fn c(v: &[u8]) -> Box<dyn Foo> {
 ...
 LL |     Box::new(v)
    |     ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
+   |                               ++++
 
 error: lifetime may not live long enough
   --> $DIR/region-object-lifetime-in-coercion.rs:33:5
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
index 1a79da2776b..473c99b672f 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
@@ -5,6 +5,15 @@ LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
    |      -- lifetime `'a` defined here
 LL |     Box::new(B(&*v)) as Box<dyn X>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
+   |
+LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> {
+   |                                                            ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn g<'a, T: 'static>(v: Box<(dyn A<T> + 'static)>) -> Box<dyn X + 'static> {
+   |                         ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0515]: cannot return value referencing local data `*v`
   --> $DIR/regions-close-object-into-object-2.rs:13:5
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
index 993b13ddbf8..05ddc09b2d0 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
@@ -29,6 +29,15 @@ LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
    |      -- lifetime `'a` defined here
 LL |     Box::new(B(&*v)) as Box<dyn X>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
+   |
+LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> {
+   |                                                    ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn i<'a, T, U>(v: Box<(dyn A<U> + 'static)>) -> Box<dyn X + 'static> {
+   |                   ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0515]: cannot return value referencing local data `*v`
   --> $DIR/regions-close-object-into-object-4.rs:13:5
diff --git a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
index 6120a53eb09..ce4d2d4d111 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
@@ -6,6 +6,15 @@ LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
 LL |     // This is illegal, because the region bound on `proc` is 'static.
 LL |     Box::new(move || { *x })
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
+   |
+LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> {
+   |                                                           ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn static_proc(x: &'static isize) -> Box<dyn FnMut() -> (isize) + 'static> {
+   |                   ~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
index 3ed3827b97d..6c65e4f0175 100644
--- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
@@ -9,10 +9,14 @@ LL | |             remaining: self.0.iter(),
 LL | |         }
    | |_________^ returning this value requires that `'1` must outlive `'static`
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
    |
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
    |                                                          ++++
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
+   |
+LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> {
+   |                                                        ++++
 
 error: lifetime may not live long enough
   --> $DIR/trait-object-nested-in-impl-trait.rs:39:9
@@ -24,6 +28,11 @@ LL | |             current: None,
 LL | |             remaining: self.0.iter(),
 LL | |         }
    | |_________^ returning this value requires that `'1` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
+   |
+LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ {
+   |                                                        ++++
 
 error: lifetime may not live long enough
   --> $DIR/trait-object-nested-in-impl-trait.rs:50:9
@@ -35,6 +44,11 @@ LL | |             current: None,
 LL | |             remaining: self.0.iter(),
 LL | |         }
    | |_________^ returning this value requires that `'a` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
+   |
+LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a {
+   |                                                               ++++
 
 error: lifetime may not live long enough
   --> $DIR/trait-object-nested-in-impl-trait.rs:61:9
@@ -47,10 +61,14 @@ LL | |             remaining: self.0.iter(),
 LL | |         }
    | |_________^ returning this value requires that `'a` must outlive `'static`
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
+help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound
    |
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
    |                                                                 ++++
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
+   |
+LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> {
+   |                                                               ++++
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.rs b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs
new file mode 100644
index 00000000000..1875d8280cb
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs
@@ -0,0 +1,14 @@
+struct Bar<T> {
+    bar: T
+}
+
+struct Foo();
+impl Foo {
+    fn foo() { }
+}
+
+fn main() {
+    let thing = Bar { bar: Foo };
+    thing.bar.foo();
+    //~^ ERROR no method named `foo` found for fn item `fn() -> Foo {Foo}` in the current scope [E0599]
+}
diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
new file mode 100644
index 00000000000..6ed70b301e4
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
@@ -0,0 +1,16 @@
+error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the current scope
+  --> $DIR/empty-tuple-method.rs:12:15
+   |
+LL |     thing.bar.foo();
+   |     --------- ^^^ method not found in `fn() -> Foo {Foo}`
+   |     |
+   |     this is the constructor of a struct
+   |
+help: call the constructor
+   |
+LL |     (thing.bar)().foo();
+   |     +         +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/typeck/issue-87181/enum-variant.rs b/src/test/ui/typeck/issue-87181/enum-variant.rs
new file mode 100644
index 00000000000..3b926b90f10
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/enum-variant.rs
@@ -0,0 +1,16 @@
+struct Bar<T> {
+    bar: T
+}
+
+enum Foo{
+    Tup()
+}
+impl Foo {
+    fn foo() { }
+}
+
+fn main() {
+    let thing = Bar { bar: Foo::Tup };
+    thing.bar.foo();
+    //~^ ERROR no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` in the current scope [E0599]
+}
diff --git a/src/test/ui/typeck/issue-87181/enum-variant.stderr b/src/test/ui/typeck/issue-87181/enum-variant.stderr
new file mode 100644
index 00000000000..a3a818696ab
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/enum-variant.stderr
@@ -0,0 +1,16 @@
+error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` in the current scope
+  --> $DIR/enum-variant.rs:14:15
+   |
+LL |     thing.bar.foo();
+   |     --------- ^^^ method not found in `fn() -> Foo {Foo::Tup}`
+   |     |
+   |     this is the constructor of an enum variant
+   |
+help: call the constructor
+   |
+LL |     (thing.bar)().foo();
+   |     +         +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/typeck/issue-87181/tuple-field.rs b/src/test/ui/typeck/issue-87181/tuple-field.rs
new file mode 100644
index 00000000000..00e3b460ecf
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/tuple-field.rs
@@ -0,0 +1,14 @@
+struct Bar<T> {
+    bar: T
+}
+
+struct Foo(char, u16);
+impl Foo {
+    fn foo() { }
+}
+
+fn main() {
+    let thing = Bar { bar: Foo };
+    thing.bar.0;
+    //~^ ERROR no field `0` on type `fn(char, u16) -> Foo {Foo}` [E0609]
+}
diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr
new file mode 100644
index 00000000000..4d22ada0247
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr
@@ -0,0 +1,16 @@
+error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}`
+  --> $DIR/tuple-field.rs:12:15
+   |
+LL |     thing.bar.0;
+   |     --------- ^
+   |     |
+   |     this is the constructor of a struct
+   |
+help: call the constructor
+   |
+LL |     (thing.bar)(_, _).0;
+   |     +         +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/typeck/issue-87181/tuple-method.rs b/src/test/ui/typeck/issue-87181/tuple-method.rs
new file mode 100644
index 00000000000..e88f642b070
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/tuple-method.rs
@@ -0,0 +1,14 @@
+struct Bar<T> {
+    bar: T
+}
+
+struct Foo(u8, i32);
+impl Foo {
+    fn foo() { }
+}
+
+fn main() {
+    let thing = Bar { bar: Foo };
+    thing.bar.foo();
+    //~^ ERROR no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}` in the current scope [E0599]
+}
diff --git a/src/test/ui/typeck/issue-87181/tuple-method.stderr b/src/test/ui/typeck/issue-87181/tuple-method.stderr
new file mode 100644
index 00000000000..1e392e17984
--- /dev/null
+++ b/src/test/ui/typeck/issue-87181/tuple-method.stderr
@@ -0,0 +1,16 @@
+error[E0599]: no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}` in the current scope
+  --> $DIR/tuple-method.rs:12:15
+   |
+LL |     thing.bar.foo();
+   |     --------- ^^^ method not found in `fn(u8, i32) -> Foo {Foo}`
+   |     |
+   |     this is the constructor of a struct
+   |
+help: call the constructor
+   |
+LL |     (thing.bar)(_, _).foo();
+   |     +         +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
index 0b6d94e71f0..e9883903674 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
@@ -2,9 +2,9 @@ error[E0599]: no method named `call` found for closure `[closure@$DIR/unboxed-cl
   --> $DIR/unboxed-closures-static-call-wrong-trait.rs:7:10
    |
 LL |     mut_.call((0, ));
-   |          ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]`
-   |
-   = note: `mut_` is a function, perhaps you wish to call it
+   |     ---- ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]`
+   |     |
+   |     this is a function, perhaps you wish to call it
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
index 53d45f6a8f2..0ffb77cf021 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
@@ -6,6 +6,11 @@ LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
 LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
 LL |     Box::new(items.iter())
    |     ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
+   |                                                   ++++
 
 error: aborting due to previous error