mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 14:31:55 +00:00
Add type flags support for Ty and Const late-bound regions
This commit is contained in:
parent
e5d46a5bda
commit
3c41003873
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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`
|
||||
|
@ -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 {
|
||||
|
@ -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`
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user