aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-10-20 16:09:51 +0100
committerGitHub <[email protected]>2020-10-20 16:09:51 +0100
commit1c24f57ef8420e924e904ec481e7c6471f3ddcc8 (patch)
treec7f1ebcc5979838d1747cf19dd562004916a7274 /crates
parentbe762ccccd5a86632e60351518528d078785a3e2 (diff)
parent3b1a648539487c08bc613b6fd6e573b0e0e38948 (diff)
Merge #6295
6295: More type safety around names r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/utils.rs2
-rw-r--r--crates/base_db/src/fixture.rs4
-rw-r--r--crates/base_db/src/input.rs57
-rw-r--r--crates/base_db/src/lib.rs4
-rw-r--r--crates/hir/src/code_model.rs6
-rw-r--r--crates/hir_def/src/import_map.rs6
-rw-r--r--crates/hir_def/src/nameres.rs6
-rw-r--r--crates/ide/src/doc_links.rs8
-rw-r--r--crates/ide/src/hover.rs2
-rw-r--r--crates/ide/src/inlay_hints.rs7
-rw-r--r--crates/ide/src/prime_caches.rs3
-rw-r--r--crates/ide/src/status.rs2
-rw-r--r--crates/project_model/src/lib.rs8
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs8
14 files changed, 76 insertions, 47 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index b37b0d2b6..4e89a7aed 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -406,7 +406,7 @@ pub use prelude::*;
406 let std_crate = path.next()?; 406 let std_crate = path.next()?;
407 let std_crate = if self 407 let std_crate = if self
408 .1 408 .1
409 .declaration_name(db) 409 .display_name(db)
410 .map(|name| name.to_string() == std_crate) 410 .map(|name| name.to_string() == std_crate)
411 .unwrap_or(false) 411 .unwrap_or(false)
412 { 412 {
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index 72f1fd667..66e6443cb 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -158,7 +158,7 @@ impl ChangeFixture {
158 let crate_id = crate_graph.add_crate_root( 158 let crate_id = crate_graph.add_crate_root(
159 file_id, 159 file_id,
160 meta.edition, 160 meta.edition,
161 Some(crate_name.clone()), 161 Some(crate_name.clone().into()),
162 meta.cfg, 162 meta.cfg,
163 meta.env, 163 meta.env,
164 Default::default(), 164 Default::default(),
@@ -187,7 +187,7 @@ impl ChangeFixture {
187 crate_graph.add_crate_root( 187 crate_graph.add_crate_root(
188 crate_root, 188 crate_root,
189 Edition::Edition2018, 189 Edition::Edition2018,
190 Some(CrateName::new("test").unwrap()), 190 Some(CrateName::new("test").unwrap().into()),
191 default_cfg, 191 default_cfg,
192 Env::default(), 192 Env::default(),
193 Default::default(), 193 Default::default(),
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index b870e2cee..87f0a0ce5 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -102,11 +102,46 @@ impl fmt::Display for CrateName {
102 102
103impl ops::Deref for CrateName { 103impl ops::Deref for CrateName {
104 type Target = str; 104 type Target = str;
105 fn deref(&self) -> &Self::Target { 105 fn deref(&self) -> &str {
106 &*self.0 106 &*self.0
107 } 107 }
108} 108}
109 109
110#[derive(Debug, Clone, PartialEq, Eq, Hash)]
111pub struct CrateDisplayName {
112 // The name we use to display various paths (with `_`).
113 crate_name: CrateName,
114 // The name as specified in Cargo.toml (with `-`).
115 canonical_name: String,
116}
117
118impl From<CrateName> for CrateDisplayName {
119 fn from(crate_name: CrateName) -> CrateDisplayName {
120 let canonical_name = crate_name.to_string();
121 CrateDisplayName { crate_name, canonical_name }
122 }
123}
124
125impl fmt::Display for CrateDisplayName {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 write!(f, "{}", self.crate_name)
128 }
129}
130
131impl ops::Deref for CrateDisplayName {
132 type Target = str;
133 fn deref(&self) -> &str {
134 &*self.crate_name
135 }
136}
137
138impl CrateDisplayName {
139 pub fn from_canonical_name(canonical_name: String) -> CrateDisplayName {
140 let crate_name = CrateName::normalize_dashes(&canonical_name);
141 CrateDisplayName { crate_name, canonical_name }
142 }
143}
144
110#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 145#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
111pub struct ProcMacroId(pub u32); 146pub struct ProcMacroId(pub u32);
112 147
@@ -127,11 +162,13 @@ impl PartialEq for ProcMacro {
127pub struct CrateData { 162pub struct CrateData {
128 pub root_file_id: FileId, 163 pub root_file_id: FileId,
129 pub edition: Edition, 164 pub edition: Edition,
130 /// A name used in the package's project declaration: for Cargo projects, it's [package].name, 165 /// A name used in the package's project declaration: for Cargo projects,
131 /// can be different for other project types or even absent (a dummy crate for the code snippet, for example). 166 /// it's [package].name, can be different for other project types or even
132 /// NOTE: The crate can be referenced as a dependency under a different name, 167 /// absent (a dummy crate for the code snippet, for example).
133 /// this one should be used when working with crate hierarchies. 168 ///
134 pub declaration_name: Option<CrateName>, 169 /// For purposes of analysis, crates are anonymous (only names in
170 /// `Dependency` matters), this name should only be used for UI.
171 pub display_name: Option<CrateDisplayName>,
135 pub cfg_options: CfgOptions, 172 pub cfg_options: CfgOptions,
136 pub env: Env, 173 pub env: Env,
137 pub dependencies: Vec<Dependency>, 174 pub dependencies: Vec<Dependency>,
@@ -160,7 +197,7 @@ impl CrateGraph {
160 &mut self, 197 &mut self,
161 file_id: FileId, 198 file_id: FileId,
162 edition: Edition, 199 edition: Edition,
163 declaration_name: Option<CrateName>, 200 display_name: Option<CrateDisplayName>,
164 cfg_options: CfgOptions, 201 cfg_options: CfgOptions,
165 env: Env, 202 env: Env,
166 proc_macro: Vec<(SmolStr, Arc<dyn tt::TokenExpander>)>, 203 proc_macro: Vec<(SmolStr, Arc<dyn tt::TokenExpander>)>,
@@ -171,7 +208,7 @@ impl CrateGraph {
171 let data = CrateData { 208 let data = CrateData {
172 root_file_id: file_id, 209 root_file_id: file_id,
173 edition, 210 edition,
174 declaration_name, 211 display_name,
175 cfg_options, 212 cfg_options,
176 env, 213 env,
177 proc_macro, 214 proc_macro,
@@ -310,8 +347,8 @@ impl CrateGraph {
310 } 347 }
311 } 348 }
312 349
313 fn hacky_find_crate(&self, declaration_name: &str) -> Option<CrateId> { 350 fn hacky_find_crate(&self, display_name: &str) -> Option<CrateId> {
314 self.iter().find(|it| self[*it].declaration_name.as_deref() == Some(declaration_name)) 351 self.iter().find(|it| self[*it].display_name.as_deref() == Some(display_name))
315 } 352 }
316} 353}
317 354
diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs
index e38aa7257..0804202d6 100644
--- a/crates/base_db/src/lib.rs
+++ b/crates/base_db/src/lib.rs
@@ -13,8 +13,8 @@ pub use crate::{
13 cancellation::Canceled, 13 cancellation::Canceled,
14 change::Change, 14 change::Change,
15 input::{ 15 input::{
16 CrateData, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacroId, 16 CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env,
17 SourceRoot, SourceRootId, 17 FileId, ProcMacroId, SourceRoot, SourceRootId,
18 }, 18 },
19}; 19};
20pub use salsa; 20pub use salsa;
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index b65be4fe1..7f169ccd2 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -2,7 +2,7 @@
2use std::{iter, sync::Arc}; 2use std::{iter, sync::Arc};
3 3
4use arrayvec::ArrayVec; 4use arrayvec::ArrayVec;
5use base_db::{CrateId, CrateName, Edition, FileId}; 5use base_db::{CrateDisplayName, CrateId, Edition, FileId};
6use either::Either; 6use either::Either;
7use hir_def::find_path::PrefixKind; 7use hir_def::find_path::PrefixKind;
8use hir_def::{ 8use hir_def::{
@@ -103,8 +103,8 @@ impl Crate {
103 db.crate_graph()[self.id].edition 103 db.crate_graph()[self.id].edition
104 } 104 }
105 105
106 pub fn declaration_name(self, db: &dyn HirDatabase) -> Option<CrateName> { 106 pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateDisplayName> {
107 db.crate_graph()[self.id].declaration_name.clone() 107 db.crate_graph()[self.id].display_name.clone()
108 } 108 }
109 109
110 pub fn query_external_importables( 110 pub fn query_external_importables(
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index 028cae2e7..1e24f29a8 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -356,7 +356,7 @@ mod tests {
356 let krate = crate_graph 356 let krate = crate_graph
357 .iter() 357 .iter()
358 .find(|krate| { 358 .find(|krate| {
359 crate_graph[*krate].declaration_name.as_ref().map(|n| n.to_string()) 359 crate_graph[*krate].display_name.as_ref().map(|n| n.to_string())
360 == Some(crate_name.to_string()) 360 == Some(crate_name.to_string())
361 }) 361 })
362 .unwrap(); 362 .unwrap();
@@ -375,7 +375,7 @@ mod tests {
375 let path = map.path_of(item).unwrap(); 375 let path = map.path_of(item).unwrap();
376 format!( 376 format!(
377 "{}::{} ({})\n", 377 "{}::{} ({})\n",
378 crate_graph[krate].declaration_name.as_ref().unwrap(), 378 crate_graph[krate].display_name.as_ref().unwrap(),
379 path, 379 path,
380 mark 380 mark
381 ) 381 )
@@ -416,7 +416,7 @@ mod tests {
416 .iter() 416 .iter()
417 .filter_map(|krate| { 417 .filter_map(|krate| {
418 let cdata = &crate_graph[krate]; 418 let cdata = &crate_graph[krate];
419 let name = cdata.declaration_name.as_ref()?; 419 let name = cdata.display_name.as_ref()?;
420 420
421 let map = db.import_map(krate); 421 let map = db.import_map(krate);
422 422
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 464ffef21..3d04f81c6 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -172,11 +172,7 @@ pub struct ModuleData {
172impl CrateDefMap { 172impl CrateDefMap {
173 pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { 173 pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<CrateDefMap> {
174 let _p = profile::span("crate_def_map_query").detail(|| { 174 let _p = profile::span("crate_def_map_query").detail(|| {
175 db.crate_graph()[krate] 175 db.crate_graph()[krate].display_name.as_deref().unwrap_or_default().to_string()
176 .declaration_name
177 .as_ref()
178 .map(ToString::to_string)
179 .unwrap_or_default()
180 }); 176 });
181 let def_map = { 177 let def_map = {
182 let edition = db.crate_graph()[krate].edition; 178 let edition = db.crate_graph()[krate].edition;
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index d9dc63b33..b9d8b8a2b 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -130,7 +130,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
130 let module = definition.module(db)?; 130 let module = definition.module(db)?;
131 let krate = module.krate(); 131 let krate = module.krate();
132 let import_map = db.import_map(krate.into()); 132 let import_map = db.import_map(krate.into());
133 let base = once(krate.declaration_name(db)?.to_string()) 133 let base = once(krate.display_name(db)?.to_string())
134 .chain(import_map.path_of(ns)?.segments.iter().map(|name| name.to_string())) 134 .chain(import_map.path_of(ns)?.segments.iter().map(|name| name.to_string()))
135 .join("/"); 135 .join("/");
136 136
@@ -188,7 +188,7 @@ fn rewrite_intra_doc_link(
188 let krate = resolved.module(db)?.krate(); 188 let krate = resolved.module(db)?.krate();
189 let canonical_path = resolved.canonical_path(db)?; 189 let canonical_path = resolved.canonical_path(db)?;
190 let new_target = get_doc_url(db, &krate)? 190 let new_target = get_doc_url(db, &krate)?
191 .join(&format!("{}/", krate.declaration_name(db)?)) 191 .join(&format!("{}/", krate.display_name(db)?))
192 .ok()? 192 .ok()?
193 .join(&canonical_path.replace("::", "/")) 193 .join(&canonical_path.replace("::", "/"))
194 .ok()? 194 .ok()?
@@ -208,7 +208,7 @@ fn rewrite_url_link(db: &RootDatabase, def: ModuleDef, target: &str) -> Option<S
208 let module = def.module(db)?; 208 let module = def.module(db)?;
209 let krate = module.krate(); 209 let krate = module.krate();
210 let canonical_path = def.canonical_path(db)?; 210 let canonical_path = def.canonical_path(db)?;
211 let base = format!("{}/{}", krate.declaration_name(db)?, canonical_path.replace("::", "/")); 211 let base = format!("{}/{}", krate.display_name(db)?, canonical_path.replace("::", "/"));
212 212
213 get_doc_url(db, &krate) 213 get_doc_url(db, &krate)
214 .and_then(|url| url.join(&base).ok()) 214 .and_then(|url| url.join(&base).ok())
@@ -357,7 +357,7 @@ fn get_doc_url(db: &RootDatabase, krate: &Crate) -> Option<Url> {
357 // 357 //
358 // FIXME: clicking on the link should just open the file in the editor, 358 // FIXME: clicking on the link should just open the file in the editor,
359 // instead of falling back to external urls. 359 // instead of falling back to external urls.
360 Some(format!("https://docs.rs/{}/*/", krate.declaration_name(db)?)) 360 Some(format!("https://docs.rs/{}/*/", krate.display_name(db)?))
361 }) 361 })
362 .and_then(|s| Url::parse(&s).ok()) 362 .and_then(|s| Url::parse(&s).ok())
363} 363}
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 845333e2a..6466422c5 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -300,7 +300,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
300 300
301fn render_path(db: &RootDatabase, module: Module, item_name: Option<String>) -> String { 301fn render_path(db: &RootDatabase, module: Module, item_name: Option<String>) -> String {
302 let crate_name = 302 let crate_name =
303 db.crate_graph()[module.krate().into()].declaration_name.as_ref().map(ToString::to_string); 303 db.crate_graph()[module.krate().into()].display_name.as_ref().map(|it| it.to_string());
304 let module_path = module 304 let module_path = module
305 .path_to_root(db) 305 .path_to_root(db)
306 .into_iter() 306 .into_iter()
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index e2079bbcf..56b985e80 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1,15 +1,14 @@
1use assists::utils::FamousDefs; 1use assists::utils::FamousDefs;
2use either::Either;
2use hir::{known, HirDisplay, Semantics}; 3use hir::{known, HirDisplay, Semantics};
3use ide_db::RootDatabase; 4use ide_db::RootDatabase;
4use stdx::to_lower_snake_case; 5use stdx::to_lower_snake_case;
5use syntax::{ 6use syntax::{
6 ast::{self, ArgListOwner, AstNode}, 7 ast::{self, ArgListOwner, AstNode, NameOwner},
7 match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, TextRange, T, 8 match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, TextRange, T,
8}; 9};
9 10
10use crate::FileId; 11use crate::FileId;
11use ast::NameOwner;
12use either::Either;
13 12
14#[derive(Clone, Debug, PartialEq, Eq)] 13#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct InlayHintsConfig { 14pub struct InlayHintsConfig {
@@ -215,7 +214,7 @@ fn hint_iterator(
215 .last() 214 .last()
216 .and_then(|strukt| strukt.as_adt())?; 215 .and_then(|strukt| strukt.as_adt())?;
217 let krate = strukt.krate(db)?; 216 let krate = strukt.krate(db)?;
218 if krate.declaration_name(db).as_deref() != Some("core") { 217 if krate.display_name(db).as_deref() != Some("core") {
219 return None; 218 return None;
220 } 219 }
221 let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; 220 let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?;
diff --git a/crates/ide/src/prime_caches.rs b/crates/ide/src/prime_caches.rs
index 9687c2734..6944dbcd2 100644
--- a/crates/ide/src/prime_caches.rs
+++ b/crates/ide/src/prime_caches.rs
@@ -32,8 +32,7 @@ pub(crate) fn prime_caches(db: &RootDatabase, cb: &(dyn Fn(PrimeCachesProgress)
32 // Unfortunately rayon prevents panics from propagation out of a `scope`, which breaks 32 // Unfortunately rayon prevents panics from propagation out of a `scope`, which breaks
33 // cancellation, so we cannot use rayon. 33 // cancellation, so we cannot use rayon.
34 for (i, krate) in topo.iter().enumerate() { 34 for (i, krate) in topo.iter().enumerate() {
35 let crate_name = 35 let crate_name = graph[*krate].display_name.as_deref().unwrap_or_default().to_string();
36 graph[*krate].declaration_name.as_ref().map(ToString::to_string).unwrap_or_default();
37 36
38 cb(PrimeCachesProgress::StartedOnCrate { 37 cb(PrimeCachesProgress::StartedOnCrate {
39 on_crate: crate_name, 38 on_crate: crate_name,
diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs
index f67f10491..0af84daa0 100644
--- a/crates/ide/src/status.rs
+++ b/crates/ide/src/status.rs
@@ -45,7 +45,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
45 match krate { 45 match krate {
46 Some(krate) => { 46 Some(krate) => {
47 let crate_graph = db.crate_graph(); 47 let crate_graph = db.crate_graph();
48 let display_crate = |krate: CrateId| match &crate_graph[krate].declaration_name { 48 let display_crate = |krate: CrateId| match &crate_graph[krate].display_name {
49 Some(it) => format!("{}({:?})", it, krate), 49 Some(it) => format!("{}({:?})", it, krate),
50 None => format!("{:?}", krate), 50 None => format!("{:?}", krate),
51 }; 51 };
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs
index ea95d1c77..5db41bc16 100644
--- a/crates/project_model/src/lib.rs
+++ b/crates/project_model/src/lib.rs
@@ -13,7 +13,7 @@ use std::{
13}; 13};
14 14
15use anyhow::{bail, Context, Result}; 15use anyhow::{bail, Context, Result};
16use base_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; 16use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId};
17use cfg::CfgOptions; 17use cfg::CfgOptions;
18use paths::{AbsPath, AbsPathBuf}; 18use paths::{AbsPath, AbsPathBuf};
19use rustc_hash::{FxHashMap, FxHashSet}; 19use rustc_hash::{FxHashMap, FxHashSet};
@@ -408,10 +408,12 @@ impl ProjectWorkspace {
408 .map(|it| proc_macro_client.by_dylib_path(&it)) 408 .map(|it| proc_macro_client.by_dylib_path(&it))
409 .unwrap_or_default(); 409 .unwrap_or_default();
410 410
411 let display_name =
412 CrateDisplayName::from_canonical_name(cargo[pkg].name.clone());
411 let crate_id = crate_graph.add_crate_root( 413 let crate_id = crate_graph.add_crate_root(
412 file_id, 414 file_id,
413 edition, 415 edition,
414 Some(CrateName::normalize_dashes(&cargo[pkg].name)), 416 Some(display_name),
415 cfg_options, 417 cfg_options,
416 env, 418 env,
417 proc_macro.clone(), 419 proc_macro.clone(),
@@ -556,7 +558,7 @@ fn sysroot_to_crate_graph(
556 let crate_id = crate_graph.add_crate_root( 558 let crate_id = crate_graph.add_crate_root(
557 file_id, 559 file_id,
558 Edition::Edition2018, 560 Edition::Edition2018,
559 Some(name), 561 Some(name.into()),
560 cfg_options.clone(), 562 cfg_options.clone(),
561 env, 563 env,
562 proc_macro, 564 proc_macro,
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index d1d3b12f8..a89993a2b 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -36,12 +36,8 @@ pub fn diagnostics(path: &Path, load_output_dirs: bool, with_proc_macro: bool) -
36 for module in work { 36 for module in work {
37 let file_id = module.definition_source(db).file_id.original_file(db); 37 let file_id = module.definition_source(db).file_id.original_file(db);
38 if !visited_files.contains(&file_id) { 38 if !visited_files.contains(&file_id) {
39 let crate_name = module 39 let crate_name =
40 .krate() 40 module.krate().display_name(db).as_deref().unwrap_or("unknown").to_string();
41 .declaration_name(db)
42 .as_ref()
43 .map(ToString::to_string)
44 .unwrap_or_else(|| "unknown".to_string());
45 println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id)); 41 println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
46 for diagnostic in analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap() 42 for diagnostic in analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap()
47 { 43 {