about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-26 13:13:04 +0000
committerbors <bors@rust-lang.org>2024-07-26 13:13:04 +0000
commit2d5a628a1de1d38318909a710ef37da6251e362e (patch)
tree6794a20dc0cff21155b593b8d3733f7a202004a7
parent355efacf0d430331c962a38af39049b76bb6266b (diff)
parenta7d57aa7c8f42dda6d33e0ac349cf834eaf041b8 (diff)
downloadrust-2d5a628a1de1d38318909a710ef37da6251e362e.tar.gz
rust-2d5a628a1de1d38318909a710ef37da6251e362e.zip
Auto merge of #128165 - saethlin:optimize-clone-shims, r=compiler-errors
Let InstCombine remove Clone shims inside Clone shims

The Clone shims that we generate tend to recurse into other Clone shims, which gets very silly very quickly. Here's our current state: https://godbolt.org/z/E69YeY8eq

So I've added InstSimplify to the shims optimization passes, and improved `is_trivially_pure_clone_copy` so that it can delete those calls inside the shim. This makes the shim way smaller because most of its size is the required ceremony for unwinding.

This change also completely breaks the UI test added for https://github.com/rust-lang/rust/issues/104870. With this PR, that program ICEs in MIR type checking because `is_trivially_pure_clone_copy` and the trait solver disagree on whether `*mut u8` is `Copy`. And adding the requisite `Copy` impl to make them agree makes the test not generate any diagnostics. Considering that I spent most of my time on this PR fixing `#![no_core]` tests, I would prefer to just delete this one. The maintenance burden of `#![no_core]` is uniquely high because when they break they tend to break in very confusing ways.

try-job: x86_64-mingw
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs6
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs3
-rw-r--r--library/rtstartup/rsbegin.rs2
-rw-r--r--library/rtstartup/rsend.rs2
-rw-r--r--tests/assembly/simd-intrinsic-mask-load.rs1
-rw-r--r--tests/assembly/simd-intrinsic-mask-store.rs1
-rw-r--r--tests/codegen/avr/avr-func-addrspace.rs1
-rw-r--r--tests/codegen/clone-shims.rs15
-rw-r--r--tests/codegen/emcripten-catch-unwind.rs2
-rw-r--r--tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs1
-rw-r--r--tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs1
-rw-r--r--tests/ui/lang-items/missing-clone-for-suggestion.rs20
-rw-r--r--tests/ui/lang-items/missing-clone-for-suggestion.stderr21
13 files changed, 31 insertions, 45 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index d2b444a066b..da98e3b9f46 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1864,9 +1864,9 @@ impl<'tcx> Ty<'tcx> {
             // Definitely absolutely not copy.
             ty::Ref(_, _, hir::Mutability::Mut) => false,
 
-            // Thin pointers & thin shared references are pure-clone-copy, but for
-            // anything with custom metadata it might be more complicated.
-            ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
+            // The standard library has a blanket Copy impl for shared references and raw pointers,
+            // for all unsized types.
+            ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => true,
 
             ty::Coroutine(..) | ty::CoroutineWitness(..) => false,
 
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 6835a39cf36..19e3bf5a599 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -17,7 +17,7 @@ use std::iter;
 
 use crate::{
     abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator,
-    mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify,
+    instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify,
 };
 use rustc_middle::mir::patch::MirPatch;
 use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
@@ -154,6 +154,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
             &deref_separator::Derefer,
             &remove_noop_landing_pads::RemoveNoopLandingPads,
             &simplify::SimplifyCfg::MakeShim,
+            &instsimplify::InstSimplify,
             &abort_unwinding_calls::AbortUnwindingCalls,
             &add_call_guards::CriticalCallEdges,
         ],
diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs
index 14bce2bbeee..9a3d95bd8dd 100644
--- a/library/rtstartup/rsbegin.rs
+++ b/library/rtstartup/rsbegin.rs
@@ -29,6 +29,8 @@ trait Copy {}
 #[lang = "freeze"]
 auto trait Freeze {}
 
+impl<T: ?Sized> Copy for *mut T {}
+
 #[lang = "drop_in_place"]
 #[inline]
 #[allow(unconditional_recursion)]
diff --git a/library/rtstartup/rsend.rs b/library/rtstartup/rsend.rs
index 714643c8386..2514eb00344 100644
--- a/library/rtstartup/rsend.rs
+++ b/library/rtstartup/rsend.rs
@@ -17,6 +17,8 @@ trait Copy {}
 #[lang = "freeze"]
 auto trait Freeze {}
 
+impl<T: ?Sized> Copy for *mut T {}
+
 #[lang = "drop_in_place"]
 #[inline]
 #[allow(unconditional_recursion)]
diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs
index d537c143d36..b650e1cee30 100644
--- a/tests/assembly/simd-intrinsic-mask-load.rs
+++ b/tests/assembly/simd-intrinsic-mask-load.rs
@@ -18,6 +18,7 @@ pub trait Sized {}
 
 #[lang = "copy"]
 trait Copy {}
