Move is_trivially_pure_clone_copy
onto Ty
instead
This commit is contained in:
parent
0d4a3f11e2
commit
b5a54d8777
2 changed files with 53 additions and 12 deletions
|
@ -2371,6 +2371,57 @@ impl<'tcx> Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fast path helper for primitives which are always `Copy` and which
|
||||||
|
/// have a side-effect-free `Clone` impl.
|
||||||
|
///
|
||||||
|
/// Returning true means the type is known to be pure and `Copy+Clone`.
|
||||||
|
/// Returning `false` means nothing -- could be `Copy`, might not be.
|
||||||
|
///
|
||||||
|
/// This is mostly useful for optimizations, as there are the types
|
||||||
|
/// on which we can replace cloning with dereferencing.
|
||||||
|
pub fn is_trivially_pure_clone_copy(self) -> bool {
|
||||||
|
match self.kind() {
|
||||||
|
ty::Bool | ty::Char | ty::Never => true,
|
||||||
|
|
||||||
|
// These aren't even `Clone`
|
||||||
|
ty::Str | ty::Slice(..) | ty::Foreign(..) | ty::Dynamic(..) => false,
|
||||||
|
|
||||||
|
ty::Int(..) | ty::Uint(..) | ty::Float(..) => true,
|
||||||
|
|
||||||
|
// The voldemort ZSTs are fine.
|
||||||
|
ty::FnDef(..) => true,
|
||||||
|
|
||||||
|
ty::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(),
|
||||||
|
|
||||||
|
// A 100-tuple isn't "trivial", so doing this only for reasonable sizes.
|
||||||
|
ty::Tuple(field_tys) => {
|
||||||
|
field_tys.len() <= 3 && field_tys.iter().all(Self::is_trivially_pure_clone_copy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sometimes traits aren't implemented for every ABI or arity,
|
||||||
|
// because we can't be generic over everything yet.
|
||||||
|
ty::FnPtr(..) => false,
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
|
||||||
|
ty::Generator(..) | ty::GeneratorWitness(..) => false,
|
||||||
|
|
||||||
|
// Might be, but not "trivial" so just giving the safe answer.
|
||||||
|
ty::Adt(..) | ty::Closure(..) | ty::Opaque(..) => false,
|
||||||
|
|
||||||
|
ty::Projection(..) | ty::Param(..) | ty::Infer(..) | ty::Error(..) => false,
|
||||||
|
|
||||||
|
ty::Bound(..) | ty::Placeholder(..) => {
|
||||||
|
bug!("`is_trivially_pure_clone_copy` applied to unexpected type: {:?}", self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extra information about why we ended up with a particular variance.
|
/// Extra information about why we ended up with a particular variance.
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_middle::mir::{
|
||||||
BinOp, Body, Constant, LocalDecls, Operand, Place, ProjectionElem, Rvalue, SourceInfo,
|
BinOp, Body, Constant, LocalDecls, Operand, Place, ProjectionElem, Rvalue, SourceInfo,
|
||||||
Statement, StatementKind, Terminator, TerminatorKind, UnOp,
|
Statement, StatementKind, Terminator, TerminatorKind, UnOp,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TyKind};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
|
||||||
pub struct InstCombine;
|
pub struct InstCombine;
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
|
||||||
let ty::Ref(_region, inner_ty, Mutability::Not) = *arg_ty.kind()
|
let ty::Ref(_region, inner_ty, Mutability::Not) = *arg_ty.kind()
|
||||||
else { return };
|
else { return };
|
||||||
|
|
||||||
if !is_trivially_pure_copy(self.tcx, inner_ty) {
|
if !inner_ty.is_trivially_pure_clone_copy() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,13 +202,3 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
|
||||||
terminator.kind = TerminatorKind::Goto { target: destination_block };
|
terminator.kind = TerminatorKind::Goto { target: destination_block };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_trivially_pure_copy<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
|
||||||
use TyKind::*;
|
|
||||||
match *ty.kind() {
|
|
||||||
Bool | Char | Int(..) | Uint(..) | Float(..) => true,
|
|
||||||
Array(element_ty, _len) => is_trivially_pure_copy(tcx, element_ty),
|
|
||||||
Tuple(field_tys) => field_tys.iter().all(|x| is_trivially_pure_copy(tcx, x)),
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue