Skip to content

Commit bfc3b20

Browse files
committed
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
2 parents b355906 + 1341e66 commit bfc3b20

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

src/librustc/traits/query/type_op/prove_predicate.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,23 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
2727
type QueryResult = ();
2828

2929
fn try_fast_path(
30-
_tcx: TyCtxt<'_, 'gcx, 'tcx>,
31-
_key: &ParamEnvAnd<'tcx, Self>,
30+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
31+
key: &ParamEnvAnd<'tcx, Self>,
3232
) -> Option<Self::QueryResult> {
33+
// Proving Sized, very often on "obviously sized" types like
34+
// `&T`, accounts for about 60% percentage of the predicates
35+
// we have to prove. No need to canonicalize and all that for
36+
// such cases.
37+
if let Predicate::Trait(trait_ref) = key.value.predicate {
38+
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
39+
if trait_ref.def_id() == sized_def_id {
40+
if trait_ref.skip_binder().self_ty().is_trivially_sized(tcx) {
41+
return Some(());
42+
}
43+
}
44+
}
45+
}
46+
3347
None
3448
}
3549

src/librustc/ty/sty.rs

+35
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,41 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
18521852
_ => bug!("cannot convert type `{:?}` to a closure kind", self),
18531853
}
18541854
}
1855+
1856+
/// Fast path helper for testing if a type is `Sized`.
1857+
///
1858+
/// Returning true means the type is known to be sized. Returning
1859+
/// `false` means nothing -- could be sized, might not be.
1860+
pub fn is_trivially_sized(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> bool {
1861+
match self.sty {
1862+
ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
1863+
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
1864+
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) |
1865+
ty::TyChar | ty::TyRef(..) | ty::TyGenerator(..) |
1866+
ty::TyGeneratorWitness(..) | ty::TyArray(..) | ty::TyClosure(..) |
1867+
ty::TyNever | ty::TyError =>
1868+
true,
1869+
1870+
ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) =>
1871+
false,
1872+
1873+
ty::TyTuple(tys) =>
1874+
tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
1875+
1876+
ty::TyAdt(def, _substs) =>
1877+
def.sized_constraint(tcx).is_empty(),
1878+
1879+
ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => false,
1880+
1881+
ty::TyInfer(ty::TyVar(_)) => false,
1882+
1883+
ty::TyInfer(ty::CanonicalTy(_)) |
1884+
ty::TyInfer(ty::FreshTy(_)) |
1885+
ty::TyInfer(ty::FreshIntTy(_)) |
1886+
ty::TyInfer(ty::FreshFloatTy(_)) =>
1887+
bug!("is_trivially_sized applied to unexpected type: {:?}", self),
1888+
}
1889+
}
18551890
}
18561891

18571892
/// Typed constant value.

0 commit comments

Comments
 (0)