+impl<T: ?Sized> Copy for *const T {}
 
 #[repr(simd)]
 pub struct i8x16([i8; 16]);
diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs
index 5d4c00c3823..95a3b28b967 100644
--- a/tests/assembly/simd-intrinsic-mask-store.rs
+++ b/tests/assembly/simd-intrinsic-mask-store.rs
@@ -18,6 +18,7 @@ pub trait Sized {}
 
 #[lang = "copy"]
 trait Copy {}
+impl<T: ?Sized> Copy for *mut T {}
 
 #[repr(simd)]
 pub struct i8x16([i8; 16]);
diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs
index 70834707564..7f9a7e6e811 100644
--- a/tests/codegen/avr/avr-func-addrspace.rs
+++ b/tests/codegen/avr/avr-func-addrspace.rs
@@ -17,6 +17,7 @@
 pub trait Sized {}
 #[lang = "copy"]
 pub trait Copy {}
+impl<T: ?Sized> Copy for *const T {}
 #[lang = "receiver"]
 pub trait Receiver {}
 #[lang = "tuple_trait"]
diff --git a/tests/codegen/clone-shims.rs b/tests/codegen/clone-shims.rs
new file mode 100644
index 00000000000..06c959f9ee7
--- /dev/null
+++ b/tests/codegen/clone-shims.rs
@@ -0,0 +1,15 @@
+// Clone shims for aggregates are generated by just calling the Clone shims for all their members.
+// Those calls generate a lot of unnecessary IR if the members are Copy. This test ensures that we
+// optimize away those inner calls without needing to inline them.
+
+//@ compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0 -Zinline-mir=no
+#![crate_type = "lib"]
+
+pub type Test = (i32, i32, *const i32);
+pub static TEST: fn(&Test) -> Test = <Test as core::clone::Clone>::clone;
+
+// CHECK-NOT: call <i32 as core::clone::Clone>::clone
+// CHECK-NOT: call <*const i32 as core::clone::Clone>::clone
+// CHECK:     ; <(i32, i32, *const i32) as core::clone::Clone>::clone
+// CHECK-NOT: call <i32 as core::clone::Clone>::clone
+// CHECK-NOT: call <*const i32 as core::clone::Clone>::clone
diff --git a/tests/codegen/emcripten-catch-unwind.rs b/tests/codegen/emcripten-catch-unwind.rs
index 6cda8c6799f..35444db9558 100644
--- a/tests/codegen/emcripten-catch-unwind.rs
+++ b/tests/codegen/emcripten-catch-unwind.rs
@@ -16,6 +16,8 @@ trait Freeze {}
 #[lang = "copy"]
 trait Copy {}
 
+impl<T> Copy for *mut T {}
+
 #[rustc_intrinsic]
 fn size_of<T>() -> usize {
     loop {}
diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
index ed0af90aaaf..520192b5d59 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
@@ -18,6 +18,7 @@ impl Copy for i64 {}
 impl Copy for u64 {}
 impl Copy for f32 {}
 impl Copy for f64 {}
+impl<T> Copy for *mut T {}
 
 // CHECK: define void @f_void()
 #[no_mangle]
diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs
index fc4d570dc2e..c1967e55e75 100644
--- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs
+++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs
@@ -15,6 +15,7 @@
 trait Sized {}
 #[lang = "copy"]
 trait Copy {}
+impl<T: ?Sized> Copy for &T {}
 #[lang = "receiver"]
 trait Receiver {}
 #[lang = "dispatch_from_dyn"]
diff --git a/tests/ui/lang-items/missing-clone-for-suggestion.rs b/tests/ui/lang-items/missing-clone-for-suggestion.rs
deleted file mode 100644
index e8290c0098a..00000000000
--- a/tests/ui/lang-items/missing-clone-for-suggestion.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Avoid panicking if the Clone trait is not found while building error suggestions
-// See #104870
-
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang = "sized"]
-trait Sized {}
-
-#[lang = "copy"]
-trait Copy {}
-
-fn g<T>(x: T) {}
-
-fn f(x: *mut u8) {
-    g(x);
-    g(x); //~ ERROR use of moved value: `x`
-}
-
-fn main() {}
diff --git a/tests/ui/lang-items/missing-clone-for-suggestion.stderr b/tests/ui/lang-items/missing-clone-for-suggestion.stderr
deleted file mode 100644
index 0187f965b5c..00000000000
--- a/tests/ui/lang-items/missing-clone-for-suggestion.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0382]: use of moved value: `x`
-  --> $DIR/missing-clone-for-suggestion.rs:17:7
-   |
-LL | fn f(x: *mut u8) {
-   |      - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait
-LL |     g(x);
-   |       - value moved here
-LL |     g(x);
-   |       ^ value used here after move
-   |
-note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary
-  --> $DIR/missing-clone-for-suggestion.rs:13:12
-   |
-LL | fn g<T>(x: T) {}
-   |    -       ^ this parameter takes ownership of the value
-   |    |
-   |    in this function
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0382`.