aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-02-09 17:27:11 +0000
committerFlorian Diebold <[email protected]>2019-02-10 09:56:58 +0000
commit6964a88e8c90f06220498d3e9194b7e2073c1e32 (patch)
treea3f8e225118c810d5c2784d64b559e3e05e6b6db
parent43e52ac9e2b26ec287b1778823bad10851cfd44e (diff)
Add an ra_cli command that analyses all crates in the current workspace
... and prints various stats about how many expressions have a type etc.
-rw-r--r--Cargo.lock27
-rw-r--r--crates/ra_batch/src/lib.rs9
-rw-r--r--crates/ra_cli/Cargo.toml6
-rw-r--r--crates/ra_cli/src/analysis_stats.rs100
-rw-r--r--crates/ra_cli/src/main.rs11
-rw-r--r--crates/ra_db/src/input.rs1
-rw-r--r--crates/ra_hir/src/code_model_api.rs34
-rw-r--r--crates/ra_hir/src/expr.rs8
-rw-r--r--crates/ra_hir/src/ty.rs35
9 files changed, 227 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 74a77ddc9..0a5bec2bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -487,6 +487,18 @@ version = "1.0.2"
487source = "registry+https://github.com/rust-lang/crates.io-index" 487source = "registry+https://github.com/rust-lang/crates.io-index"
488 488
489[[package]] 489[[package]]
490name = "indicatif"
491version = "0.11.0"
492source = "registry+https://github.com/rust-lang/crates.io-index"
493dependencies = [
494 "console 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
495 "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
496 "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
497 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
498 "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
499]
500
501[[package]]
490name = "inotify" 502name = "inotify"
491version = "0.6.1" 503version = "0.6.1"
492source = "registry+https://github.com/rust-lang/crates.io-index" 504source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -781,6 +793,14 @@ dependencies = [
781] 793]
782 794
783[[package]] 795[[package]]
796name = "number_prefix"
797version = "0.2.8"
798source = "registry+https://github.com/rust-lang/crates.io-index"
799dependencies = [
800 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
801]
802
803[[package]]
784name = "owning_ref" 804name = "owning_ref"
785version = "0.4.0" 805version = "0.4.0"
786source = "registry+https://github.com/rust-lang/crates.io-index" 806source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -930,7 +950,12 @@ version = "0.1.0"
930dependencies = [ 950dependencies = [
931 "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", 951 "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
932 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 952 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
953 "flexi_logger 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
954 "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
933 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 955 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
956 "ra_batch 0.1.0",
957 "ra_db 0.1.0",
958 "ra_hir 0.1.0",
934 "ra_ide_api_light 0.1.0", 959 "ra_ide_api_light 0.1.0",
935 "ra_syntax 0.1.0", 960 "ra_syntax 0.1.0",
936 "tools 0.1.0", 961 "tools 0.1.0",
@@ -1949,6 +1974,7 @@ dependencies = [
1949"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1974"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
1950"checksum im 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0627d417829c1d763d602687634869f254fc79f7e22dea6c824dab993db857e4" 1975"checksum im 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0627d417829c1d763d602687634869f254fc79f7e22dea6c824dab993db857e4"
1951"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" 1976"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
1977"checksum indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c60da1c9abea75996b70a931bba6c750730399005b61ccd853cee50ef3d0d0c"
1952"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" 1978"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
1953"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" 1979"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
1954"checksum insta 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcdfb5ab565a1fc5c397722d5a9503f2095696ef07ef1a222d85a0fd6666c6aa" 1980"checksum insta 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcdfb5ab565a1fc5c397722d5a9503f2095696ef07ef1a222d85a0fd6666c6aa"
@@ -1982,6 +2008,7 @@ dependencies = [
1982"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" 2008"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
1983"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" 2009"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
1984"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" 2010"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"
2011"checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee"
1985"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" 2012"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
1986"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" 2013"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
1987"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" 2014"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index ea91d88b7..014663546 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -60,7 +60,11 @@ impl BatchDatabase {
60 match change { 60 match change {
61 VfsChange::AddRoot { root, files } => { 61 VfsChange::AddRoot { root, files } => {
62 let source_root_id = vfs_root_to_id(root); 62 let source_root_id = vfs_root_to_id(root);
63 log::debug!("loaded source root {:?} with path {:?}", source_root_id, vfs.root2path(root)); 63 log::debug!(
64 "loaded source root {:?} with path {:?}",
65 source_root_id,
66 vfs.root2path(root)
67 );
64 let mut file_map = FxHashMap::default(); 68 let mut file_map = FxHashMap::default();
65 for (vfs_file, path, text) in files { 69 for (vfs_file, path, text) in files {
66 let file_id = vfs_file_to_id(vfs_file); 70 let file_id = vfs_file_to_id(vfs_file);
@@ -111,7 +115,8 @@ impl BatchDatabase {
111 let crate_graph = ws.to_crate_graph(&mut load); 115 let crate_graph = ws.to_crate_graph(&mut load);
112 log::debug!("crate graph: {:?}", crate_graph); 116 log::debug!("crate graph: {:?}", crate_graph);
113 117
114 let local_roots = roots.into_iter() 118 let local_roots = roots
119 .into_iter()
115 .filter(|r| vfs.root2path(*r).starts_with(&root)) 120 .filter(|r| vfs.root2path(*r).starts_with(&root))
116 .map(vfs_root_to_id) 121 .map(vfs_root_to_id)
117 .collect(); 122 .collect();
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml
index eb1722d5e..641ac5cbd 100644
--- a/crates/ra_cli/Cargo.toml
+++ b/crates/ra_cli/Cargo.toml
@@ -9,6 +9,12 @@ publish = false
9clap = "2.32.0" 9clap = "2.32.0"
10failure = "0.1.4" 10failure = "0.1.4"
11join_to_string = "0.1.1" 11join_to_string = "0.1.1"
12flexi_logger = "0.10.0"
13indicatif = "0.11.0"
14
12ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
13ra_ide_api_light = { path = "../ra_ide_api_light" } 16ra_ide_api_light = { path = "../ra_ide_api_light" }
14tools = { path = "../tools" } 17tools = { path = "../tools" }
18ra_batch = { path = "../ra_batch" }
19ra_hir = { path = "../ra_hir" }
20ra_db = { path = "../ra_db" }
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs
new file mode 100644
index 000000000..a46ac974d
--- /dev/null
+++ b/crates/ra_cli/src/analysis_stats.rs
@@ -0,0 +1,100 @@
1use std::collections::HashSet;
2
3use ra_db::SourceDatabase;
4use ra_batch::BatchDatabase;
5use ra_hir::{Crate, ModuleDef, Ty, ImplItem};
6use ra_syntax::AstNode;
7
8use crate::Result;
9
10pub fn run(verbose: bool) -> Result<()> {
11 let (db, roots) = BatchDatabase::load_cargo(".")?;
12 println!("Database loaded, {} roots", roots.len());
13 let mut num_crates = 0;
14 let mut visited_modules = HashSet::new();
15 let mut visit_queue = Vec::new();
16 for root in roots {
17 for krate in Crate::source_root_crates(&db, root) {
18 num_crates += 1;
19 let module = krate.root_module(&db).expect("crate in source root without root module");
20 visit_queue.push(module);
21 }
22 }
23 println!("Crates in this dir: {}", num_crates);
24 let mut num_decls = 0;
25 let mut funcs = Vec::new();
26 while let Some(module) = visit_queue.pop() {
27 if visited_modules.insert(module) {
28 visit_queue.extend(module.children(&db));
29
30 for decl in module.declarations(&db) {
31 num_decls += 1;
32 match decl {
33 ModuleDef::Function(f) => funcs.push(f),
34 _ => {}
35 }
36 }
37
38 for impl_block in module.impl_blocks(&db) {
39 for item in impl_block.items() {
40 num_decls += 1;
41 match item {
42 ImplItem::Method(f) => funcs.push(*f),
43 _ => {}
44 }
45 }
46 }
47 }
48 }
49 println!("Total modules found: {}", visited_modules.len());
50 println!("Total declarations: {}", num_decls);
51 println!("Total functions: {}", funcs.len());
52 let bar = indicatif::ProgressBar::new(funcs.len() as u64);
53 bar.tick();
54 let mut num_exprs = 0;
55 let mut num_exprs_unknown = 0;
56 let mut num_exprs_partially_unknown = 0;
57 for f in funcs {
58 if verbose {
59 let (file_id, source) = f.source(&db);
60 let original_file = file_id.original_file(&db);
61 let path = db.file_relative_path(original_file);
62 let syntax_range = source.syntax().range();
63 let name = f.name(&db);
64 println!("{} ({:?} {})", name, path, syntax_range);
65 }
66 let body = f.body(&db);
67 let inference_result = f.infer(&db);
68 for (expr_id, _) in body.exprs() {
69 let ty = &inference_result[expr_id];
70 num_exprs += 1;
71 if let Ty::Unknown = ty {
72 num_exprs_unknown += 1;
73 } else {
74 let mut is_partially_unknown = false;
75 ty.walk(&mut |ty| {
76 if let Ty::Unknown = ty {
77 is_partially_unknown = true;
78 }
79 });
80 if is_partially_unknown {
81 num_exprs_partially_unknown += 1;
82 }
83 }
84 }
85 bar.inc(1);
86 }
87 bar.finish_and_clear();
88 println!("Total expressions: {}", num_exprs);
89 println!(
90 "Expressions of unknown type: {} ({}%)",
91 num_exprs_unknown,
92 (num_exprs_unknown * 100 / num_exprs)
93 );
94 println!(
95 "Expressions of partially unknown type: {} ({}%)",
96 num_exprs_partially_unknown,
97 (num_exprs_partially_unknown * 100 / num_exprs)
98 );
99 Ok(())
100}
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index a4debeb48..72e6ae4d5 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -1,3 +1,5 @@
1mod analysis_stats;
2
1use std::{fs, io::Read, path::Path, time::Instant}; 3use std::{fs, io::Read, path::Path, time::Instant};
2 4
3use clap::{App, Arg, SubCommand}; 5use clap::{App, Arg, SubCommand};
@@ -5,10 +7,12 @@ use join_to_string::join;
5use ra_ide_api_light::{extend_selection, file_structure, syntax_tree}; 7use ra_ide_api_light::{extend_selection, file_structure, syntax_tree};
6use ra_syntax::{SourceFile, TextRange, TreeArc, AstNode}; 8use ra_syntax::{SourceFile, TextRange, TreeArc, AstNode};
7use tools::collect_tests; 9use tools::collect_tests;
10use flexi_logger::Logger;
8 11
9type Result<T> = ::std::result::Result<T, failure::Error>; 12type Result<T> = ::std::result::Result<T, failure::Error>;
10 13
11fn main() -> Result<()> { 14fn main() -> Result<()> {
15 Logger::with_env().start()?;
12 let matches = App::new("ra-cli") 16 let matches = App::new("ra-cli")
13 .setting(clap::AppSettings::SubcommandRequiredElseHelp) 17 .setting(clap::AppSettings::SubcommandRequiredElseHelp)
14 .subcommand( 18 .subcommand(
@@ -23,6 +27,9 @@ fn main() -> Result<()> {
23 .arg(Arg::with_name("start")) 27 .arg(Arg::with_name("start"))
24 .arg(Arg::with_name("end")), 28 .arg(Arg::with_name("end")),
25 ) 29 )
30 .subcommand(
31 SubCommand::with_name("analysis-stats").arg(Arg::with_name("verbose").short("v")),
32 )
26 .get_matches(); 33 .get_matches();
27 match matches.subcommand() { 34 match matches.subcommand() {
28 ("parse", Some(matches)) => { 35 ("parse", Some(matches)) => {
@@ -56,6 +63,10 @@ fn main() -> Result<()> {
56 let sels = selections(&file, start, end); 63 let sels = selections(&file, start, end);
57 println!("{}", sels) 64 println!("{}", sels)
58 } 65 }
66 ("analysis-stats", Some(matches)) => {
67 let verbose = matches.is_present("verbose");
68 analysis_stats::run(verbose)?;
69 }
59 _ => unreachable!(), 70 _ => unreachable!(),
60 } 71 }
61 Ok(()) 72 Ok(())
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index 405634fe0..8decc65c5 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -112,6 +112,7 @@ impl CrateGraph {
112 self.arena[&crate_id].file_id 112 self.arena[&crate_id].file_id
113 } 113 }
114 114
115 // TODO: this only finds one crate with the given root; we could have multiple
115 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { 116 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
116 let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; 117 let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
117 Some(crate_id) 118 Some(crate_id)
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index cafc5279d..19f103855 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,7 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
4use ra_db::{CrateId, FileId}; 4use ra_db::{CrateId, FileId, SourceRootId};
5use ra_syntax::{ast::self, TreeArc, SyntaxNode}; 5use ra_syntax::{ast::self, TreeArc, SyntaxNode};
6 6
7use crate::{ 7use crate::{
@@ -16,7 +16,7 @@ use crate::{
16 docs::{Documentation, Docs, docs_from_ast}, 16 docs::{Documentation, Docs, docs_from_ast},
17 module_tree::ModuleId, 17 module_tree::ModuleId,
18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, 18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
19 impl_block::ImplId, 19 impl_block::{ImplId, ImplBlock},
20 resolve::Resolver, 20 resolve::Resolver,
21}; 21};
22 22
@@ -44,6 +44,15 @@ impl Crate {
44 pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> { 44 pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> {
45 self.root_module_impl(db) 45 self.root_module_impl(db)
46 } 46 }
47
48 // TODO: should this be in source_binder?
49 pub fn source_root_crates(
50 db: &impl PersistentHirDatabase,
51 source_root: SourceRootId,
52 ) -> Vec<Crate> {
53 let crate_ids = db.source_root_crates(source_root);
54 crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect()
55 }
47} 56}
48 57
49#[derive(Debug)] 58#[derive(Debug)]
@@ -168,6 +177,27 @@ impl Module {
168 let item_map = db.item_map(self.krate); 177 let item_map = db.item_map(self.krate);
169 Resolver::default().push_module_scope(item_map, *self) 178 Resolver::default().push_module_scope(item_map, *self)
170 } 179 }
180
181 pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> {
182 let (lowered_module, _) = db.lower_module(self);
183 lowered_module
184 .declarations
185 .values()
186 .cloned()
187 .flat_map(|per_ns| {
188 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
189 })
190 .collect()
191 }
192
193 pub fn impl_blocks(self, db: &impl HirDatabase) -> Vec<ImplBlock> {
194 let module_impl_blocks = db.impls_in_module(self);
195 module_impl_blocks
196 .impls
197 .iter()
198 .map(|(impl_id, _)| ImplBlock::from_id(module_impl_blocks.clone(), impl_id))
199 .collect()
200 }
171} 201}
172 202
173impl Docs for Module { 203impl Docs for Module {
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index b30e11abb..4e73590d0 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -70,6 +70,14 @@ impl Body {
70 self.owner 70 self.owner
71 } 71 }
72 72
73 pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> {
74 self.exprs.iter()
75 }
76
77 pub fn pats(&self) -> impl Iterator<Item = (PatId, &Pat)> {
78 self.pats.iter()
79 }
80
73 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { 81 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> {
74 db.body_syntax_mapping(self.owner) 82 db.body_syntax_mapping(self.owner)
75 } 83 }
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 7203a8a10..08561573b 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -449,6 +449,41 @@ impl Ty {
449 Ty::Tuple(Arc::new([])) 449 Ty::Tuple(Arc::new([]))
450 } 450 }
451 451
452 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
453 f(self);
454 match self {
455 Ty::Slice(t) | Ty::Array(t) => t.walk(f),
456 Ty::RawPtr(t, _) => t.walk(f),
457 Ty::Ref(t, _) => t.walk(f),
458 Ty::Tuple(ts) => {
459 for t in ts.iter() {
460 t.walk(f);
461 }
462 }
463 Ty::FnPtr(sig) => {
464 for input in &sig.input {
465 input.walk(f);
466 }
467 sig.output.walk(f);
468 }
469 Ty::FnDef { substs, sig, .. } => {
470 for input in &sig.input {
471 input.walk(f);
472 }
473 sig.output.walk(f);
474 for t in substs.0.iter() {
475 t.walk(f);
476 }
477 }
478 Ty::Adt { substs, .. } => {
479 for t in substs.0.iter() {
480 t.walk(f);
481 }
482 }
483 _ => {}
484 }
485 }
486
452 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 487 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
453 f(self); 488 f(self);
454 match self { 489 match self {