about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-24 12:08:51 +0000
committerbors <bors@rust-lang.org>2023-01-24 12:08:51 +0000
commit86f73a00815274f003cd03f819070d010a5d3aad (patch)
tree81aede515fd002bb5ff681782b416eb81154a30d
parente46c242a38396c5dd1cb85b5002ca17f83c4c1b7 (diff)
parente9f14c505f4a87e67bf3e2f0c743a5e25119b367 (diff)
downloadrust-86f73a00815274f003cd03f819070d010a5d3aad.tar.gz
rust-86f73a00815274f003cd03f819070d010a5d3aad.zip
Auto merge of #14017 - lowr:patch/remove-type-walk, r=Veykril
internal: remove `TypeWalk`

Because less code is better!

`hir_ty::TypeWalk` is only used in analysis-stats and its usage can be replaced by checking `TypeFlags` (which is precomputed upon `TyKind` interning so it should make analysis-stats a bit faster, though it was really negligible in my local environment).

We should just use chalk's `TypeVisitor` or `TypeFolder` instead even if we come to need it again.
-rw-r--r--crates/hir-ty/src/lib.rs3
-rw-r--r--crates/hir-ty/src/walk.rs147
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs10
4 files changed, 8 insertions, 159 deletions
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<Interner>;
 
 pub type Ty = chalk_ir::Ty<Interner>;
 pub type TyKind = chalk_ir::TyKind<Interner>;
+pub type TypeFlags = chalk_ir::TypeFlags;
 pub type DynTy = chalk_ir::DynTy<Interner>;
 pub type FnPointer = chalk_ir::FnPointer<Interner>;
 // pub type FnSubst = chalk_ir::FnSubst<Interner>;
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<T: TypeWalk> TypeWalk for Vec<T> {
-    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<T: TypeWalk + HasInterner<Interner = Interner>> TypeWalk for Binders<T> {
-    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<Interner> {
-    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;
                     }