Don't panic on crates depending on themselves

Fixes #3883.
This commit is contained in:
Florian Diebold 2020-06-19 18:02:54 +02:00
parent 90a5c4626a
commit 584bddef0c
2 changed files with 31 additions and 6 deletions

View file

@ -254,12 +254,12 @@ impl CrateGraph {
return false;
}
for dep in &self[from].dependencies {
let crate_id = dep.crate_id;
if crate_id == target {
if target == from {
return true;
}
for dep in &self[from].dependencies {
let crate_id = dep.crate_id;
if self.dfs_find(target, crate_id, visited) {
return true;
}
@ -369,7 +369,7 @@ mod tests {
use super::{CfgOptions, CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId};
#[test]
fn it_should_panic_because_of_cycle_dependencies() {
fn detect_cyclic_dependency_indirect() {
let mut graph = CrateGraph::default();
let crate1 = graph.add_crate_root(
FileId(1u32),
@ -403,6 +403,31 @@ mod tests {
assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err());
}
#[test]
fn detect_cyclic_dependency_direct() {
let mut graph = CrateGraph::default();
let crate1 = graph.add_crate_root(
FileId(1u32),
Edition2018,
None,
CfgOptions::default(),
Env::default(),
Default::default(),
Default::default(),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
Edition2018,
None,
CfgOptions::default(),
Env::default(),
Default::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());
}
#[test]
fn it_works() {
let mut graph = CrateGraph::default();

View file

@ -36,8 +36,8 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
// populate external prelude
for dep in &crate_graph[def_map.krate].dependencies {
let dep_def_map = db.crate_def_map(dep.crate_id);
log::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(),
ModuleId { krate: dep.crate_id, local_id: dep_def_map.root }.into(),