Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes

This commit is contained in:
Seivan Heidari 2019-11-10 23:37:09 +01:00
commit 7cd075ff0b
5 changed files with 112 additions and 6 deletions

View file

@ -36,11 +36,12 @@ pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) ->
); );
// look for the prelude // look for the prelude
if def_map.prelude.is_none() { // If the dependency defines a prelude, we overwrite an already defined
let map = db.crate_def_map(dep.crate_id); // prelude. This is necessary to import the "std" prelude if a crate
if map.prelude.is_some() { // depends on both "core" and "std".
def_map.prelude = map.prelude; let dep_def_map = db.crate_def_map(dep.crate_id);
} if dep_def_map.prelude.is_some() {
def_map.prelude = dep_def_map.prelude;
} }
} }

View file

@ -463,6 +463,37 @@ fn values_dont_shadow_extern_crates() {
"###); "###);
} }
#[test]
fn std_prelude_takes_precedence_above_core_prelude() {
let map = def_map(
r#"
//- /main.rs crate:main deps:core,std
use {Foo, Bar};
//- /std.rs crate:std deps:core
#[prelude_import]
pub use self::prelude::*;
mod prelude {
pub struct Foo;
pub use core::prelude::Bar;
}
//- /core.rs crate:core
#[prelude_import]
pub use self::prelude::*;
mod prelude {
pub struct Bar;
}
"#,
);
assert_snapshot!(map, @r###"
crate
Bar: t v
Foo: t v
"###);
}
#[test] #[test]
fn cfg_not_test() { fn cfg_not_test() {
let map = def_map( let map = def_map(

View file

@ -597,6 +597,68 @@ mod tests {
); );
} }
#[test]
fn completes_std_prelude_if_core_is_defined() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
fn foo() { let x: <|> }
//- /core/lib.rs
#[prelude_import]
use prelude::*;
mod prelude {
struct Option;
}
//- /std/lib.rs
#[prelude_import]
use prelude::*;
mod prelude {
struct String;
}
"
),
@r###"
[
CompletionItem {
label: "String",
source_range: [18; 18),
delete: [18; 18),
insert: "String",
kind: Struct,
},
CompletionItem {
label: "core",
source_range: [18; 18),
delete: [18; 18),
insert: "core",
kind: Module,
},
CompletionItem {
label: "foo()",
source_range: [18; 18),
delete: [18; 18),
insert: "foo()$0",
kind: Function,
lookup: "foo",
detail: "fn foo()",
},
CompletionItem {
label: "std",
source_range: [18; 18),
delete: [18; 18),
insert: "std",
kind: Module,
},
]
"###
);
}
#[test] #[test]
fn completes_macros_as_value() { fn completes_macros_as_value() {
assert_debug_snapshot!( assert_debug_snapshot!(

View file

@ -199,6 +199,7 @@ impl ProjectWorkspace {
} }
} }
let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied());
let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied());
let mut pkg_to_lib_crate = FxHashMap::default(); let mut pkg_to_lib_crate = FxHashMap::default();
@ -226,7 +227,7 @@ impl ProjectWorkspace {
} }
} }
// Set deps to the std and to the lib target of the current package // Set deps to the core, std and to the lib target of the current package
for &from in pkg_crates.get(&pkg).into_iter().flatten() { for &from in pkg_crates.get(&pkg).into_iter().flatten() {
if let Some(to) = lib_tgt { if let Some(to) = lib_tgt {
if to != from { if to != from {
@ -240,6 +241,13 @@ impl ProjectWorkspace {
} }
} }
} }
// core is added as a dependency before std in order to
// mimic rustcs dependency order
if let Some(core) = libcore {
if let Err(_) = crate_graph.add_dep(from, "core".into(), core) {
log::error!("cyclic dependency on core for {}", pkg.name(&cargo))
}
}
if let Some(std) = libstd { if let Some(std) = libstd {
if let Err(_) = crate_graph.add_dep(from, "std".into(), std) { if let Err(_) = crate_graph.add_dep(from, "std".into(), std) {
log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) log::error!("cyclic dependency on std for {}", pkg.name(&cargo))

View file

@ -27,6 +27,10 @@ struct SysrootCrateData {
} }
impl Sysroot { impl Sysroot {
pub fn core(&self) -> Option<SysrootCrate> {
self.by_name("core")
}
pub fn std(&self) -> Option<SysrootCrate> { pub fn std(&self) -> Option<SysrootCrate> {
self.by_name("std") self.by_name("std")
} }