Skip to content

Add type flags support for Ty and Const late-bound variables #105733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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