add TypeFlags::HAS_NON_REGION_ERROR and TypeFlags::HAS_RE_ERROR

This commit is contained in:
Makai
2026-03-16 22:07:03 +08:00
parent 12ab1cf1fd
commit e18dd4a992
3 changed files with 38 additions and 14 deletions
+1 -1
View File
@@ -291,7 +291,7 @@ pub fn type_flags(self) -> TypeFlags {
}
ty::ReError(_) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_ERROR;
flags = flags | TypeFlags::HAS_RE_ERROR;
}
}
+18 -13
View File
@@ -91,19 +91,24 @@ pub struct TypeFlags: u32 {
| TypeFlags::HAS_TY_INHERENT.bits()
| TypeFlags::HAS_CT_PROJECTION.bits();
/// Is a type or const error reachable?
const HAS_NON_REGION_ERROR = 1 << 15;
/// Is a region error reachable?
const HAS_RE_ERROR = 1 << 16;
/// Is an error type/lifetime/const reachable?
const HAS_ERROR = 1 << 15;
const HAS_ERROR = TypeFlags::HAS_NON_REGION_ERROR.bits()
| TypeFlags::HAS_RE_ERROR.bits();
/// Does this have any region that "appears free" in the type?
/// Basically anything but `ReBound` and `ReErased`.
const HAS_FREE_REGIONS = 1 << 16;
const HAS_FREE_REGIONS = 1 << 17;
/// Does this have any `ReBound` regions?
const HAS_RE_BOUND = 1 << 17;
const HAS_RE_BOUND = 1 << 18;
/// Does this have any `Bound` types?
const HAS_TY_BOUND = 1 << 18;
const HAS_TY_BOUND = 1 << 19;
/// Does this have any `ConstKind::Bound` consts?
const HAS_CT_BOUND = 1 << 19;
const HAS_CT_BOUND = 1 << 20;
/// Does this have any bound variables?
/// Used to check if a global bound is safe to evaluate.
const HAS_BOUND_VARS = TypeFlags::HAS_RE_BOUND.bits()
@@ -111,7 +116,7 @@ pub struct TypeFlags: u32 {
| TypeFlags::HAS_CT_BOUND.bits();
/// Does this have any `ReErased` regions?
const HAS_RE_ERASED = 1 << 20;
const HAS_RE_ERASED = 1 << 21;
/// Does this value have parameters/placeholders/inference variables which could be
/// replaced later, in a way that would change the results of `impl` specialization?
@@ -123,19 +128,19 @@ pub struct TypeFlags: u32 {
| TypeFlags::HAS_CT_INFER.bits();
/// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?
const HAS_TY_FRESH = 1 << 21;
const HAS_TY_FRESH = 1 << 22;
/// Does this value have `InferConst::Fresh`?
const HAS_CT_FRESH = 1 << 22;
const HAS_CT_FRESH = 1 << 23;
/// Does this have any binders with bound vars (e.g. that need to be anonymized)?
const HAS_BINDER_VARS = 1 << 23;
const HAS_BINDER_VARS = 1 << 24;
/// Does this type have any coroutines in it?
const HAS_TY_CORO = 1 << 24;
const HAS_TY_CORO = 1 << 25;
/// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`?
const HAS_CANONICAL_BOUND = 1 << 25;
const HAS_CANONICAL_BOUND = 1 << 26;
}
}
@@ -240,7 +245,7 @@ fn add_kind(&mut self, kind: &ty::TyKind<I>) {
| ty::Str
| ty::Foreign(..) => {}
ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
ty::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR),
ty::Param(_) => {
self.add_flags(TypeFlags::HAS_TY_PARAM);
@@ -489,7 +494,7 @@ fn add_const_kind(&mut self, c: &ty::ConstKind<I>) {
}
}
ty::ConstKind::Expr(e) => self.add_args(e.args().as_slice()),
ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR),
}
}
+19
View File
@@ -279,6 +279,8 @@ fn references_error(&self) -> bool {
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed>;
fn non_region_error_reported(&self) -> Result<(), I::ErrorGuaranteed>;
fn has_non_region_param(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
}
@@ -352,6 +354,11 @@ fn has_bound_vars(&self) -> bool {
fn still_further_specializable(&self) -> bool {
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
}
/// True if a type or const error is reachable
fn has_non_region_error(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_NON_REGION_ERROR)
}
}
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T {
@@ -376,6 +383,18 @@ fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> {
Ok(())
}
}
fn non_region_error_reported(&self) -> Result<(), I::ErrorGuaranteed> {
if self.has_non_region_error() {
if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) {
Err(guar)
} else {
panic!("type flags said there was an non region error, but now there is not")
}
} else {
Ok(())
}
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]