Skip to content

Commit

Permalink
Short-circuit some trivially const Drop types
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 19, 2022
1 parent 33e5efb commit ba87be0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
19 changes: 9 additions & 10 deletions compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,10 @@ impl Qualif for NeedsNonConstDrop {
qualifs.needs_non_const_drop
}

fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
// Avoid selecting for simple cases.
match ty::util::needs_drop_components(ty, &cx.tcx.data_layout).as_deref() {
Ok([]) => 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([..]) => {}
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
// Avoid selecting for simple cases, such as builtin types.
if ty::util::trivial_const_drop(ty) {
return false;
}

let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
Expand Down Expand Up @@ -187,11 +182,15 @@ impl Qualif for NeedsNonConstDrop {
impl_src,
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
return true;
}

if impl_src.borrow_nested_obligations().is_empty() {
return false;
}

// If we successfully found one, then select all of the predicates
// implied by our const drop impl.
let mut fcx = FulfillmentContext::new();
Expand Down
36 changes: 36 additions & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// ```
// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
Expand Down

0 comments on commit ba87be0

Please sign in to comment.