Short-circuit some trivially const Drop types
This commit is contained in:
parent
33e5efbd58
commit
ba87be05cf
2 changed files with 45 additions and 10 deletions
|
@ -146,15 +146,10 @@ impl Qualif for NeedsNonConstDrop {
|
||||||
qualifs.needs_non_const_drop
|
qualifs.needs_non_const_drop
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
|
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
// Avoid selecting for simple cases.
|
// Avoid selecting for simple cases, such as builtin types.
|
||||||
match ty::util::needs_drop_components(ty, &cx.tcx.data_layout).as_deref() {
|
if ty::util::trivial_const_drop(ty) {
|
||||||
Ok([]) => return false,
|
return false;
|
||||||
Err(ty::util::AlwaysRequiresDrop) => return true,
|
|
||||||
// If we've got a single component, select with that
|
|
||||||
// to increase the chance that we hit the selection cache.
|
|
||||||
Ok([t]) => ty = t,
|
|
||||||
Ok([..]) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
|
let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
|
||||||
|
@ -187,11 +182,15 @@ impl Qualif for NeedsNonConstDrop {
|
||||||
impl_src,
|
impl_src,
|
||||||
ImplSource::ConstDrop(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
|
ImplSource::ConstDrop(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
|
||||||
) {
|
) {
|
||||||
// If our const drop candidate is not ConstDrop or implied by param,
|
// If our const drop candidate is not ConstDrop or implied by the param env,
|
||||||
// then it's bad
|
// then it's bad
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if impl_src.borrow_nested_obligations().is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If we successfully found one, then select all of the predicates
|
// If we successfully found one, then select all of the predicates
|
||||||
// implied by our const drop impl.
|
// implied by our const drop impl.
|
||||||
let mut fcx = FulfillmentContext::new();
|
let mut fcx = FulfillmentContext::new();
|
||||||
|
|
|
@ -1041,6 +1041,42 @@ pub fn needs_drop_components<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
|
||||||
|
match *ty.kind() {
|
||||||
|
ty::Bool
|
||||||
|
| ty::Char
|
||||||
|
| ty::Int(_)
|
||||||
|
| ty::Uint(_)
|
||||||
|
| ty::Float(_)
|
||||||
|
| ty::Infer(ty::IntVar(_))
|
||||||
|
| ty::Infer(ty::FloatVar(_))
|
||||||
|
| ty::Str
|
||||||
|
| ty::RawPtr(_)
|
||||||
|
| ty::Ref(..)
|
||||||
|
| ty::FnDef(..)
|
||||||
|
| ty::FnPtr(_) => true,
|
||||||
|
|
||||||
|
ty::Opaque(..)
|
||||||
|
| ty::Dynamic(..)
|
||||||
|
| ty::Error(_)
|
||||||
|
| ty::Bound(..)
|
||||||
|
| ty::Param(_)
|
||||||
|
| ty::Placeholder(_)
|
||||||
|
| ty::Never
|
||||||
|
| ty::Foreign(_)
|
||||||
|
| ty::Projection(_)
|
||||||
|
| ty::Infer(_) => false,
|
||||||
|
|
||||||
|
// Not trivial because they have components, and instead of looking inside,
|
||||||
|
// we'll just perform trait selection.
|
||||||
|
ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(_) | ty::Adt(..) => false,
|
||||||
|
|
||||||
|
ty::Array(ty, _) | ty::Slice(ty) => trivial_const_drop(ty),
|
||||||
|
|
||||||
|
ty::Tuple(tys) => tys.iter().all(|ty| trivial_const_drop(ty.expect_ty())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Does the equivalent of
|
// Does the equivalent of
|
||||||
// ```
|
// ```
|
||||||
// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
|
// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
|
||||||
|
|
Loading…
Add table
Reference in a new issue