about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-03-03 04:28:08 +0000
committerbors <bors@rust-lang.org>2022-03-03 04:28:08 +0000
commit2f8d1a835b4e7feaf625f74d0d5cb9b84dbc845a (patch)
tree58c9e240fbbb366d99880f74d49ab390c79285fb /src
parent8769f4ef2fe1efddd1f072485f97f568e7328f79 (diff)
parent878a4ff90e5987027f8ce3d350faaad02e0c83c9 (diff)
downloadrust-2f8d1a835b4e7feaf625f74d0d5cb9b84dbc845a.tar.gz
rust-2f8d1a835b4e7feaf625f74d0d5cb9b84dbc845a.zip
Auto merge of #94541 - Dylan-DPC:rollup-564wbq3, r=Dylan-DPC
Rollup of 9 pull requests

Successful merges:

 - #92061 (update char signess for openbsd)
 - #93072 (Compatible variants suggestion with desugaring)
 - #93354 (Add documentation about `BorrowedFd::to_owned`.)
 - #93663 (Rename `BorrowedFd::borrow_raw_fd` to `BorrowedFd::borrow_raw`.)
 - #94375 (Adt copy suggestions)
 - #94433 (Improve allowness of the unexpected_cfgs lint)
 - #94499 (Documentation was missed when demoting Windows XP to no_std only)
 - #94505 (Restore the local filter on mono item sorting)
 - #94529 (Unused doc comments blocks)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
-rw-r--r--src/doc/rustc/src/platform-support.md6
-rw-r--r--src/test/codegen/debuginfo-generic-closure-env-names.rs18
-rw-r--r--src/test/ui/async-await/proper-span-for-type-error.fixed3
-rw-r--r--src/test/ui/async-await/proper-span-for-type-error.stderr7
-rw-r--r--src/test/ui/check-cfg/allow-macro-cfg.rs14
-rw-r--r--src/test/ui/check-cfg/allow-same-level.rs11
-rw-r--r--src/test/ui/check-cfg/allow-same-level.stderr10
-rw-r--r--src/test/ui/check-cfg/allow-top-level.rs15
-rw-r--r--src/test/ui/check-cfg/allow-upper-level.rs12
-rw-r--r--src/test/ui/did_you_mean/compatible-variants.rs15
-rw-r--r--src/test/ui/did_you_mean/compatible-variants.stderr61
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs14
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr28
-rw-r--r--src/test/ui/moves/use_of_moved_value_clone_suggestions.rs6
-rw-r--r--src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr13
-rw-r--r--src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed72
-rw-r--r--src/test/ui/moves/use_of_moved_value_copy_suggestions.rs72
-rw-r--r--src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr147
18 files changed, 499 insertions, 25 deletions
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index d7e0b9d50f0..4c05818440b 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -139,7 +139,7 @@ target | std | notes
 `armv7r-none-eabi` | * | Bare ARMv7-R
 `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat
 `asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten
-`i586-pc-windows-msvc` | ✓ | 32-bit Windows w/o SSE
+`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE
 `i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
 `i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL
 `i686-linux-android` | ✓ | 32-bit x86 Android
@@ -236,7 +236,7 @@ target | std | host | notes
 `hexagon-unknown-linux-musl` | ? |  |
 `i386-apple-ios` | ✓ |  | 32-bit x86 iOS
 `i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+)
