From e9f14c505f4a87e67bf3e2f0c743a5e25119b367 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Tue, 24 Jan 2023 19:26:07 +0900 Subject: [PATCH] Remove `TypeWalk` and use `TypeFlags` instead --- crates/hir-ty/src/lib.rs | 3 +- crates/hir-ty/src/walk.rs | 147 ------------------ crates/hir/src/lib.rs | 7 +- .../rust-analyzer/src/cli/analysis_stats.rs | 10 +- 4 files changed, 8 insertions(+), 159 deletions(-) delete mode 100644 crates/hir-ty/src/walk.rs diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index cbe6873c7d5..a1182445ede 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -20,7 +20,6 @@ mod lower; mod mapping; mod tls; mod utils; -mod walk; pub mod db; pub mod diagnostics; pub mod display; @@ -71,7 +70,6 @@ pub use mapping::{ }; pub use traits::TraitEnvironment; pub use utils::{all_super_traits, is_fn_unsafe_to_call}; -pub use walk::TypeWalk; pub use chalk_ir::{ cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, @@ -107,6 +105,7 @@ pub type GenericArgData = chalk_ir::GenericArgData; pub type Ty = chalk_ir::Ty; pub type TyKind = chalk_ir::TyKind; +pub type TypeFlags = chalk_ir::TypeFlags; pub type DynTy = chalk_ir::DynTy; pub type FnPointer = chalk_ir::FnPointer; // pub type FnSubst = chalk_ir::FnSubst; diff --git a/crates/hir-ty/src/walk.rs b/crates/hir-ty/src/walk.rs deleted file mode 100644 index c476894552e..00000000000 --- a/crates/hir-ty/src/walk.rs +++ /dev/null @@ -1,147 +0,0 @@ -//! The `TypeWalk` trait (probably to be replaced by Chalk's `Fold` and -//! `Visit`). - -use chalk_ir::interner::HasInterner; - -use crate::{ - AliasEq, AliasTy, Binders, CallableSig, FnSubst, GenericArg, GenericArgData, Interner, - OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause, -}; - -/// This allows walking structures that contain types to do something with those -/// types, similar to Chalk's `Fold` trait. -pub trait TypeWalk { - fn walk(&self, f: &mut impl FnMut(&Ty)); -} - -impl TypeWalk for Ty { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - match self.kind(Interner) { - TyKind::Alias(AliasTy::Projection(p_ty)) => { - for t in p_ty.substitution.iter(Interner) { - t.walk(f); - } - } - TyKind::Alias(AliasTy::Opaque(o_ty)) => { - for t in o_ty.substitution.iter(Interner) { - t.walk(f); - } - } - TyKind::Dyn(dyn_ty) => { - for p in dyn_ty.bounds.skip_binders().interned().iter() { - p.walk(f); - } - } - TyKind::Slice(ty) - | TyKind::Array(ty, _) - | TyKind::Ref(_, _, ty) - | TyKind::Raw(_, ty) => { - ty.walk(f); - } - TyKind::Function(fn_pointer) => { - fn_pointer.substitution.0.walk(f); - } - TyKind::Adt(_, substs) - | TyKind::FnDef(_, substs) - | TyKind::Tuple(_, substs) - | TyKind::OpaqueType(_, substs) - | TyKind::AssociatedType(_, substs) - | TyKind::Closure(.., substs) => { - substs.walk(f); - } - _ => {} - } - f(self); - } -} - -impl TypeWalk for Vec { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - for t in self { - t.walk(f); - } - } -} - -impl TypeWalk for OpaqueTy { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.substitution.walk(f); - } -} - -impl TypeWalk for ProjectionTy { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.substitution.walk(f); - } -} - -impl TypeWalk for AliasTy { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - match self { - AliasTy::Projection(it) => it.walk(f), - AliasTy::Opaque(it) => it.walk(f), - } - } -} - -impl TypeWalk for GenericArg { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - if let GenericArgData::Ty(ty) = &self.interned() { - ty.walk(f); - } - } -} - -impl TypeWalk for Substitution { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - for t in self.iter(Interner) { - t.walk(f); - } - } -} - -impl> TypeWalk for Binders { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.skip_binders().walk(f); - } -} - -impl TypeWalk for TraitRef { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.substitution.walk(f); - } -} - -impl TypeWalk for WhereClause { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - match self { - WhereClause::Implemented(trait_ref) => trait_ref.walk(f), - WhereClause::AliasEq(alias_eq) => alias_eq.walk(f), - _ => {} - } - } -} - -impl TypeWalk for CallableSig { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - for t in self.params_and_return.iter() { - t.walk(f); - } - } -} - -impl TypeWalk for AliasEq { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.ty.walk(f); - match &self.alias { - AliasTy::Projection(projection_ty) => projection_ty.walk(f), - AliasTy::Opaque(opaque) => opaque.walk(f), - } - } -} - -impl TypeWalk for FnSubst { - fn walk(&self, f: &mut impl FnMut(&Ty)) { - self.0.walk(f) - } -} diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 6ec39dfd73f..4415bef4bb1 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -3168,6 +3168,8 @@ impl Type { } pub fn contains_unknown(&self) -> bool { + // FIXME: When we get rid of `ConstScalar::Unknown`, we can just look at precomputed + // `TypeFlags` in `TyData`. return go(&self.ty); fn go(ty: &Ty) -> bool { @@ -3482,10 +3484,9 @@ impl Type { Type { env: self.env.clone(), ty } } + /// Visits every type, including generic arguments, in this type. `cb` is called with type + /// itself first, and then with its generic arguments. pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { - // TypeWalk::walk for a Ty at first visits parameters and only after that the Ty itself. - // We need a different order here. - fn walk_substs( db: &dyn HirDatabase, type_: &Type, diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 053db5fc533..4b91433f63a 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -15,7 +15,7 @@ use hir_def::{ expr::ExprId, FunctionId, }; -use hir_ty::{TyExt, TypeWalk}; +use hir_ty::{Interner, TyExt, TypeFlags}; use ide::{Analysis, AnalysisHost, LineCol, RootDatabase}; use ide_db::base_db::{ salsa::{self, debug::DebugQueryTable, ParallelDatabase}, @@ -280,12 +280,8 @@ impl flags::AnalysisStats { } true } else { - let mut is_partially_unknown = false; - ty.walk(&mut |ty| { - if ty.is_unknown() { - is_partially_unknown = true; - } - }); + let is_partially_unknown = + ty.data(Interner).flags.contains(TypeFlags::HAS_ERROR); if is_partially_unknown { num_exprs_partially_unknown += 1; }