Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Make extern crate test; work #10385

Merged
merged 2 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions crates/base_db/src/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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();
}
}

Expand All @@ -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();
}
}

Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -301,6 +312,7 @@ struct FileMeta {
path: String,
krate: Option<String>,
deps: Vec<String>,
extern_prelude: Vec<String>,
cfg: CfgOptions,
edition: Edition,
env: Env,
Expand All @@ -313,10 +325,12 @@ impl From<Fixture> 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(),
Expand Down
69 changes: 49 additions & 20 deletions crates/base_db/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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(())
}

Expand Down Expand Up @@ -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,
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand All @@ -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)]
);
}
}
56 changes: 40 additions & 16 deletions crates/hir_def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand All @@ -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(),
Expand Down Expand Up @@ -239,6 +243,7 @@ struct DefData<'a> {
struct DefCollector<'a> {
db: &'a dyn DefDatabase,
def_map: DefMap,
deps: FxHashMap<Name, ModuleDefId>,
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
unresolved_imports: Vec<ImportDirective>,
resolved_imports: Vec<ImportDirective>,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
Expand Down
6 changes: 0 additions & 6 deletions crates/hir_def/src/nameres/path_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
//! `ReachedFixedPoint` signals about this.

use base_db::Edition;
use hir_expand::name;
use hir_expand::name::Name;

use crate::{
Expand Down Expand Up @@ -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(_) => {
Expand Down
30 changes: 30 additions & 0 deletions crates/hir_def/src/nameres/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
"#]],
);
}
5 changes: 2 additions & 3 deletions crates/project_model/src/project_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>(),
cfg: crate_data.cfg,
Expand Down
Loading