-`i686-pc-windows-msvc` | ✓ |  | 32-bit Windows XP support
+`i686-pc-windows-msvc` | * |  | 32-bit Windows XP support
 `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
 `i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2
 [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD
@@ -283,7 +283,7 @@ target | std | host | notes
 [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? |  | WebAssembly
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
 `x86_64-apple-tvos` | * | | x86 64-bit tvOS
-`x86_64-pc-windows-msvc` | ✓ |  | 64-bit Windows XP support
+`x86_64-pc-windows-msvc` | * |  | 64-bit Windows XP support
 `x86_64-sun-solaris` | ? |  | Deprecated target for 64-bit Solaris 10/11, illumos
 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
 `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
diff --git a/src/test/codegen/debuginfo-generic-closure-env-names.rs b/src/test/codegen/debuginfo-generic-closure-env-names.rs
index ad59f740b56..b29f8b4a029 100644
--- a/src/test/codegen/debuginfo-generic-closure-env-names.rs
+++ b/src/test/codegen/debuginfo-generic-closure-env-names.rs
@@ -3,7 +3,7 @@
 // of the enclosing functions don't get lost.
 //
 // Unfortunately, the order that debuginfo gets emitted into LLVM IR becomes a bit hard
-// to predict once async fns are involved.
+// to predict once async fns are involved, so DAG allows any order.
 //
 // Note that the test does not check async-fns when targeting MSVC because debuginfo for
 // those does not follow the enum-fallback encoding yet and thus is incomplete.
@@ -27,24 +27,24 @@
 // CHECK: ![[generic_async_block_NAMESPACE:[0-9]+]] = !DINamespace(name: "generic_async_block"
 
 // function_containing_closure<u32>()
-// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<u32>", scope: ![[function_containing_closure_NAMESPACE]]
-// MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<u32>", scope: ![[function_containing_closure_NAMESPACE]]
+// NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<u32>", scope: ![[function_containing_closure_NAMESPACE]]
+// MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<u32>", scope: ![[function_containing_closure_NAMESPACE]]
 
 // generic_async_function<Foo>()
-// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_function_NAMESPACE]]
+// NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_function_NAMESPACE]]
 
 // generic_async_function<u32>()
-// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<u32>", scope: ![[generic_async_function_NAMESPACE]]
+// NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}<u32>", scope: ![[generic_async_function_NAMESPACE]]
 
 // generic_async_block<Foo>()
-// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_block_NAMESPACE]]
+// NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[generic_async_block_NAMESPACE]]
 
 // generic_async_block<u32>()
-// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<u32>", scope: ![[generic_async_block_NAMESPACE]]
+// NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{async_block_env#0}<u32>", scope: ![[generic_async_block_NAMESPACE]]
 
 // function_containing_closure<Foo>()
-// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
-// MSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
+// NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
+// MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0<debuginfo_generic_closure_env_names::Foo>", scope: ![[function_containing_closure_NAMESPACE]]
 
 
 #![crate_type = "lib"]
diff --git a/src/test/ui/async-await/proper-span-for-type-error.fixed b/src/test/ui/async-await/proper-span-for-type-error.fixed
index 1f1e1184dcc..7d43b575d2f 100644
--- a/src/test/ui/async-await/proper-span-for-type-error.fixed
+++ b/src/test/ui/async-await/proper-span-for-type-error.fixed
@@ -5,7 +5,8 @@
 async fn a() {}
 
 async fn foo() -> Result<(), i32> {
-    Ok(a().await) //~ ERROR mismatched types
+    a().await;
+    Ok(()) //~ ERROR mismatched types
 }
 
 fn main() {}
diff --git a/src/test/ui/async-await/proper-span-for-type-error.stderr b/src/test/ui/async-await/proper-span-for-type-error.stderr
index 611dc0407bf..25f05156ce2 100644
--- a/src/test/ui/async-await/proper-span-for-type-error.stderr
+++ b/src/test/ui/async-await/proper-span-for-type-error.stderr
@@ -6,10 +6,11 @@ LL |     a().await
    |
    = note:   expected enum `Result<(), i32>`
            found unit type `()`
-help: try wrapping the expression in `Ok`
+help: try adding an expression at the end of the block
+   |
+LL ~     a().await;
+LL ~     Ok(())
    |
-LL |     Ok(a().await)
-   |     +++         +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/check-cfg/allow-macro-cfg.rs b/src/test/ui/check-cfg/allow-macro-cfg.rs
new file mode 100644
index 00000000000..8016a4d190c
--- /dev/null
+++ b/src/test/ui/check-cfg/allow-macro-cfg.rs
@@ -0,0 +1,14 @@
+// This test check that local #[allow(unexpected_cfgs)] works
+//
+// check-pass
+// compile-flags:--check-cfg=names() -Z unstable-options
+
+#[allow(unexpected_cfgs)]
+fn foo() {
+    if cfg!(FALSE) {}
+}
+
+fn main() {
+    #[allow(unexpected_cfgs)]
+    if cfg!(FALSE) {}
+}
diff --git a/src/test/ui/check-cfg/allow-same-level.rs b/src/test/ui/check-cfg/allow-same-level.rs
new file mode 100644
index 00000000000..6c869dc4202
--- /dev/null
+++ b/src/test/ui/check-cfg/allow-same-level.rs
@@ -0,0 +1,11 @@
+// This test check that #[allow(unexpected_cfgs)] doesn't work if put on the same level
+//
+// check-pass
+// compile-flags:--check-cfg=names() -Z unstable-options
+
+#[allow(unexpected_cfgs)]
+#[cfg(FALSE)]
+//~^ WARNING unexpected `cfg` condition name
+fn bar() {}
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/allow-same-level.stderr b/src/test/ui/check-cfg/allow-same-level.stderr
new file mode 100644
index 00000000000..7797de584b9
--- /dev/null
+++ b/src/test/ui/check-cfg/allow-same-level.stderr
@@ -0,0 +1,10 @@
+warning: unexpected `cfg` condition name
+  --> $DIR/allow-same-level.rs:7:7
+   |
+LL | #[cfg(FALSE)]
+   |       ^^^^^
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/check-cfg/allow-top-level.rs b/src/test/ui/check-cfg/allow-top-level.rs
new file mode 100644
index 00000000000..d14b0eae5cc
--- /dev/null
+++ b/src/test/ui/check-cfg/allow-top-level.rs
@@ -0,0 +1,15 @@
+// This test check that a top-level #![allow(unexpected_cfgs)] works
+//
+// check-pass
+// compile-flags:--check-cfg=names() -Z unstable-options
+
+#![allow(unexpected_cfgs)]
+
+#[cfg(FALSE)]
+fn bar() {}
+
+fn foo() {
+    if cfg!(FALSE) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/allow-upper-level.rs b/src/test/ui/check-cfg/allow-upper-level.rs
new file mode 100644
index 00000000000..04340694d9c
--- /dev/null
+++ b/src/test/ui/check-cfg/allow-upper-level.rs
@@ -0,0 +1,12 @@
+// This test check that #[allow(unexpected_cfgs)] work if put on an upper level
+//
+// check-pass
+// compile-flags:--check-cfg=names() -Z unstable-options
+
+#[allow(unexpected_cfgs)]
+mod aa {
+    #[cfg(FALSE)]
+    fn bar() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/compatible-variants.rs b/src/test/ui/did_you_mean/compatible-variants.rs
index a70dda8386f..b078064b267 100644
--- a/src/test/ui/did_you_mean/compatible-variants.rs
+++ b/src/test/ui/did_you_mean/compatible-variants.rs
@@ -23,6 +23,21 @@ fn b() -> Result<(), ()> {
     //~| HELP try adding an expression
 }
 
+fn c() -> Option<()> {
+    for _ in [1, 2] {
+        //~^ ERROR mismatched types
+        f();
+    }
+    //~^ HELP try adding an expression
+}
+
+fn d() -> Option<()> {
+    c()?
+    //~^ ERROR incompatible types
+    //~| HELP try removing this `?`
+    //~| HELP try adding an expression
+}
+
 fn main() {
     let _: Option<()> = while false {};
     //~^ ERROR mismatched types
diff --git a/src/test/ui/did_you_mean/compatible-variants.stderr b/src/test/ui/did_you_mean/compatible-variants.stderr
index 0dfd8f5c128..51c1bf97c4e 100644
--- a/src/test/ui/did_you_mean/compatible-variants.stderr
+++ b/src/test/ui/did_you_mean/compatible-variants.stderr
@@ -37,7 +37,52 @@ LL +     Ok(())
    |
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:27:25
+  --> $DIR/compatible-variants.rs:27:5
+   |
+LL |   fn c() -> Option<()> {
+   |             ---------- expected `Option<()>` because of return type
+LL | /     for _ in [1, 2] {
+LL | |
+LL | |         f();
+LL | |     }
+   | |_____^ expected enum `Option`, found `()`
+   |
+   = note:   expected enum `Option<()>`
+           found unit type `()`
+help: try adding an expression at the end of the block
+   |
+LL ~     }
+LL +     None
+   |
+LL ~     }
+LL +     Some(())
+   |
+
+error[E0308]: `?` operator has incompatible types
+  --> $DIR/compatible-variants.rs:35:5
+   |
+LL |     c()?
+   |     ^^^^ expected enum `Option`, found `()`
+   |
+   = note: `?` operator cannot convert from `()` to `Option<()>`
+   = note:   expected enum `Option<()>`
+           found unit type `()`
+help: try removing this `?`
+   |
+LL -     c()?
+LL +     c()
+   | 
+help: try adding an expression at the end of the block
+   |
+LL ~     c()?;
+LL +     None
+   |
+LL ~     c()?;
+LL +     Some(())
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/compatible-variants.rs:42:25
    |
 LL |     let _: Option<()> = while false {};
    |            ----------   ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
@@ -52,7 +97,7 @@ LL |     let _: Option<()> = Some(while false {});
    |                         +++++              +
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:31:9
+  --> $DIR/compatible-variants.rs:46:9
    |
 LL |         while false {}
    |         ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
@@ -69,7 +114,7 @@ LL +         Some(())
    |
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:35:31
+  --> $DIR/compatible-variants.rs:50:31
    |
 LL |     let _: Result<i32, i32> = 1;
    |            ----------------   ^ expected enum `Result`, found integer
@@ -86,7 +131,7 @@ LL |     let _: Result<i32, i32> = Err(1);
    |                               ++++ +
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:38:26
+  --> $DIR/compatible-variants.rs:53:26
    |
 LL |     let _: Option<i32> = 1;
    |            -----------   ^ expected enum `Option`, found integer
@@ -101,7 +146,7 @@ LL |     let _: Option<i32> = Some(1);
    |                          +++++ +
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:41:28
+  --> $DIR/compatible-variants.rs:56:28
    |
 LL |     let _: Hey<i32, i32> = 1;
    |            -------------   ^ expected enum `Hey`, found integer
@@ -118,7 +163,7 @@ LL |     let _: Hey<i32, i32> = Hey::B(1);
    |                            +++++++ +
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:44:29
+  --> $DIR/compatible-variants.rs:59:29
    |
 LL |     let _: Hey<i32, bool> = false;
    |            --------------   ^^^^^ expected enum `Hey`, found `bool`
@@ -133,7 +178,7 @@ LL |     let _: Hey<i32, bool> = Hey::B(false);
    |                             +++++++     +
 
 error[E0308]: mismatched types
-  --> $DIR/compatible-variants.rs:48:19
+  --> $DIR/compatible-variants.rs:63:19
    |
 LL |     let _ = Foo { bar };
    |                   ^^^ expected enum `Option`, found `i32`
@@ -145,6 +190,6 @@ help: try wrapping the expression in `Some`
 LL |     let _ = Foo { bar: Some(bar) };
    |                   ++++++++++   +
 
-error: aborting due to 9 previous errors
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs
index 258f9e4831f..54d86c31fb4 100644
--- a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs
+++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs
@@ -29,4 +29,18 @@ fn doc_comment_on_expr(num: u8) -> bool {
 fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {}
 //~^ ERROR: unused doc comment
 
+fn doc_comment_on_block() {
+    /// unused doc comment
+    //~^ ERROR: unused doc comment
+    {
+        let x = 12;
+    }
+}
+
+/// unused doc comment
+//~^ ERROR: unused doc comment
+extern "C" {
+    fn foo();
+}
+
 fn main() {}
diff --git a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
index 3ce1df71a2e..30a96af583a 100644
--- a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
+++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
@@ -49,6 +49,32 @@ LL | fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {}
    |
    = help: use `//` for a plain comment
 
+error: unused doc comment
+  --> $DIR/unused-doc-comments-edge-cases.rs:33:5
+   |
+LL |       /// unused doc comment
+   |       ^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | /     {
+LL | |         let x = 12;
+LL | |     }
+   | |_____- rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/unused-doc-comments-edge-cases.rs:40:1
+   |
+LL |   /// unused doc comment
+   |   ^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / extern "C" {
+LL | |     fn foo();
+LL | | }
+   | |_- rustdoc does not generate documentation for extern block
+   |
+   = help: use `//` for a plain comment
+
 error[E0308]: mismatched types
   --> $DIR/unused-doc-comments-edge-cases.rs:14:9
    |
@@ -63,7 +89,7 @@ help: you might have meant to return this value
 LL |         return true;
    |         ++++++     +
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0308, E0658.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/moves/use_of_moved_value_clone_suggestions.rs b/src/test/ui/moves/use_of_moved_value_clone_suggestions.rs
new file mode 100644
index 00000000000..d5c8d4e6bdf
--- /dev/null
+++ b/src/test/ui/moves/use_of_moved_value_clone_suggestions.rs
@@ -0,0 +1,6 @@
+// `Rc` is not ever `Copy`, we should not suggest adding `T: Copy` constraint
+fn duplicate_rc<T>(t: std::rc::Rc<T>) -> (std::rc::Rc<T>, std::rc::Rc<T>) {
+    (t, t) //~ use of moved value: `t`
+}
+
+fn main() {}
diff --git a/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr b/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr
new file mode 100644
index 00000000000..c25981e6f80
--- /dev/null
+++ b/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_clone_suggestions.rs:3:9
+   |
+LL | fn duplicate_rc<T>(t: std::rc::Rc<T>) -> (std::rc::Rc<T>, std::rc::Rc<T>) {
+   |                    - move occurs because `t` has type `Rc<T>`, which does not implement the `Copy` trait
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed b/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed
new file mode 100644
index 00000000000..d31046c7700
--- /dev/null
+++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed
@@ -0,0 +1,72 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn duplicate_t<T: Copy>(t: T) -> (T, T) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_opt<T: Copy>(t: Option<T>) -> (Option<T>, Option<T>) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_tup1<T: Copy>(t: (T,)) -> ((T,), (T,)) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_tup2<A: Copy, B: Copy>(t: (A, B)) -> ((A, B), (A, B)) {
+    //~^ HELP consider restricting type parameters
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+struct S<T>(T);
+trait Trait {}
+impl<T: Trait + Clone> Clone for S<T> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+impl<T: Trait + Copy> Copy for S<T> {}
+
+trait A {}
+trait B {}
+
+// Test where bounds are added with different bound placements
+fn duplicate_custom_1<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) where {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom_2<T>(t: S<T>) -> (S<T>, S<T>)
+where
+    T: A + Trait + Copy,
+    //~^ HELP consider further restricting this bound
+{
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>)
+where
+    T: A,
+    T: B, T: Trait, T: Copy
+    //~^ HELP consider further restricting type parameter `T`
+{
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom_4<T: A>(t: S<T>) -> (S<T>, S<T>)
+where
+    T: B + Trait + Copy,
+    //~^ HELP consider further restricting this bound
+{
+    (t, t) //~ use of moved value: `t`
+}
+
+fn main() {}
diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs b/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs
new file mode 100644
index 00000000000..7cc5189fac0
--- /dev/null
+++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs
@@ -0,0 +1,72 @@
+// run-rustfix
+#![allow(dead_code)]
+
+fn duplicate_t<T>(t: T) -> (T, T) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_opt<T>(t: Option<T>) -> (Option<T>, Option<T>) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_tup1<T>(t: (T,)) -> ((T,), (T,)) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_tup2<A, B>(t: (A, B)) -> ((A, B), (A, B)) {
+    //~^ HELP consider restricting type parameters
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom<T>(t: S<T>) -> (S<T>, S<T>) {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+struct S<T>(T);
+trait Trait {}
+impl<T: Trait + Clone> Clone for S<T> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+impl<T: Trait + Copy> Copy for S<T> {}
+
+trait A {}
+trait B {}
+
+// Test where bounds are added with different bound placements
+fn duplicate_custom_1<T>(t: S<T>) -> (S<T>, S<T>) where {
+    //~^ HELP consider restricting type parameter `T`
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom_2<T>(t: S<T>) -> (S<T>, S<T>)
+where
+    T: A,
+    //~^ HELP consider further restricting this bound
+{
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>)
+where
+    T: A,
+    T: B,
+    //~^ HELP consider further restricting type parameter `T`
+{
+    (t, t) //~ use of moved value: `t`
+}
+
+fn duplicate_custom_4<T: A>(t: S<T>) -> (S<T>, S<T>)
+where
+    T: B,
+    //~^ HELP consider further restricting this bound
+{
+    (t, t) //~ use of moved value: `t`
+}
+
+fn main() {}
diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr b/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr
new file mode 100644
index 00000000000..8e72697ca30
--- /dev/null
+++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr
@@ -0,0 +1,147 @@
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:6:9
+   |
+LL | fn duplicate_t<T>(t: T) -> (T, T) {
+   |                   - move occurs because `t` has type `T`, which does not implement the `Copy` trait
+LL |
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider restricting type parameter `T`
+   |
+LL | fn duplicate_t<T: Copy>(t: T) -> (T, T) {
+   |                 ++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:11:9
+   |
+LL | fn duplicate_opt<T>(t: Option<T>) -> (Option<T>, Option<T>) {
+   |                     - move occurs because `t` has type `Option<T>`, which does not implement the `Copy` trait
+LL |
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider restricting type parameter `T`
+   |
+LL | fn duplicate_opt<T: Copy>(t: Option<T>) -> (Option<T>, Option<T>) {
+   |                   ++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:16:9
+   |
+LL | fn duplicate_tup1<T>(t: (T,)) -> ((T,), (T,)) {
+   |                      - move occurs because `t` has type `(T,)`, which does not implement the `Copy` trait
+LL |
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider restricting type parameter `T`
+   |
+LL | fn duplicate_tup1<T: Copy>(t: (T,)) -> ((T,), (T,)) {
+   |                    ++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:21:9
+   |
+LL | fn duplicate_tup2<A, B>(t: (A, B)) -> ((A, B), (A, B)) {
+   |                         - move occurs because `t` has type `(A, B)`, which does not implement the `Copy` trait
+LL |
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider restricting type parameters
+   |
+LL | fn duplicate_tup2<A: Copy, B: Copy>(t: (A, B)) -> ((A, B), (A, B)) {
+   |                    ++++++   ++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:26:9
+   |
+LL | fn duplicate_custom<T>(t: S<T>) -> (S<T>, S<T>) {
+   |                        - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
+LL |
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider restricting type parameter `T`
+   |
+LL | fn duplicate_custom<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) {
+   |                      ++++++++++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:44:9
+   |
+LL | fn duplicate_custom_1<T>(t: S<T>) -> (S<T>, S<T>) where {
+   |                          - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
+LL |
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider restricting type parameter `T`
+   |
+LL | fn duplicate_custom_1<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) where {
+   |                        ++++++++++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:52:9
+   |
+LL | fn duplicate_custom_2<T>(t: S<T>) -> (S<T>, S<T>)
+   |                          - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
+...
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider further restricting this bound
+   |
+LL |     T: A + Trait + Copy,
+   |          ++++++++++++++
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:61:9
+   |
+LL | fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>)
+   |                          - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
+...
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider further restricting type parameter `T`
+   |
+LL |     T: B, T: Trait, T: Copy
+   |         ~~~~~~~~~~~~~~~~~~~
+
+error[E0382]: use of moved value: `t`
+  --> $DIR/use_of_moved_value_copy_suggestions.rs:69:9
+   |
+LL | fn duplicate_custom_4<T: A>(t: S<T>) -> (S<T>, S<T>)
+   |                             - move occurs because `t` has type `S<T>`, which does not implement the `Copy` trait
+...
+LL |     (t, t)
+   |      -  ^ value used here after move
+   |      |
+   |      value moved here
+   |
+help: consider further restricting this bound
+   |
+LL |     T: B + Trait + Copy,
+   |          ++++++++++++++
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0382`.