Skip to content

Commit

Permalink
Auto merge of #105733 - compiler-errors:ty-ct-late-flags, r=cjgillot
Browse files Browse the repository at this point in the history
Add type flags support for `Ty` and `Const` late-bound variables

I've been working on `for<T>` binders, and these will eventually be useful.
  • Loading branch information
bors committed Jan 8, 2023
2 parents 8ea62f6 + 3c41003 commit e6485ed
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 14 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/erase_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 14 additions & 2 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -131,6 +141,7 @@ impl FlagComputation {

&ty::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
self.add_flags(TypeFlags::HAS_TY_LATE_BOUND);
}

&ty::Placeholder(..) => {
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/ty/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_symbol_mangling/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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`
Expand Down
20 changes: 14 additions & 6 deletions compiler/rustc_type_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down

0 comments on commit e6485ed

Please sign in to comment.