about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/rustdoc-json/enums/discriminant/basic.rs12
-rw-r--r--src/test/rustdoc-json/enums/discriminant/expr.rs39
-rw-r--r--src/test/rustdoc-json/enums/discriminant/limits.rs43
-rw-r--r--src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs15
-rw-r--r--src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs10
-rw-r--r--src/test/ui/borrowck/issue-101119.rs16
-rw-r--r--src/test/ui/borrowck/issue-101119.stderr15
-rw-r--r--src/test/ui/consts/const-float-bits-reject-conv.stderr40
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace-std.rs6
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr2
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace.rs18
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr2
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.rs12
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.stderr79
-rw-r--r--src/test/ui/lint/issue-101284.rs15
-rw-r--r--src/test/ui/proc-macro/auxiliary/expand-expr.rs23
-rw-r--r--src/test/ui/stats/hir-stats.stderr328
-rw-r--r--src/test/ui/suggestions/copied-and-cloned.fixed23
-rw-r--r--src/test/ui/suggestions/copied-and-cloned.rs23
-rw-r--r--src/test/ui/suggestions/copied-and-cloned.stderr83
20 files changed, 580 insertions, 224 deletions
diff --git a/src/test/rustdoc-json/enums/discriminant/basic.rs b/src/test/rustdoc-json/enums/discriminant/basic.rs
new file mode 100644
index 00000000000..8c221615aa7
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/basic.rs
@@ -0,0 +1,12 @@
+#[repr(i8)]
+pub enum Ordering {
+    // @is "$.index[*][?(@.name=='Less')].inner.variant_inner.expr" '"-1"'
+    // @is "$.index[*][?(@.name=='Less')].inner.variant_inner.value" '"-1"'
+    Less = -1,
+    // @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.expr" '"0"'
+    // @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.value" '"0"'
+    Equal = 0,
+    // @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.expr" '"1"'
+    // @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.value" '"1"'
+    Greater = 1,
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/expr.rs b/src/test/rustdoc-json/enums/discriminant/expr.rs
new file mode 100644
index 00000000000..235b0b47381
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/expr.rs
@@ -0,0 +1,39 @@
+pub enum Foo {
+    // @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.value" '"0"'
+    // @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.expr" '"{ _ }"'
+    Addition = 0 + 0,
+    // @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.value" '"1"'
+    // @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.expr" '"0b1"'
+    Bin = 0b1,
+    // @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.value" '"2"'
+    // @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.expr" '"0o2"'
+    Oct = 0o2,
+    // @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.value" '"3"'
+    // @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.expr" '"THREE"'
+    PubConst = THREE,
+    // @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.value" '"4"'
+    // @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.expr" '"0x4"'
+    Hex = 0x4,
+    // @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.value" '"5"'
+    // @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.expr" '"{ _ }"'
+    Cast = 5 as isize,
+    // @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.value" '"6"'
+    // @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.expr" '"{ _ }"'
+    PubCall = six(),
+    // @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.value" '"7"'
+    // @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.expr" '"{ _ }"'
+    PrivCall = seven(),
+    // @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.value" '"8"'
+    // @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.expr" '"EIGHT"'
+    PrivConst = EIGHT,
+}
+
+pub const THREE: isize = 3;
+const EIGHT: isize = 8;
+
+pub const fn six() -> isize {
+    6
+}
+const fn seven() -> isize {
+    7
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/limits.rs b/src/test/rustdoc-json/enums/discriminant/limits.rs
new file mode 100644
index 00000000000..8df73d78d23
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/limits.rs
@@ -0,0 +1,43 @@
+// ignore-tidy-linelength
+#![feature(repr128)]
+#![allow(incomplete_features)]
+
+#[repr(u64)]
+pub enum U64 {
+    // @is "$.index[*][?(@.name=='U64Min')].inner.variant_inner.value" '"0"'
+    // @is "$.index[*][?(@.name=='U64Min')].inner.variant_inner.expr" '"u64::MIN"'
+    U64Min = u64::MIN,
+    // @is "$.index[*][?(@.name=='U64Max')].inner.variant_inner.value" '"18446744073709551615"'
+    // @is "$.index[*][?(@.name=='U64Max')].inner.variant_inner.expr" '"u64::MAX"'
+    U64Max = u64::MAX,
+}
+
+#[repr(i64)]
+pub enum I64 {
+    // @is "$.index[*][?(@.name=='I64Min')].inner.variant_inner.value" '"-9223372036854775808"'
+    // @is "$.index[*][?(@.name=='I64Min')].inner.variant_inner.expr" '"i64::MIN"'
+    I64Min = i64::MIN,
+    // @is "$.index[*][?(@.name=='I64Max')].inner.variant_inner.value" '"9223372036854775807"'
+    // @is "$.index[*][?(@.name=='I64Max')].inner.variant_inner.expr" '"i64::MAX"'
+    I64Max = i64::MAX,
+}
+
+#[repr(u128)]
+pub enum U128 {
+    // @is "$.index[*][?(@.name=='U128Min')].inner.variant_inner.value" '"0"'
+    // @is "$.index[*][?(@.name=='U128Min')].inner.variant_inner.expr" '"u128::MIN"'
+    U128Min = u128::MIN,
+    // @is "$.index[*][?(@.name=='U128Max')].inner.variant_inner.value" '"340282366920938463463374607431768211455"'
+    // @is "$.index[*][?(@.name=='U128Max')].inner.variant_inner.expr" '"u128::MAX"'
+    U128Max = u128::MAX,
+}
+
+#[repr(i128)]
+pub enum I128 {
+    // @is "$.index[*][?(@.name=='I128Min')].inner.variant_inner.value" '"-170141183460469231731687303715884105728"'
+    // @is "$.index[*][?(@.name=='I128Min')].inner.variant_inner.expr" '"i128::MIN"'
+    I128Min = i128::MIN,
+    // @is "$.index[*][?(@.name=='I128Max')].inner.variant_inner.value" '"170141183460469231731687303715884105727"'
+    // @is "$.index[*][?(@.name=='I128Max')].inner.variant_inner.expr" '"i128::MAX"'
+    I128Max = i128::MAX,
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
new file mode 100644
index 00000000000..3417baa0760
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
@@ -0,0 +1,15 @@
+#[repr(u32)]
+pub enum Foo {
+    // @is "$.index[*][?(@.name=='Basic')].inner.variant_inner.value" '"0"'
+    // @is "$.index[*][?(@.name=='Basic')].inner.variant_inner.expr" '"0"'
+    Basic = 0,
+    // @is "$.index[*][?(@.name=='Suffix')].inner.variant_inner.value" '"10"'
+    // @is "$.index[*][?(@.name=='Suffix')].inner.variant_inner.expr" '"10u32"'
+    Suffix = 10u32,
+    // @is "$.index[*][?(@.name=='Underscore')].inner.variant_inner.value" '"100"'
+    // @is "$.index[*][?(@.name=='Underscore')].inner.variant_inner.expr" '"1_0_0"'
+    Underscore = 1_0_0,
+    // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant_inner.value" '"1000"'
+    // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant_inner.expr" '"1_0_0_0u32"'
+    SuffixUnderscore = 1_0_0_0u32,
+}
diff --git a/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
new file mode 100644
index 00000000000..6af944a2219
--- /dev/null
+++ b/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
@@ -0,0 +1,10 @@
+pub enum Foo {
+    // @is "$.index[*][?(@.name=='Has')].inner.variant_inner" '{"expr":"0", "value":"0"}'
+    Has = 0,
+    // @is "$.index[*][?(@.name=='Doesnt')].inner.variant_inner" null
+    Doesnt,
+    // @is "$.index[*][?(@.name=='AlsoDoesnt')].inner.variant_inner" null
+    AlsoDoesnt,
+    // @is "$.index[*][?(@.name=='AlsoHas')].inner.variant_inner" '{"expr":"44", "value":"44"}'
+    AlsoHas = 44,
+}
diff --git a/src/test/ui/borrowck/issue-101119.rs b/src/test/ui/borrowck/issue-101119.rs
new file mode 100644
index 00000000000..64e52eaac06
--- /dev/null
+++ b/src/test/ui/borrowck/issue-101119.rs
@@ -0,0 +1,16 @@
+struct State;
+
+fn once(_: impl FnOnce()) {}
+
+fn fill_memory_blocks_mt(state: &mut State) {
+    loop {
+        once(move || {
+            //~^ ERROR use of moved value: `state`
+            fill_segment(state);
+        });
+    }
+}
+
+fn fill_segment(_: &mut State) {}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/issue-101119.stderr b/src/test/ui/borrowck/issue-101119.stderr
new file mode 100644
index 00000000000..a22afdc6764
--- /dev/null
+++ b/src/test/ui/borrowck/issue-101119.stderr
@@ -0,0 +1,15 @@
+error[E0382]: use of moved value: `state`
+  --> $DIR/issue-101119.rs:7:14
+   |
+LL | fn fill_memory_blocks_mt(state: &mut State) {
+   |                          ----- move occurs because `state` has type `&mut State`, which does not implement the `Copy` trait
+LL |     loop {
+LL |         once(move || {
+   |              ^^^^^^^ value moved into closure here, in previous iteration of loop
+LL |
+LL |             fill_segment(state);
+   |                          ----- use occurs due to use in closure
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr
index d6e993a1010..01f2f489564 100644
--- a/src/test/ui/consts/const-float-bits-reject-conv.stderr
+++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr
@@ -10,16 +10,6 @@ LL |                     panic!("const-eval error: cannot use f32::to_bits on a
 LL |         unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
    |                  -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL
    |
-  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-   |     ------------------------------------------------------------------ inside `<fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32} as FnOnce<(f32,)>>::call_once - shim(fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-  ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
-LL |     called_in_const.call_once(arg)
-   |     ------------------------------ inside `const_eval_select::<(f32,), fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32}, [closure@core::f32::<impl f32>::to_bits::{closure#0}], u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
   ::: $DIR/const-float-bits-reject-conv.rs:27:30
    |
 LL |     const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
@@ -39,16 +29,6 @@ LL |                     panic!("const-eval error: cannot use f32::to_bits on a
 LL |         unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
    |                  -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL
    |
-  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-   |     ------------------------------------------------------------------ inside `<fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32} as FnOnce<(f32,)>>::call_once - shim(fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-  ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
-LL |     called_in_const.call_once(arg)
-   |     ------------------------------ inside `const_eval_select::<(f32,), fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32}, [closure@core::f32::<impl f32>::to_bits::{closure#0}], u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
   ::: $DIR/const-float-bits-reject-conv.rs:28:30
    |
 LL |     const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
@@ -117,16 +97,6 @@ LL |                     panic!("const-eval error: cannot use f64::to_bits on a
 LL |         unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
    |                  -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL
    |
-  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-   |     ------------------------------------------------------------------ inside `<fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64} as FnOnce<(f64,)>>::call_once - shim(fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-  ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
-LL |     called_in_const.call_once(arg)
-   |     ------------------------------ inside `const_eval_select::<(f64,), fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64}, [closure@core::f64::<impl f64>::to_bits::{closure#0}], u64>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
   ::: $DIR/const-float-bits-reject-conv.rs:54:30
    |
 LL |     const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
@@ -146,16 +116,6 @@ LL |                     panic!("const-eval error: cannot use f64::to_bits on a
 LL |         unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
    |                  -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL
    |
-  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-   |     ------------------------------------------------------------------ inside `<fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64} as FnOnce<(f64,)>>::call_once - shim(fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64})` at $SRC_DIR/core/src/ops/function.rs:LL:COL
-   |
-  ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
-LL |     called_in_const.call_once(arg)
-   |     ------------------------------ inside `const_eval_select::<(f64,), fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64}, [closure@core::f64::<impl f64>::to_bits::{closure#0}], u64>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-   |
   ::: $DIR/const-float-bits-reject-conv.rs:55:30
    |
 LL |     const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
new file mode 100644
index 00000000000..29aefe07162
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
@@ -0,0 +1,6 @@
+// See issue #100696.
+// run-fail
+// check-run-results
+fn main() {
+    &""[1..];
+}
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
new file mode 100644
index 00000000000..e53e6034620
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
@@ -0,0 +1,2 @@
+thread 'main' panicked at 'byte index 1 is out of bounds of ``', $DIR/const-eval-select-backtrace-std.rs:5:6
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace.rs b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
new file mode 100644
index 00000000000..99f0725200c
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
@@ -0,0 +1,18 @@
+#![feature(core_intrinsics)]
+// See issue #100696.
+// run-fail
+// check-run-results
+
+#[track_caller]
+fn uhoh() {
+    panic!("Aaah!")
+}
+
+const fn c() {}
+
+fn main() {
+    // safety: this is unsound and just used to test
+    unsafe {
+        std::intrinsics::const_eval_select((), c, uhoh);
+    }
+}
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
new file mode 100644
index 00000000000..2fd730ac7a6
--- /dev/null
+++ b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
@@ -0,0 +1,2 @@
+thread 'main' panicked at 'Aaah!', $DIR/const-eval-select-backtrace.rs:16:9
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.rs b/src/test/ui/intrinsics/const-eval-select-bad.rs
index e5640f5ab53..fa14efad7b4 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.rs
+++ b/src/test/ui/intrinsics/const-eval-select-bad.rs
@@ -5,10 +5,13 @@ use std::intrinsics::const_eval_select;
 
 const fn not_fn_items() {
     const_eval_select((), || {}, || {});
-    //~^ ERROR the trait bound
+    //~^ ERROR this argument must be a function item
+    //~| ERROR this argument must be a function item
     const_eval_select((), 42, 0xDEADBEEF);
-    //~^ ERROR the trait bound
+    //~^ ERROR expected a `FnOnce<()>` closure
     //~| ERROR expected a `FnOnce<()>` closure
+    //~| ERROR this argument must be a function item
+    //~| ERROR this argument must be a function item
 }
 
 const fn foo(n: i32) -> i32 {
@@ -35,4 +38,9 @@ const fn args_ty_mismatch() {
     //~^ ERROR type mismatch
 }
 
+const fn non_const_fn() {
+    const_eval_select((1,), bar, bar);
+    //~^ ERROR this argument must be a `const fn`
+}
+
 fn main() {}
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index 904e83624b3..3720528ad4e 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -1,42 +1,57 @@
-error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]: FnOnce<()>` is not satisfied
+error: this argument must be a function item
   --> $DIR/const-eval-select-bad.rs:7:27
    |
 LL |     const_eval_select((), || {}, || {});
-   |     -----------------     ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`
-   |     |
-   |     required by a bound introduced by this call
+   |                           ^^^^^
    |
-   = help: the trait `~const FnOnce<()>` is not implemented for closure `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`
-note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`, but that implementation is not `const`
-  --> $DIR/const-eval-select-bad.rs:7:27
+   = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]
+   = help: consult the documentation on `const_eval_select` for more information
+
+error: this argument must be a function item
+  --> $DIR/const-eval-select-bad.rs:7:34
    |
 LL |     const_eval_select((), || {}, || {});
-   |                           ^^^^^
-   = note: wrap the `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]` in a closure with no arguments: `|| { /* code */ }`
-note: required by a bound in `const_eval_select`
-  --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |                                  ^^^^^
    |
-LL |     F: ~const FnOnce<ARG, Output = RET>,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+   = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:34: 7:36]
+   = help: consult the documentation on `const_eval_select` for more information
 
-error[E0277]: the trait bound `{integer}: FnOnce<()>` is not satisfied
-  --> $DIR/const-eval-select-bad.rs:9:27
+error: this argument must be a function item
+  --> $DIR/const-eval-select-bad.rs:10:27
+   |
+LL |     const_eval_select((), 42, 0xDEADBEEF);
+   |                           ^^
+   |
+   = note: expected a function item, found {integer}
+   = help: consult the documentation on `const_eval_select` for more information
+
+error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
+  --> $DIR/const-eval-select-bad.rs:10:27
    |
 LL |     const_eval_select((), 42, 0xDEADBEEF);
    |     -----------------     ^^ expected an `FnOnce<()>` closure, found `{integer}`
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `~const FnOnce<()>` is not implemented for `{integer}`
+   = help: the trait `FnOnce<()>` is not implemented for `{integer}`
    = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }`
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
    |
-LL |     F: ~const FnOnce<ARG, Output = RET>,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL |         F: FnOnce<ARG, Output = RET>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+
+error: this argument must be a function item
+  --> $DIR/const-eval-select-bad.rs:10:31
+   |
+LL |     const_eval_select((), 42, 0xDEADBEEF);
+   |                               ^^^^^^^^^^
+   |
+   = note: expected a function item, found {integer}
+   = help: consult the documentation on `const_eval_select` for more information
 
 error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
-  --> $DIR/const-eval-select-bad.rs:9:31
+  --> $DIR/const-eval-select-bad.rs:10:31
    |
 LL |     const_eval_select((), 42, 0xDEADBEEF);
    |     -----------------         ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
@@ -48,11 +63,11 @@ LL |     const_eval_select((), 42, 0xDEADBEEF);
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
    |
-LL |     G: FnOnce<ARG, Output = RET> + ~const Destruct,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL |         G: FnOnce<ARG, Output = RET>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
 
 error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
-  --> $DIR/const-eval-select-bad.rs:29:34
+  --> $DIR/const-eval-select-bad.rs:32:34
    |
 LL |     const_eval_select((1,), foo, bar);
    |     -----------------            ^^^ expected `i32`, found `bool`
@@ -62,11 +77,11 @@ LL |     const_eval_select((1,), foo, bar);
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
    |
-LL |     G: FnOnce<ARG, Output = RET> + ~const Destruct,
-   |                    ^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL |         G: FnOnce<ARG, Output = RET>,
+   |                        ^^^^^^^^^^^^ required by this bound in `const_eval_select`
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/const-eval-select-bad.rs:34:32
+  --> $DIR/const-eval-select-bad.rs:37:32
    |
 LL | const fn foo(n: i32) -> i32 {
    | --------------------------- found signature defined here
@@ -81,10 +96,18 @@ LL |     const_eval_select((true,), foo, baz);
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
    |
-LL |     F: ~const FnOnce<ARG, Output = RET>,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL |         F: FnOnce<ARG, Output = RET>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+
+error: this argument must be a `const fn`
+  --> $DIR/const-eval-select-bad.rs:42:29
+   |
+LL |     const_eval_select((1,), bar, bar);
+   |                             ^^^
+   |
+   = help: consult the documentation on `const_eval_select` for more information
 
-error: aborting due to 5 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0271, E0277, E0631.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/lint/issue-101284.rs b/src/test/ui/lint/issue-101284.rs
new file mode 100644
index 00000000000..1381d4f1727
--- /dev/null
+++ b/src/test/ui/lint/issue-101284.rs
@@ -0,0 +1,15 @@
+// check-pass
+// edition:2021
+#![deny(rust_2021_compatibility)]
+
+pub struct Warns {
+    // `Arc` has significant drop
+    _significant_drop: std::sync::Arc<()>,
+    field: String,
+}
+
+pub fn test(w: Warns) {
+    _ = || drop(w.field);
+}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/auxiliary/expand-expr.rs b/src/test/ui/proc-macro/auxiliary/expand-expr.rs
index 5463e79d74e..1d6ef8a1361 100644
--- a/src/test/ui/proc-macro/auxiliary/expand-expr.rs
+++ b/src/test/ui/proc-macro/auxiliary/expand-expr.rs
@@ -80,13 +80,21 @@ fn assert_ts_eq(lhs: &TokenStream, rhs: &TokenStream) {
 pub fn expand_expr_is(input: TokenStream) -> TokenStream {
     let mut iter = input.into_iter();
     let mut expected_tts = Vec::new();
-    loop {
+    let comma = loop {
         match iter.next() {
-            Some(TokenTree::Punct(ref p)) if p.as_char() == ',' => break,
+            Some(TokenTree::Punct(p)) if p.as_char() == ',' => break p,
             Some(tt) => expected_tts.push(tt),
             None => panic!("expected comma"),
         }
-    }
+    };
+
+    // Make sure that `Ident` and `Literal` objects from this proc-macro's
+    // environment are not invalidated when `expand_expr` recursively invokes
+    // another macro by taking a local copy, and checking it after the fact.
+    let pre_expand_span = comma.span();
+    let pre_expand_ident = Ident::new("ident", comma.span());
+    let pre_expand_literal = Literal::string("literal");
+    let pre_expand_call_site = Span::call_site();
 
     let expected = expected_tts.into_iter().collect::<TokenStream>();
     let expanded = iter.collect::<TokenStream>().expand_expr().expect("expand_expr failed");
@@ -100,6 +108,15 @@ pub fn expand_expr_is(input: TokenStream) -> TokenStream {
     // Also compare the raw tts to make sure they line up.
     assert_ts_eq(&expected, &expanded);
 
+    assert!(comma.span().eq(&pre_expand_span), "pre-expansion span is still equal");
+    assert_eq!(pre_expand_ident.to_string(), "ident", "pre-expansion identifier is still valid");
+    assert_eq!(
+        pre_expand_literal.to_string(),
+        "\"literal\"",
+        "pre-expansion literal is still valid"
+    );
+    assert!(Span::call_site().eq(&pre_expand_call_site), "pre-expansion call-site is still equal");
+
     TokenStream::new()
 }
 
diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr
index eb828bb9a2c..78f70997555 100644
--- a/src/test/ui/stats/hir-stats.stderr
+++ b/src/test/ui/stats/hir-stats.stderr
@@ -1,151 +1,177 @@
-
-PRE EXPANSION AST STATS
-
-Name                Accumulated Size         Count     Item Size
-----------------------------------------------------------------
-ExprField                 48 ( 0.6%)             1            48
-Crate                     56 ( 0.7%)             1            56
-Attribute                 64 ( 0.8%)             2            32
-- Normal                    32 ( 0.4%)             1
-- DocComment                32 ( 0.4%)             1
-GenericArgs               64 ( 0.8%)             1            64
-- AngleBracketed            64 ( 0.8%)             1
-Local                     72 ( 0.9%)             1            72
-WherePredicate            72 ( 0.9%)             1            72
-- BoundPredicate            72 ( 0.9%)             1
-Arm                       96 ( 1.1%)             2            48
-ForeignItem               96 ( 1.1%)             1            96
-- Fn                        96 ( 1.1%)             1
-FieldDef                 160 ( 1.9%)             2            80
-Stmt                     160 ( 1.9%)             5            32
-- Local                     32 ( 0.4%)             1
-- MacCall                   32 ( 0.4%)             1
-- Expr                      96 ( 1.1%)             3
-Param                    160 ( 1.9%)             4            40
-FnDecl                   200 ( 2.4%)             5            40
-Variant                  240 ( 2.8%)             2           120
-Block                    288 ( 3.4%)             6            48
-GenericBound             352 ( 4.2%)             4            88
-- Trait                    352 ( 4.2%)             4
-AssocItem                416 ( 4.9%)             4           104
-- TyAlias                  208 ( 2.5%)             2
-- Fn                       208 ( 2.5%)             2
-GenericParam             520 ( 6.1%)             5           104
-PathSegment              720 ( 8.5%)            30            24
-Expr                     832 ( 9.8%)             8           104
-- Path                     104 ( 1.2%)             1
-- Match                    104 ( 1.2%)             1
-- Struct                   104 ( 1.2%)             1
-- Lit                      208 ( 2.5%)             2
-- Block                    312 ( 3.7%)             3
-Pat                      840 ( 9.9%)             7           120
-- Struct                   120 ( 1.4%)             1
-- Wild                     120 ( 1.4%)             1
-- Ident                    600 ( 7.1%)             5
-Ty                     1_344 (15.9%)            14            96
-- Rptr                      96 ( 1.1%)             1
-- Ptr                       96 ( 1.1%)             1
-- ImplicitSelf             192 ( 2.3%)             2
-- Path                     960 (11.4%)            10
-Item                   1_656 (19.6%)             9           184
-- Trait                    184 ( 2.2%)             1
-- Enum                     184 ( 2.2%)             1
-- ForeignMod               184 ( 2.2%)             1
-- Impl                     184 ( 2.2%)             1
-- Fn                       368 ( 4.4%)             2
-- Use                      552 ( 6.5%)             3
-----------------------------------------------------------------
-Total                  8_456
-
-
-POST EXPANSION AST STATS
-
-Name                Accumulated Size         Count     Item Size
-----------------------------------------------------------------
-ExprField                 48 ( 0.5%)             1            48
-Crate                     56 ( 0.6%)             1            56
-GenericArgs               64 ( 0.7%)             1            64
-- AngleBracketed            64 ( 0.7%)             1
-Local                     72 ( 0.8%)             1            72
-WherePredicate            72 ( 0.8%)             1            72
-- BoundPredicate            72 ( 0.8%)             1
-Arm                       96 ( 1.0%)             2            48
-ForeignItem               96 ( 1.0%)             1            96
-- Fn                        96 ( 1.0%)             1
-InlineAsm                120 ( 1.3%)             1           120
-Attribute                128 ( 1.4%)             4            32
-- DocComment                32 ( 0.3%)             1
-- Normal                    96 ( 1.0%)             3
-FieldDef                 160 ( 1.7%)             2            80
-Stmt                     160 ( 1.7%)             5            32
-- Local                     32 ( 0.3%)             1
-- Semi                      32 ( 0.3%)             1
-- Expr                      96 ( 1.0%)             3
-Param                    160 ( 1.7%)             4            40
-FnDecl                   200 ( 2.2%)             5            40
-Variant                  240 ( 2.6%)             2           120
-Block                    288 ( 3.1%)             6            48
-GenericBound             352 ( 3.8%)             4            88
-- Trait                    352 ( 3.8%)             4
-AssocItem                416 ( 4.5%)             4           104
-- TyAlias                  208 ( 2.3%)             2
-- Fn                       208 ( 2.3%)             2
-GenericParam             520 ( 5.7%)             5           104
-PathSegment              792 ( 8.6%)            33            24
-Pat                      840 ( 9.1%)             7           120
-- Struct                   120 ( 1.3%)             1
-- Wild                     120 ( 1.3%)             1
-- Ident                    600 ( 6.5%)             5
-Expr                     936 (10.2%)             9           104
-- Path                     104 ( 1.1%)             1
-- Match                    104 ( 1.1%)             1
-- Struct                   104 ( 1.1%)             1
-- InlineAsm                104 ( 1.1%)             1
-- Lit                      208 ( 2.3%)             2
-- Block                    312 ( 3.4%)             3
-Ty                     1_344 (14.6%)            14            96
-- Rptr                      96 ( 1.0%)             1
-- Ptr                       96 ( 1.0%)             1
-- ImplicitSelf             192 ( 2.1%)             2
-- Path                     960 (10.5%)            10
-Item                   2_024 (22.0%)            11           184
-- Trait                    184 ( 2.0%)             1
-- Enum                     184 ( 2.0%)             1
-- ExternCrate              184 ( 2.0%)             1
-- ForeignMod               184 ( 2.0%)             1
-- Impl                     184 ( 2.0%)             1
-- Fn                       368 ( 4.0%)             2
-- Use                      736 ( 8.0%)             4
-----------------------------------------------------------------
-Total                  9_184
-
-
-HIR STATS
-
-Name                Accumulated Size         Count     Item Size
-----------------------------------------------------------------
-Param                     64 ( 0.7%)             2            32
-Local                     64 ( 0.7%)             1            64
-ForeignItem               72 ( 0.8%)             1            72
-FieldDef                  96 ( 1.0%)             2            48
-Arm                       96 ( 1.0%)             2            48
-Stmt                      96 ( 1.0%)             3            32
-FnDecl                   120 ( 1.3%)             3            40
-Attribute                128 ( 1.4%)             4            32
-Lifetime                 128 ( 1.4%)             4            32
-Variant                  160 ( 1.7%)             2            80
-ImplItem                 176 ( 1.9%)             2            88
-GenericBound             192 ( 2.1%)             4            48
-TraitItem                192 ( 2.1%)             2            96
-WherePredicate           216 ( 2.3%)             3            72
-Block                    288 ( 3.1%)             6            48
-QPath                    408 ( 4.4%)            17            24
-Pat                      440 ( 4.8%)             5            88
-Expr                     672 ( 7.3%)            12            56
-Item                     960 (10.4%)            12            80
-Ty                     1_152 (12.4%)            16            72
-Path                   1_296 (14.0%)            27            48
-PathSegment            2_240 (24.2%)            40            56
-----------------------------------------------------------------
-Total                  9_256
-
+ast-stats-1 PRE EXPANSION AST STATS
+ast-stats-1 Name                Accumulated Size         Count     Item Size
+ast-stats-1 ----------------------------------------------------------------
+ast-stats-1 ExprField                 48 ( 0.6%)             1            48
+ast-stats-1 Crate                     56 ( 0.7%)             1            56
+ast-stats-1 Attribute                 64 ( 0.8%)             2            32
+ast-stats-1 - Normal                    32 ( 0.4%)             1
+ast-stats-1 - DocComment                32 ( 0.4%)             1
+ast-stats-1 GenericArgs               64 ( 0.8%)             1            64
+ast-stats-1 - AngleBracketed            64 ( 0.8%)             1
+ast-stats-1 Local                     72 ( 0.9%)             1            72
+ast-stats-1 WherePredicate            72 ( 0.9%)             1            72
+ast-stats-1 - BoundPredicate            72 ( 0.9%)             1
+ast-stats-1 Arm                       96 ( 1.1%)             2            48
+ast-stats-1 ForeignItem               96 ( 1.1%)             1            96
+ast-stats-1 - Fn                        96 ( 1.1%)             1
+ast-stats-1 FieldDef                 160 ( 1.9%)             2            80
+ast-stats-1 Stmt                     160 ( 1.9%)             5            32
+ast-stats-1 - Local                     32 ( 0.4%)             1
+ast-stats-1 - MacCall                   32 ( 0.4%)             1
+ast-stats-1 - Expr                      96 ( 1.1%)             3
+ast-stats-1 Param                    160 ( 1.9%)             4            40
+ast-stats-1 FnDecl                   200 ( 2.4%)             5            40
+ast-stats-1 Variant                  240 ( 2.8%)             2           120
+ast-stats-1 Block                    288 ( 3.4%)             6            48
+ast-stats-1 GenericBound             352 ( 4.2%)             4            88
+ast-stats-1 - Trait                    352 ( 4.2%)             4
+ast-stats-1 AssocItem                416 ( 4.9%)             4           104
+ast-stats-1 - TyAlias                  208 ( 2.5%)             2
+ast-stats-1 - Fn                       208 ( 2.5%)             2
+ast-stats-1 GenericParam             520 ( 6.1%)             5           104
+ast-stats-1 PathSegment              720 ( 8.5%)            30            24
+ast-stats-1 Expr                     832 ( 9.8%)             8           104
+ast-stats-1 - Path                     104 ( 1.2%)             1
+ast-stats-1 - Match                    104 ( 1.2%)             1
+ast-stats-1 - Struct                   104 ( 1.2%)             1
+ast-stats-1 - Lit                      208 ( 2.5%)             2
+ast-stats-1 - Block                    312 ( 3.7%)             3
+ast-stats-1 Pat                      840 ( 9.9%)             7           120
+ast-stats-1 - Struct                   120 ( 1.4%)             1
+ast-stats-1 - Wild                     120 ( 1.4%)             1
+ast-stats-1 - Ident                    600 ( 7.1%)             5
+ast-stats-1 Ty                     1_344 (15.9%)            14            96
+ast-stats-1 - Rptr                      96 ( 1.1%)             1
+ast-stats-1 - Ptr                       96 ( 1.1%)             1
+ast-stats-1 - ImplicitSelf             192 ( 2.3%)             2
+ast-stats-1 - Path                     960 (11.4%)            10
+ast-stats-1 Item                   1_656 (19.6%)             9           184
+ast-stats-1 - Trait                    184 ( 2.2%)             1
+ast-stats-1 - Enum                     184 ( 2.2%)             1
+ast-stats-1 - ForeignMod               184 ( 2.2%)             1
+ast-stats-1 - Impl                     184 ( 2.2%)             1
+ast-stats-1 - Fn                       368 ( 4.4%)             2
+ast-stats-1 - Use                      552 ( 6.5%)             3
+ast-stats-1 ----------------------------------------------------------------
+ast-stats-1 Total                  8_456
+ast-stats-1
+ast-stats-2 POST EXPANSION AST STATS
+ast-stats-2 Name                Accumulated Size         Count     Item Size
+ast-stats-2 ----------------------------------------------------------------
+ast-stats-2 ExprField                 48 ( 0.5%)             1            48
+ast-stats-2 Crate                     56 ( 0.6%)             1            56
+ast-stats-2 GenericArgs               64 ( 0.7%)             1            64
+ast-stats-2 - AngleBracketed            64 ( 0.7%)             1
+ast-stats-2 Local                     72 ( 0.8%)             1            72
+ast-stats-2 WherePredicate            72 ( 0.8%)             1            72
+ast-stats-2 - BoundPredicate            72 ( 0.8%)             1
+ast-stats-2 Arm                       96 ( 1.0%)             2            48
+ast-stats-2 ForeignItem               96 ( 1.0%)             1            96
+ast-stats-2 - Fn                        96 ( 1.0%)             1
+ast-stats-2 InlineAsm                120 ( 1.3%)             1           120
+ast-stats-2 Attribute                128 ( 1.4%)             4            32
+ast-stats-2 - DocComment                32 ( 0.3%)             1
+ast-stats-2 - Normal                    96 ( 1.0%)             3
+ast-stats-2 FieldDef                 160 ( 1.7%)             2            80
+ast-stats-2 Stmt                     160 ( 1.7%)             5            32
+ast-stats-2 - Local                     32 ( 0.3%)             1
+ast-stats-2 - Semi                      32 ( 0.3%)             1
+ast-stats-2 - Expr                      96 ( 1.0%)             3
+ast-stats-2 Param                    160 ( 1.7%)             4            40
+ast-stats-2 FnDecl                   200 ( 2.2%)             5            40
+ast-stats-2 Variant                  240 ( 2.6%)             2           120
+ast-stats-2 Block                    288 ( 3.1%)             6            48
+ast-stats-2 GenericBound             352 ( 3.8%)             4            88
+ast-stats-2 - Trait                    352 ( 3.8%)             4
+ast-stats-2 AssocItem                416 ( 4.5%)             4           104
+ast-stats-2 - TyAlias                  208 ( 2.3%)             2
+ast-stats-2 - Fn                       208 ( 2.3%)             2
+ast-stats-2 GenericParam             520 ( 5.7%)             5           104
+ast-stats-2 PathSegment              792 ( 8.6%)            33            24
+ast-stats-2 Pat                      840 ( 9.1%)             7           120
+ast-stats-2 - Struct                   120 ( 1.3%)             1
+ast-stats-2 - Wild                     120 ( 1.3%)             1
+ast-stats-2 - Ident                    600 ( 6.5%)             5
+ast-stats-2 Expr                     936 (10.2%)             9           104
+ast-stats-2 - Path                     104 ( 1.1%)             1
+ast-stats-2 - Match                    104 ( 1.1%)             1
+ast-stats-2 - Struct                   104 ( 1.1%)             1
+ast-stats-2 - InlineAsm                104 ( 1.1%)             1
+ast-stats-2 - Lit                      208 ( 2.3%)             2
+ast-stats-2 - Block                    312 ( 3.4%)             3
+ast-stats-2 Ty                     1_344 (14.6%)            14            96
+ast-stats-2 - Rptr                      96 ( 1.0%)             1
+ast-stats-2 - Ptr                       96 ( 1.0%)             1
+ast-stats-2 - ImplicitSelf             192 ( 2.1%)             2
+ast-stats-2 - Path                     960 (10.5%)            10
+ast-stats-2 Item                   2_024 (22.0%)            11           184
+ast-stats-2 - Trait                    184 ( 2.0%)             1
+ast-stats-2 - Enum                     184 ( 2.0%)             1
+ast-stats-2 - ExternCrate              184 ( 2.0%)             1
+ast-stats-2 - ForeignMod               184 ( 2.0%)             1
+ast-stats-2 - Impl                     184 ( 2.0%)             1
+ast-stats-2 - Fn                       368 ( 4.0%)             2
+ast-stats-2 - Use                      736 ( 8.0%)             4
+ast-stats-2 ----------------------------------------------------------------
+ast-stats-2 Total                  9_184
+ast-stats-2
+hir-stats HIR STATS
+hir-stats Name                Accumulated Size         Count     Item Size
+hir-stats ----------------------------------------------------------------
+hir-stats ForeignItemRef            24 ( 0.2%)             1            24
+hir-stats Mod                       32 ( 0.3%)             1            32
+hir-stats ExprField                 40 ( 0.4%)             1            40
+hir-stats TraitItemRef              56 ( 0.6%)             2            28
+hir-stats Param                     64 ( 0.6%)             2            32
+hir-stats Local                     64 ( 0.6%)             1            64
+hir-stats InlineAsm                 72 ( 0.7%)             1            72
+hir-stats ImplItemRef               72 ( 0.7%)             2            36
+hir-stats FieldDef                  96 ( 1.0%)             2            48
+hir-stats Arm                       96 ( 1.0%)             2            48
+hir-stats Body                      96 ( 1.0%)             3            32
+hir-stats Stmt                      96 ( 1.0%)             3            32
+hir-stats - Local                     32 ( 0.3%)             1
+hir-stats - Semi                      32 ( 0.3%)             1
+hir-stats - Expr                      32 ( 0.3%)             1
+hir-stats FnDecl                   120 ( 1.2%)             3            40
+hir-stats Attribute                128 ( 1.3%)             4            32
+hir-stats GenericArgs              144 ( 1.4%)             3            48
+hir-stats Variant                  160 ( 1.6%)             2            80
+hir-stats GenericArg               160 ( 1.6%)             4            40
+hir-stats - Type                      40 ( 0.4%)             1
+hir-stats - Lifetime                 120 ( 1.2%)             3
+hir-stats GenericBound             192 ( 1.9%)             4            48
+hir-stats - Trait                    192 ( 1.9%)             4
+hir-stats WherePredicate           216 ( 2.1%)             3            72
+hir-stats - BoundPredicate           216 ( 2.1%)             3
+hir-stats Block                    288 ( 2.9%)             6            48
+hir-stats GenericParam             400 ( 4.0%)             5            80
+hir-stats Pat                      440 ( 4.4%)             5            88
+hir-stats - Wild                      88 ( 0.9%)             1
+hir-stats - Struct                    88 ( 0.9%)             1
+hir-stats - Binding                  264 ( 2.6%)             3
+hir-stats Generics                 560 ( 5.5%)            10            56
+hir-stats Expr                     672 ( 6.7%)            12            56
+hir-stats - Path                      56 ( 0.6%)             1
+hir-stats - Struct                    56 ( 0.6%)             1
+hir-stats - Match                     56 ( 0.6%)             1
+hir-stats - InlineAsm                 56 ( 0.6%)             1
+hir-stats - Lit                      112 ( 1.1%)             2
+hir-stats - Block                    336 ( 3.3%)             6
+hir-stats Item                     960 ( 9.5%)            12            80
+hir-stats - Trait                     80 ( 0.8%)             1
+hir-stats - Enum                      80 ( 0.8%)             1
+hir-stats - ExternCrate               80 ( 0.8%)             1
+hir-stats - ForeignMod                80 ( 0.8%)             1
+hir-stats - Impl                      80 ( 0.8%)             1
+hir-stats - Fn                       160 ( 1.6%)             2
+hir-stats - Use                      400 ( 4.0%)             5
+hir-stats Ty                     1_080 (10.7%)            15            72
+hir-stats - Ptr                       72 ( 0.7%)             1
+hir-stats - Rptr                      72 ( 0.7%)             1
+hir-stats - Path                     936 ( 9.3%)            13
+hir-stats Path                   1_536 (15.2%)            32            48
+hir-stats PathSegment            2_240 (22.2%)            40            56
+hir-stats ----------------------------------------------------------------
+hir-stats Total                 10_104
+hir-stats
diff --git a/src/test/ui/suggestions/copied-and-cloned.fixed b/src/test/ui/suggestions/copied-and-cloned.fixed
new file mode 100644
index 00000000000..f801403feec
--- /dev/null
+++ b/src/test/ui/suggestions/copied-and-cloned.fixed
@@ -0,0 +1,23 @@
+// run-rustfix
+
+fn expect<T>(_: T) {}
+
+fn main() {
+    let x = Some(&());
+    expect::<Option<()>>(x.copied());
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::copied` to copy the value inside the `Option`
+    let x = Ok(&());
+    expect::<Result<(), ()>>(x.copied());
+    //~^ ERROR mismatched types
+    //~| HELP use `Result::copied` to copy the value inside the `Result`
+    let s = String::new();
+    let x = Some(&s);
+    expect::<Option<String>>(x.cloned());
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
+    let x = Ok(&s);
+    expect::<Result<String, ()>>(x.cloned());
+    //~^ ERROR mismatched types
+    //~| HELP use `Result::cloned` to clone the value inside the `Result`
+}
diff --git a/src/test/ui/suggestions/copied-and-cloned.rs b/src/test/ui/suggestions/copied-and-cloned.rs
new file mode 100644
index 00000000000..640450b7655
--- /dev/null
+++ b/src/test/ui/suggestions/copied-and-cloned.rs
@@ -0,0 +1,23 @@
+// run-rustfix
+
+fn expect<T>(_: T) {}
+
+fn main() {
+    let x = Some(&());
+    expect::<Option<()>>(x);
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::copied` to copy the value inside the `Option`
+    let x = Ok(&());
+    expect::<Result<(), ()>>(x);
+    //~^ ERROR mismatched types
+    //~| HELP use `Result::copied` to copy the value inside the `Result`
+    let s = String::new();
+    let x = Some(&s);
+    expect::<Option<String>>(x);
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
+    let x = Ok(&s);
+    expect::<Result<String, ()>>(x);
+    //~^ ERROR mismatched types
+    //~| HELP use `Result::cloned` to clone the value inside the `Result`
+}
diff --git a/src/test/ui/suggestions/copied-and-cloned.stderr b/src/test/ui/suggestions/copied-and-cloned.stderr
new file mode 100644
index 00000000000..a6336281b40
--- /dev/null
+++ b/src/test/ui/suggestions/copied-and-cloned.stderr
@@ -0,0 +1,83 @@
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:7:26
+   |
+LL |     expect::<Option<()>>(x);
+   |     -------------------- ^ expected `()`, found `&()`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected enum `Option<()>`
+              found enum `Option<&()>`
+note: function defined here
+  --> $DIR/copied-and-cloned.rs:3:4
+   |
+LL | fn expect<T>(_: T) {}
+   |    ^^^^^^    ----
+help: use `Option::copied` to copy the value inside the `Option`
+   |
+LL |     expect::<Option<()>>(x.copied());
+   |                           +++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:11:30
+   |
+LL |     expect::<Result<(), ()>>(x);
+   |     ------------------------ ^ expected `()`, found `&()`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected enum `Result<(), ()>`
+              found enum `Result<&(), _>`
+note: function defined here
+  --> $DIR/copied-and-cloned.rs:3:4
+   |
+LL | fn expect<T>(_: T) {}
+   |    ^^^^^^    ----
+help: use `Result::copied` to copy the value inside the `Result`
+   |
+LL |     expect::<Result<(), ()>>(x.copied());
+   |                               +++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:16:30
+   |
+LL |     expect::<Option<String>>(x);
+   |     ------------------------ ^ expected struct `String`, found `&String`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected enum `Option<String>`
+              found enum `Option<&String>`
+note: function defined here
+  --> $DIR/copied-and-cloned.rs:3:4
+   |
+LL | fn expect<T>(_: T) {}
+   |    ^^^^^^    ----
+help: use `Option::cloned` to clone the value inside the `Option`
+   |
+LL |     expect::<Option<String>>(x.cloned());
+   |                               +++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:20:34
+   |
+LL |     expect::<Result<String, ()>>(x);
+   |     ---------------------------- ^ expected struct `String`, found `&String`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected enum `Result<String, ()>`
+              found enum `Result<&String, _>`
+note: function defined here
+  --> $DIR/copied-and-cloned.rs:3:4
+   |
+LL | fn expect<T>(_: T) {}
+   |    ^^^^^^    ----
+help: use `Result::cloned` to clone the value inside the `Result`
+   |
+LL |     expect::<Result<String, ()>>(x.cloned());
+   |                                   +++++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.