mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Auto merge of #53248 - nikomatsakis:nll-trivial-sized-predicate, r=eddyb
skip trivial `Sized` predicates This came to about a 2% win for me in cargo. Small, but hey. r? @eddyb
This commit is contained in:
commit
bfc3b20663
@ -27,9 +27,23 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
|
||||
type QueryResult = ();
|
||||
|
||||
fn try_fast_path(
|
||||
_tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
_key: &ParamEnvAnd<'tcx, Self>,
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResult> {
|
||||
// Proving Sized, very often on "obviously sized" types like
|
||||
// `&T`, accounts for about 60% percentage of the predicates
|
||||
// we have to prove. No need to canonicalize and all that for
|
||||
// such cases.
|
||||
if let Predicate::Trait(trait_ref) = key.value.predicate {
|
||||
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
|
||||
if trait_ref.def_id() == sized_def_id {
|
||||
if trait_ref.skip_binder().self_ty().is_trivially_sized(tcx) {
|
||||
return Some(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1852,6 +1852,41 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
_ => bug!("cannot convert type `{:?}` to a closure kind", self),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fast path helper for testing if a type is `Sized`.
|
||||
///
|
||||
/// Returning true means the type is known to be sized. Returning
|
||||
/// `false` means nothing -- could be sized, might not be.
|
||||
pub fn is_trivially_sized(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> bool {
|
||||
match self.sty {
|
||||
ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
|
||||
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
||||
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) |
|
||||
ty::TyChar | ty::TyRef(..) | ty::TyGenerator(..) |
|
||||
ty::TyGeneratorWitness(..) | ty::TyArray(..) | ty::TyClosure(..) |
|
||||
ty::TyNever | ty::TyError =>
|
||||
true,
|
||||
|
||||
ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) =>
|
||||
false,
|
||||
|
||||
ty::TyTuple(tys) =>
|
||||
tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
|
||||
|
||||
ty::TyAdt(def, _substs) =>
|
||||
def.sized_constraint(tcx).is_empty(),
|
||||
|
||||
ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => false,
|
||||
|
||||
ty::TyInfer(ty::TyVar(_)) => false,
|
||||
|
||||
ty::TyInfer(ty::CanonicalTy(_)) |
|
||||
ty::TyInfer(ty::FreshTy(_)) |
|
||||
ty::TyInfer(ty::FreshIntTy(_)) |
|
||||
ty::TyInfer(ty::FreshFloatTy(_)) =>
|
||||
bug!("is_trivially_sized applied to unexpected type: {:?}", self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed constant value.
|
||||
|
Loading…
Reference in New Issue
Block a user