1
Fork 0

add STILL_FURTHER_SPECIALIZABLE flag

This commit adds a STILL_FURTHER_SPECIALIZABLE flag to `TypeFlags`
which replaces `needs_infer` and `needs_subst` in `Instance::resolve`
and `assemble_candidates_from_impls.`

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-04-01 16:20:27 +01:00
parent b793f403bd
commit c665eaeeb0
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
6 changed files with 86 additions and 57 deletions

View file

@ -1,4 +1,4 @@
use crate::ty::subst::{GenericArgKind, SubstsRef};
use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::{self, InferConst, Ty, TypeFlags};
#[derive(Debug)]
@ -81,6 +81,7 @@ impl FlagComputation {
&ty::Param(_) => {
self.add_flags(TypeFlags::HAS_TY_PARAM);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
}
&ty::Generator(_, ref substs, _) => {
@ -99,14 +100,17 @@ impl FlagComputation {
&ty::Bound(debruijn, _) => {
self.add_binder(debruijn);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
}
&ty::Placeholder(..) => {
self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
}
&ty::Infer(infer) => {
self.add_flags(TypeFlags::HAS_TY_INFER);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
match infer {
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {}
@ -218,17 +222,23 @@ impl FlagComputation {
}
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::HAS_CT_INFER);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
match infer {
InferConst::Fresh(_) => {}
InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
}
}
ty::ConstKind::Bound(debruijn, _) => self.add_binder(debruijn),
ty::ConstKind::Bound(debruijn, _) => {
self.add_binder(debruijn);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
}
ty::ConstKind::Param(_) => {
self.add_flags(TypeFlags::HAS_CT_PARAM);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
}
ty::ConstKind::Placeholder(_) => {
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
}
ty::ConstKind::Value(_) => {}
}
@ -243,7 +253,7 @@ impl FlagComputation {
self.add_substs(projection_ty.substs);
}
fn add_substs(&mut self, substs: SubstsRef<'_>) {
fn add_substs(&mut self, substs: &[GenericArg<'_>]) {
for kind in substs {
match kind.unpack() {
GenericArgKind::Type(ty) => self.add_ty(ty),

View file

@ -142,6 +142,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
}
/// Indicates whether this value still has parameters/placeholders/inference variables
/// which could be replaced later, in a way that would change the results of `impl`
/// specialization.
fn still_further_specializable(&self) -> bool {
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
}
/// 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

@ -598,6 +598,10 @@ bitflags! {
/// Does this have any [ReErased] regions?
const HAS_RE_ERASED = 1 << 17;
/// 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 << 18;
/// Flags representing the nominal content of a type,
/// computed by FlagsComputation. If you add a new nominal
/// flag, it should be added here too.
@ -618,7 +622,8 @@ bitflags! {
| TypeFlags::HAS_TY_ERR.bits
| TypeFlags::HAS_FREE_REGIONS.bits
| TypeFlags::HAS_RE_LATE_BOUND.bits
| TypeFlags::HAS_RE_ERASED.bits;
| TypeFlags::HAS_RE_ERASED.bits
| TypeFlags::STILL_FURTHER_SPECIALIZABLE.bits;
}
}

View file

@ -1623,16 +1623,19 @@ impl RegionKind {
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_INFER;
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
}
ty::RePlaceholder(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
}
ty::ReEarlyBound(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PARAM;
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
}
ty::ReFree { .. } | ty::ReScope { .. } => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;

View file

@ -1028,7 +1028,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
let poly_trait_ref =
selcx.infcx().resolve_vars_if_possible(&poly_trait_ref);
!poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst()
!poly_trait_ref.still_further_specializable()
} else {
debug!(
"assemble_candidates_from_impls: not eligible due to default: \

View file

@ -127,7 +127,11 @@ fn resolve_associated_item<'tcx>(
// and the obligation is monomorphic, otherwise passes such as
// transmute checking and polymorphic MIR optimizations could
// get a result which isn't correct for all monomorphizations.
if param_env.reveal == Reveal::All { !trait_ref.needs_subst() } else { false }
if param_env.reveal == Reveal::All {
!trait_ref.still_further_specializable()
} else {
false
}
};
if !eligible {