ty: add MAY_POLYMORPHIZE flag

This commit adds a `MAY_POLYMORPHIZE` which checks for closures and
generators so that polymorphization of substs does not need to traverse
every substs.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-08-07 17:50:45 +01:00
parent 0d9924a87b
commit 5827b5a4bd
No known key found for this signature in database
GPG Key ID: 2592E76C87381FD9
4 changed files with 19 additions and 1 deletions

View File

@ -85,6 +85,8 @@ impl FlagComputation {
}
&ty::Generator(_, ref substs, _) => {
self.add_flags(TypeFlags::MAY_POLYMORPHIZE);
let substs = substs.as_generator();
let should_remove_further_specializable =
!self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
@ -107,6 +109,8 @@ impl FlagComputation {
}
&ty::Closure(_, substs) => {
self.add_flags(TypeFlags::MAY_POLYMORPHIZE);
let substs = substs.as_closure();
let should_remove_further_specializable =
!self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);

View File

@ -150,6 +150,12 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
}
/// Does this value contain closures or generators such that it may require
/// polymorphization?
fn may_polymorphize(&self) -> bool {
self.has_type_flags(TypeFlags::MAY_POLYMORPHIZE)
}
/// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
pub struct Visitor<F>(F);

View File

@ -528,7 +528,11 @@ fn polymorphize<'tcx>(
// ..then use the identity for this parameter.
tcx.mk_param_from_def(param),
// Otherwise, use the parameter as before (polymorphizing any closures or generators).
// If the parameter does not contain any closures or generators, then use the
// substitution directly.
_ if !substs.may_polymorphize() => substs[param.index as usize],
// Otherwise, use the substitution after polymorphizing.
_ => {
let arg = substs[param.index as usize];
let polymorphized_arg = arg.fold_with(&mut PolymorphizationFolder { tcx });

View File

@ -575,6 +575,10 @@ bitflags! {
/// Does this value have parameters/placeholders/inference variables which could be
/// replaced later, in a way that would change the results of `impl` specialization?
const STILL_FURTHER_SPECIALIZABLE = 1 << 17;
/// Does this value contain closures or generators such that it may require
/// polymorphization?
const MAY_POLYMORPHIZE = 1 << 18;
}
}