From 0b76b29512d21636c28edbd44b55f0da8477f76c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 28 Sep 2021 21:23:46 +0200 Subject: [PATCH] support non-extern-prelude dependencies --- crates/base_db/src/fixture.rs | 30 +++++--- crates/base_db/src/input.rs | 69 +++++++++++++------ crates/hir_def/src/nameres/collector.rs | 56 ++++++++++----- crates/hir_def/src/nameres/path_resolution.rs | 6 -- crates/hir_def/src/nameres/tests.rs | 30 ++++++++ crates/project_model/src/project_json.rs | 5 +- crates/project_model/src/tests.rs | 38 ++++++++++ crates/project_model/src/workspace.rs | 6 +- crates/test_utils/src/fixture.rs | 20 ++++++ 9 files changed, 205 insertions(+), 55 deletions(-) diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index cc1de54dfb3..017684fc830 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs @@ -10,8 +10,8 @@ use tt::Subtree; use vfs::{file_set::FileSet, VfsPath}; use crate::{ - input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Edition, Env, FileId, - FilePosition, FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, + input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env, + FileId, FilePosition, FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, SourceDatabaseExt, SourceRoot, SourceRootId, }; @@ -144,8 +144,9 @@ impl ChangeFixture { let prev = crates.insert(crate_name.clone(), crate_id); assert!(prev.is_none()); for dep in meta.deps { + let prelude = meta.extern_prelude.contains(&dep); let dep = CrateName::normalize_dashes(&dep); - crate_deps.push((crate_name.clone(), dep)) + crate_deps.push((crate_name.clone(), dep, prelude)) } } else if meta.path == "/main.rs" || meta.path == "/lib.rs" { assert!(default_crate_root.is_none()); @@ -173,10 +174,15 @@ impl ChangeFixture { Default::default(), ); } else { - for (from, to) in crate_deps { + for (from, to, prelude) in crate_deps { let from_id = crates[&from]; let to_id = crates[&to]; - crate_graph.add_dep(from_id, CrateName::new(&to).unwrap(), to_id).unwrap(); + crate_graph + .add_dep( + from_id, + Dependency::with_prelude(CrateName::new(&to).unwrap(), to_id, prelude), + ) + .unwrap(); } } @@ -203,7 +209,9 @@ impl ChangeFixture { ); for krate in all_crates { - crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap(); + crate_graph + .add_dep(krate, Dependency::new(CrateName::new("core").unwrap(), core_crate)) + .unwrap(); } } @@ -235,7 +243,10 @@ impl ChangeFixture { for krate in all_crates { crate_graph - .add_dep(krate, CrateName::new("proc_macros").unwrap(), proc_macros_crate) + .add_dep( + krate, + Dependency::new(CrateName::new("proc_macros").unwrap(), proc_macros_crate), + ) .unwrap(); } } @@ -301,6 +312,7 @@ struct FileMeta { path: String, krate: Option, deps: Vec, + extern_prelude: Vec, cfg: CfgOptions, edition: Edition, env: Env, @@ -313,10 +325,12 @@ impl From for FileMeta { f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into())); f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into())); + let deps = f.deps; FileMeta { path: f.path, krate: f.krate, - deps: f.deps, + extern_prelude: f.extern_prelude.unwrap_or_else(|| deps.clone()), + deps, cfg, edition: f.edition.as_ref().map_or(Edition::CURRENT, |v| Edition::from_str(v).unwrap()), env: f.env.into_iter().collect(), diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index 565d0c02cfe..1dd7783b0ec 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs @@ -217,6 +217,22 @@ pub struct Env { pub struct Dependency { pub crate_id: CrateId, pub name: CrateName, + prelude: bool, +} + +impl Dependency { + pub fn new(name: CrateName, crate_id: CrateId) -> Self { + Self { name, crate_id, prelude: true } + } + + pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool) -> Self { + Self { name, crate_id, prelude } + } + + /// Whether this dependency is to be added to the depending crate's extern prelude. + pub fn is_prelude(&self) -> bool { + self.prelude + } } impl CrateGraph { @@ -249,22 +265,21 @@ impl CrateGraph { pub fn add_dep( &mut self, from: CrateId, - name: CrateName, - to: CrateId, + dep: Dependency, ) -> Result<(), CyclicDependenciesError> { let _p = profile::span("add_dep"); // Check if adding a dep from `from` to `to` creates a cycle. To figure // that out, look for a path in the *opposite* direction, from `to` to // `from`. - if let Some(path) = self.find_path(&mut FxHashSet::default(), to, from) { + if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) { let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect(); let err = CyclicDependenciesError { path }; - assert!(err.from().0 == from && err.to().0 == to); + assert!(err.from().0 == from && err.to().0 == dep.crate_id); return Err(err); } - self.arena.get_mut(&from).unwrap().add_dep(name, to); + self.arena.get_mut(&from).unwrap().add_dep(dep); Ok(()) } @@ -409,7 +424,7 @@ impl CrateGraph { .get_mut(&std) .unwrap() .dependencies - .push(Dependency { crate_id: cfg_if, name: CrateName::new("cfg_if").unwrap() }); + .push(Dependency::new(CrateName::new("cfg_if").unwrap(), cfg_if)); true } _ => false, @@ -435,8 +450,8 @@ impl CrateId { } impl CrateData { - fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { - self.dependencies.push(Dependency { crate_id, name }) + fn add_dep(&mut self, dep: Dependency) { + self.dependencies.push(dep) } } @@ -562,9 +577,15 @@ mod tests { Env::default(), Default::default(), ); - assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); - assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); - assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); + assert!(graph + .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2)) + .is_ok()); + assert!(graph + .add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3)) + .is_ok()); + assert!(graph + .add_dep(crate3, Dependency::new(CrateName::new("crate1").unwrap(), crate1)) + .is_err()); } #[test] @@ -588,8 +609,12 @@ mod tests { Env::default(), Default::default(), ); - assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); - assert!(graph.add_dep(crate2, CrateName::new("crate2").unwrap(), crate2).is_err()); + assert!(graph + .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2)) + .is_ok()); + assert!(graph + .add_dep(crate2, Dependency::new(CrateName::new("crate2").unwrap(), crate2)) + .is_err()); } #[test] @@ -622,8 +647,12 @@ mod tests { Env::default(), Default::default(), ); - assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); - assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); + assert!(graph + .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2)) + .is_ok()); + assert!(graph + .add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3)) + .is_ok()); } #[test] @@ -648,14 +677,14 @@ mod tests { Default::default(), ); assert!(graph - .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) + .add_dep( + crate1, + Dependency::new(CrateName::normalize_dashes("crate-name-with-dashes"), crate2) + ) .is_ok()); assert_eq!( graph[crate1].dependencies, - vec![Dependency { - crate_id: crate2, - name: CrateName::new("crate_name_with_dashes").unwrap() - }] + vec![Dependency::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2)] ); } } diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index d6762d1acf0..53ab87005ca 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -61,14 +61,17 @@ pub(super) fn collect_defs( ) -> DefMap { let crate_graph = db.crate_graph(); - if block.is_none() { - // populate external prelude - for dep in &crate_graph[def_map.krate].dependencies { - tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); - let dep_def_map = db.crate_def_map(dep.crate_id); - def_map - .extern_prelude - .insert(dep.as_name(), dep_def_map.module_id(dep_def_map.root).into()); + let mut deps = FxHashMap::default(); + // populate external prelude and dependency list + for dep in &crate_graph[def_map.krate].dependencies { + tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); + let dep_def_map = db.crate_def_map(dep.crate_id); + let dep_root = dep_def_map.module_id(dep_def_map.root); + + deps.insert(dep.as_name(), dep_root.into()); + + if dep.is_prelude() && block.is_none() { + def_map.extern_prelude.insert(dep.as_name(), dep_root.into()); } } @@ -87,6 +90,7 @@ pub(super) fn collect_defs( let mut collector = DefCollector { db, def_map, + deps, glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), resolved_imports: Vec::new(), @@ -239,6 +243,7 @@ struct DefData<'a> { struct DefCollector<'a> { db: &'a dyn DefDatabase, def_map: DefMap, + deps: FxHashMap, glob_imports: FxHashMap>, unresolved_imports: Vec, resolved_imports: Vec, @@ -660,7 +665,7 @@ impl DefCollector<'_> { self.def_map.edition, ); - let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name); + let res = self.resolve_extern_crate(&extern_crate.name); if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { if m == self.def_map.module_id(current_module_id) { @@ -720,13 +725,13 @@ impl DefCollector<'_> { fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); if import.is_extern_crate { - let res = self.def_map.resolve_name_in_extern_prelude( - self.db, - import - .path - .as_ident() - .expect("extern crate should have been desugared to one-element path"), - ); + let name = import + .path + .as_ident() + .expect("extern crate should have been desugared to one-element path"); + + let res = self.resolve_extern_crate(name); + if res.is_none() { PartialResolvedImport::Unresolved } else { @@ -766,6 +771,24 @@ impl DefCollector<'_> { } } + fn resolve_extern_crate(&self, name: &Name) -> PerNs { + let arc; + let root = match self.def_map.block { + Some(_) => { + arc = self.def_map.crate_root(self.db).def_map(self.db); + &*arc + } + None => &self.def_map, + }; + + if name == &name!(self) { + cov_mark::hit!(extern_crate_self_as); + PerNs::types(root.module_id(root.root()).into(), Visibility::Public) + } else { + self.deps.get(name).map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) + } + } + fn record_resolved_import(&mut self, directive: &ImportDirective) { let module_id = directive.module_id; let import = &directive.import; @@ -2009,6 +2032,7 @@ mod tests { let mut collector = DefCollector { db, def_map, + deps: FxHashMap::default(), glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), resolved_imports: Vec::new(), diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index e71805bc8ea..4fb81bde461 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs @@ -11,7 +11,6 @@ //! `ReachedFixedPoint` signals about this. use base_db::Edition; -use hir_expand::name; use hir_expand::name::Name; use crate::{ @@ -65,11 +64,6 @@ impl DefMap { db: &dyn DefDatabase, name: &Name, ) -> PerNs { - if name == &name!(self) { - cov_mark::hit!(extern_crate_self_as); - return PerNs::types(self.module_id(self.root).into(), Visibility::Public); - } - let arc; let root = match self.block { Some(_) => { diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs index ff34b4a9f27..37336ce1e95 100644 --- a/crates/hir_def/src/nameres/tests.rs +++ b/crates/hir_def/src/nameres/tests.rs @@ -860,3 +860,33 @@ pub const settings: () = (); "#]], ) } + +#[test] +fn non_prelude_deps() { + check( + r#" +//- /lib.rs crate:lib deps:dep extern-prelude: +use dep::Struct; +//- /dep.rs crate:dep +pub struct Struct; + "#, + expect![[r#" + crate + Struct: _ + "#]], + ); + check( + r#" +//- /lib.rs crate:lib deps:dep extern-prelude: +extern crate dep; +use dep::Struct; +//- /dep.rs crate:dep +pub struct Struct; + "#, + expect![[r#" + crate + Struct: t v + dep: t + "#]], + ); +} diff --git a/crates/project_model/src/project_json.rs b/crates/project_model/src/project_json.rs index 5db1aa1b4f3..75ad66a5cc4 100644 --- a/crates/project_model/src/project_json.rs +++ b/crates/project_model/src/project_json.rs @@ -83,9 +83,8 @@ impl ProjectJson { deps: crate_data .deps .into_iter() - .map(|dep_data| Dependency { - crate_id: CrateId(dep_data.krate as u32), - name: dep_data.name, + .map(|dep_data| { + Dependency::new(dep_data.name, CrateId(dep_data.krate as u32)) }) .collect::>(), cfg: crate_data.cfg, diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs index 0e37624f314..452ba18fe75 100644 --- a/crates/project_model/src/tests.rs +++ b/crates/project_model/src/tests.rs @@ -166,6 +166,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -231,6 +232,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -287,6 +289,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -295,6 +298,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -407,6 +411,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -415,6 +420,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -527,6 +533,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -535,6 +542,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -615,6 +623,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -680,6 +689,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -738,6 +748,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -746,6 +757,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -860,6 +872,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -868,6 +881,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -982,6 +996,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -990,6 +1005,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -1061,6 +1077,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -1128,6 +1145,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -1186,6 +1204,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1194,6 +1213,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -1310,6 +1330,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1318,6 +1339,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -1434,6 +1456,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "hello_world", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1442,6 +1465,7 @@ fn cargo_hello_world_project_model() { name: CrateName( "libc", ), + prelude: true, }, ], proc_macro: [], @@ -1491,6 +1515,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "core", ), + prelude: true, }, ], proc_macro: [], @@ -1581,6 +1606,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "std", ), + prelude: true, }, ], proc_macro: [], @@ -1644,6 +1670,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "core", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1652,6 +1679,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "alloc", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1660,6 +1688,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "std", ), + prelude: true, }, ], proc_macro: [], @@ -1804,6 +1833,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "alloc", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1812,6 +1842,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "core", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1820,6 +1851,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "panic_abort", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1828,6 +1860,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "panic_unwind", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1836,6 +1869,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "profiler_builtins", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1844,6 +1878,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "std_detect", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1852,6 +1887,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "term", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1860,6 +1896,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "test", ), + prelude: true, }, Dependency { crate_id: CrateId( @@ -1868,6 +1905,7 @@ fn rust_project_hello_world_project_model() { name: CrateName( "unwind", ), + prelude: true, }, ], proc_macro: [], diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 282116c297d..225c7f90252 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -5,7 +5,9 @@ use std::{collections::VecDeque, convert::TryFrom, fmt, fs, process::Command}; use anyhow::{format_err, Context, Result}; -use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; +use base_db::{ + CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacro, +}; use cfg::{CfgDiff, CfgOptions}; use paths::{AbsPath, AbsPathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -875,7 +877,7 @@ fn sysroot_to_crate_graph( } fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) { - if let Err(err) = graph.add_dep(from, name, to) { + if let Err(err) = graph.add_dep(from, Dependency::new(name, to)) { tracing::error!("{}", err) } } diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs index 71cc67a9ca3..f2013b34c5a 100644 --- a/crates/test_utils/src/fixture.rs +++ b/crates/test_utils/src/fixture.rs @@ -70,6 +70,7 @@ pub struct Fixture { pub text: String, pub krate: Option, pub deps: Vec, + pub extern_prelude: Option>, pub cfg_atoms: Vec, pub cfg_key_values: Vec<(String, String)>, pub edition: Option, @@ -171,6 +172,7 @@ impl Fixture { let mut krate = None; let mut deps = Vec::new(); + let mut extern_prelude = None; let mut edition = None; let mut cfg_atoms = Vec::new(); let mut cfg_key_values = Vec::new(); @@ -183,6 +185,14 @@ impl Fixture { match key { "crate" => krate = Some(value.to_string()), "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), + "extern-prelude" => { + if value.is_empty() { + extern_prelude = Some(Vec::new()); + } else { + extern_prelude = + Some(value.split(',').map(|it| it.to_string()).collect::>()); + } + } "edition" => edition = Some(value.to_string()), "cfg" => { for entry in value.split(',') { @@ -204,11 +214,21 @@ impl Fixture { } } + for prelude_dep in extern_prelude.iter().flatten() { + assert!( + deps.contains(prelude_dep), + "extern-prelude {:?} must be a subset of deps {:?}", + extern_prelude, + deps + ); + } + Fixture { path, text: String::new(), krate, deps, + extern_prelude, cfg_atoms, cfg_key_values, edition,