Add type flags support for Ty and Const late-bound regions

This commit is contained in:
Michael Goulet 2022-12-15 02:38:39 +00:00
parent e5d46a5bda
commit 3c41003873
7 changed files with 42 additions and 14 deletions

View File

@ -1912,7 +1912,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
}
let pred = obligation.predicate;
// Match the existing behavior.
if pred.is_global() && !pred.has_late_bound_regions() {
if pred.is_global() && !pred.has_late_bound_vars() {
let pred = self.normalize(span, None, pred);
let hir_node = tcx.hir().find(self.body_id);

View File

@ -21,7 +21,7 @@ impl<'tcx> TyCtxt<'tcx> {
T: TypeFoldable<'tcx>,
{
// If there's nothing to erase avoid performing the query at all
if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) {
if !value.has_type_flags(TypeFlags::HAS_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) {
return value;
}
debug!("erase_regions({:?})", value);

View File

@ -59,8 +59,18 @@ impl FlagComputation {
{
let mut computation = FlagComputation::new();
if !value.bound_vars().is_empty() {
computation.flags = computation.flags | TypeFlags::HAS_RE_LATE_BOUND;
for bv in value.bound_vars() {
match bv {
ty::BoundVariableKind::Ty(_) => {
computation.flags |= TypeFlags::HAS_TY_LATE_BOUND;
}
ty::BoundVariableKind::Region(_) => {
computation.flags |= TypeFlags::HAS_RE_LATE_BOUND;
}
ty::BoundVariableKind::Const => {
computation.flags |= TypeFlags::HAS_CT_LATE_BOUND;
}
}
}
f(&mut computation, value.skip_binder());
@ -131,6 +141,7 @@ impl FlagComputation {
&ty::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
self.add_flags(TypeFlags::HAS_TY_LATE_BOUND);
}
&ty::Placeholder(..) => {
@ -303,6 +314,7 @@ impl FlagComputation {
}
ty::ConstKind::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
self.add_flags(TypeFlags::HAS_CT_LATE_BOUND);
}
ty::ConstKind::Param(_) => {
self.add_flags(TypeFlags::HAS_CT_PARAM);

View File

@ -165,6 +165,14 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone {
fn has_late_bound_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
}
/// True if there are any late-bound non-region variables
fn has_non_region_late_bound(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_LATE_BOUND - TypeFlags::HAS_RE_LATE_BOUND)
}
/// True if there are any late-bound variables
fn has_late_bound_vars(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_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`

View File

@ -206,6 +206,7 @@ impl<'tcx> SymbolMangler<'tcx> {
where
T: TypeVisitable<'tcx>,
{
// FIXME(non-lifetime-binders): What to do here?
let regions = if value.has_late_bound_regions() {
self.tcx.collect_referenced_late_bound_regions(value)
} else {

View File

@ -755,7 +755,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// contain the "'static" lifetime (any other lifetime
// would either be late-bound or local), so it is guaranteed
// to outlive any other lifetime
if pred.0.is_global() && !pred.0.has_late_bound_regions() {
if pred.0.is_global() && !pred.0.has_late_bound_vars() {
Ok(EvaluatedToOk)
} else {
Ok(EvaluatedToOkModuloRegions)
@ -1785,9 +1785,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Check if a bound would previously have been removed when normalizing
// the param_env so that it can be given the lowest priority. See
// #50825 for the motivation for this.
let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| {
cand.is_global() && !cand.has_late_bound_regions()
};
let is_global =
|cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_late_bound_vars();
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
// `DiscriminantKindCandidate`, `ConstDestructCandidate`

View File

@ -241,22 +241,30 @@ bitflags! {
/// Basically anything but `ReLateBound` and `ReErased`.
const HAS_FREE_REGIONS = 1 << 14;
/// Does this have any `ReLateBound` regions? Used to check
/// if a global bound is safe to evaluate.
/// Does this have any `ReLateBound` regions?
const HAS_RE_LATE_BOUND = 1 << 15;
/// Does this have any `Bound` types?
const HAS_TY_LATE_BOUND = 1 << 16;
/// Does this have any `ConstKind::Bound` consts?
const HAS_CT_LATE_BOUND = 1 << 17;
/// Does this have any bound variables?
/// Used to check if a global bound is safe to evaluate.
const HAS_LATE_BOUND = TypeFlags::HAS_RE_LATE_BOUND.bits
| TypeFlags::HAS_TY_LATE_BOUND.bits
| TypeFlags::HAS_CT_LATE_BOUND.bits;
/// Does this have any `ReErased` regions?
const HAS_RE_ERASED = 1 << 16;
const HAS_RE_ERASED = 1 << 18;
/// 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;
const STILL_FURTHER_SPECIALIZABLE = 1 << 19;
/// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?
const HAS_TY_FRESH = 1 << 18;
const HAS_TY_FRESH = 1 << 20;
/// Does this value have `InferConst::Fresh`?
const HAS_CT_FRESH = 1 << 19;
const HAS_CT_FRESH = 1 << 21;
}
}