Let InstCombine remove Clone shims inside Clone shims
Co-authored-by: scottmcm <scottmcm@users.noreply.github.com>
This commit is contained in:
parent
92c6c03805
commit
a7d57aa7c8
@ -1864,9 +1864,9 @@ pub fn is_trivially_pure_clone_copy(self) -> bool {
|
|||||||
// Definitely absolutely not copy.
|
// Definitely absolutely not copy.
|
||||||
ty::Ref(_, _, hir::Mutability::Mut) => false,
|
ty::Ref(_, _, hir::Mutability::Mut) => false,
|
||||||
|
|
||||||
// Thin pointers & thin shared references are pure-clone-copy, but for
|
// The standard library has a blanket Copy impl for shared references and raw pointers,
|
||||||
// anything with custom metadata it might be more complicated.
|
// for all unsized types.
|
||||||
ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
|
ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => true,
|
||||||
|
|
||||||
ty::Coroutine(..) | ty::CoroutineWitness(..) => false,
|
ty::Coroutine(..) | ty::CoroutineWitness(..) => false,
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator,
|
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_middle::mir::patch::MirPatch;
|
||||||
use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
|
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,
|
&deref_separator::Derefer,
|
||||||
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
||||||
&simplify::SimplifyCfg::MakeShim,
|
&simplify::SimplifyCfg::MakeShim,
|
||||||
|
&instsimplify::InstSimplify,
|
||||||
&abort_unwinding_calls::AbortUnwindingCalls,
|
&abort_unwinding_calls::AbortUnwindingCalls,
|
||||||
&add_call_guards::CriticalCallEdges,
|
&add_call_guards::CriticalCallEdges,
|
||||||
],
|
],
|
||||||
|
@ -29,6 +29,8 @@ trait Copy {}
|
|||||||
#[lang = "freeze"]
|
#[lang = "freeze"]
|
||||||
auto trait Freeze {}
|
auto trait Freeze {}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Copy for *mut T {}
|
||||||
|
|
||||||
#[lang = "drop_in_place"]
|
#[lang = "drop_in_place"]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unconditional_recursion)]
|
#[allow(unconditional_recursion)]
|
||||||
|
@ -17,6 +17,8 @@ trait Copy {}
|
|||||||
#[lang = "freeze"]
|
#[lang = "freeze"]
|
||||||
auto trait Freeze {}
|
auto trait Freeze {}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Copy for *mut T {}
|
||||||
|
|
||||||
#[lang = "drop_in_place"]
|
#[lang = "drop_in_place"]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unconditional_recursion)]
|
#[allow(unconditional_recursion)]
|
||||||
|
@ -18,6 +18,7 @@ pub trait Sized {}
|
|||||||
|
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
trait Copy {}
|
trait Copy {}
|
||||||
|
impl<T: ?Sized> Copy for *const T {}
|
||||||
|
|
||||||
#[repr(simd)]
|
#[repr(simd)]
|
||||||
pub struct i8x16([i8; 16]);
|
pub struct i8x16([i8; 16]);
|
||||||
|
@ -18,6 +18,7 @@ pub trait Sized {}
|
|||||||
|
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
trait Copy {}
|
trait Copy {}
|
||||||
|
impl<T: ?Sized> Copy for *mut T {}
|
||||||
|
|
||||||
#[repr(simd)]
|
#[repr(simd)]
|
||||||
pub struct i8x16([i8; 16]);
|
pub struct i8x16([i8; 16]);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
pub trait Sized {}
|
pub trait Sized {}
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
pub trait Copy {}
|
pub trait Copy {}
|
||||||
|
impl<T: ?Sized> Copy for *const T {}
|
||||||
#[lang = "receiver"]
|
#[lang = "receiver"]
|
||||||
pub trait Receiver {}
|
pub trait Receiver {}
|
||||||
#[lang = "tuple_trait"]
|
#[lang = "tuple_trait"]
|
||||||
|
15
tests/codegen/clone-shims.rs
Normal file
15
tests/codegen/clone-shims.rs
Normal file
@ -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
|
@ -16,6 +16,8 @@ trait Freeze {}
|
|||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
trait Copy {}
|
trait Copy {}
|
||||||
|
|
||||||
|
impl<T> Copy for *mut T {}
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
fn size_of<T>() -> usize {
|
fn size_of<T>() -> usize {
|
||||||
loop {}
|
loop {}
|
||||||
|
@ -18,6 +18,7 @@ impl Copy for i64 {}
|
|||||||
impl Copy for u64 {}
|
impl Copy for u64 {}
|
||||||
impl Copy for f32 {}
|
impl Copy for f32 {}
|
||||||
impl Copy for f64 {}
|
impl Copy for f64 {}
|
||||||
|
impl<T> Copy for *mut T {}
|
||||||
|
|
||||||
// CHECK: define void @f_void()
|
// CHECK: define void @f_void()
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
trait Sized {}
|
trait Sized {}
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
trait Copy {}
|
trait Copy {}
|
||||||
|
impl<T: ?Sized> Copy for &T {}
|
||||||
#[lang = "receiver"]
|
#[lang = "receiver"]
|
||||||
trait Receiver {}
|
trait Receiver {}
|
||||||
#[lang = "dispatch_from_dyn"]
|
#[lang = "dispatch_from_dyn"]
|
||||||
|
@ -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() {}
|
|
@ -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`.
|
|
Loading…
Reference in New Issue
Block a user