5422: Rewrite def map tests from insta to expect r=matklad a=matklad

Those indentation markers are annoying...



bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot]
2020-07-17 12:38:52 +00:00
committed by GitHub
7 changed files with 1799 additions and 1919 deletions
+387 -415
View File
@@ -6,558 +6,531 @@
use std::sync::Arc;
use insta::assert_snapshot;
use expect::{expect, Expect};
use ra_db::{fixture::WithFixture, SourceDatabase};
use test_utils::mark;
use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
fn def_map(ra_fixture: &str) -> String {
compute_crate_def_map(ra_fixture).dump()
}
fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
let db = TestDB::with_files(fixture);
let krate = db.crate_graph().iter().next().unwrap();
db.crate_def_map(krate)
}
fn check(ra_fixture: &str, expect: Expect) {
let db = TestDB::with_files(ra_fixture);
let krate = db.crate_graph().iter().next().unwrap();
let actual = db.crate_def_map(krate).dump() + "\n";
expect.assert_eq(&actual);
}
#[test]
fn crate_def_map_smoke_test() {
let map = def_map(
r"
//- /lib.rs
mod foo;
struct S;
use crate::foo::bar::E;
use self::E::V;
check(
r#"
//- /lib.rs
mod foo;
struct S;
use crate::foo::bar::E;
use self::E::V;
//- /foo/mod.rs
pub mod bar;
fn f() {}
//- /foo/mod.rs
pub mod bar;
fn f() {}
//- /foo/bar.rs
pub struct Baz;
//- /foo/bar.rs
pub struct Baz;
union U {
to_be: bool,
not_to_be: u8,
}
union U { to_be: bool, not_to_be: u8 }
enum E { V }
enum E { V }
extern {
static EXT: u8;
fn ext();
}
"#,
expect![[r#"
crate
E: t
S: t v
V: t v
foo: t
extern {
static EXT: u8;
fn ext();
}
",
crate::foo
bar: t
f: v
crate::foo::bar
Baz: t v
E: t
EXT: v
U: t
ext: v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮E: t
⋮S: t v
⋮V: t v
⋮foo: t
⋮crate::foo
⋮bar: t
⋮f: v
⋮crate::foo::bar
⋮Baz: t v
⋮E: t
⋮EXT: v
⋮U: t
⋮ext: v
"###)
}
#[test]
fn crate_def_map_super_super() {
let map = def_map(
"
//- /lib.rs
mod a {
const A: usize = 0;
mod b {
const B: usize = 0;
mod c {
use super::super::*;
}
}
check(
r#"
mod a {
const A: usize = 0;
mod b {
const B: usize = 0;
mod c {
use super::super::*;
}
",
}
}
"#,
expect![[r#"
crate
a: t
crate::a
A: v
b: t
crate::a::b
B: v
c: t
crate::a::b::c
A: v
b: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮a: t
⋮crate::a
⋮A: v
⋮b: t
⋮crate::a::b
⋮B: v
⋮c: t
⋮crate::a::b::c
⋮A: v
⋮b: t
"###)
}
#[test]
fn crate_def_map_fn_mod_same_name() {
let map = def_map(
"
//- /lib.rs
mod m {
pub mod z {}
pub fn z() {}
}
",
check(
r#"
mod m {
pub mod z {}
pub fn z() {}
}
"#,
expect![[r#"
crate
m: t
crate::m
z: t v
crate::m::z
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮m: t
⋮crate::m
⋮z: t v
⋮crate::m::z
"###)
}
#[test]
fn bogus_paths() {
mark::check!(bogus_paths);
let map = def_map(
"
//- /lib.rs
mod foo;
struct S;
use self;
check(
r#"
//- /lib.rs
mod foo;
struct S;
use self;
//- /foo/mod.rs
use super;
use crate;
//- /foo/mod.rs
use super;
use crate;
"#,
expect![[r#"
crate
S: t v
foo: t
",
crate::foo
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮S: t v
⋮foo: t
⋮crate::foo
"###
)
}
#[test]
fn use_as() {
let map = def_map(
"
//- /lib.rs
mod foo;
check(
r#"
//- /lib.rs
mod foo;
use crate::foo::Baz as Foo;
use crate::foo::Baz as Foo;
//- /foo/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
Foo: t v
foo: t
//- /foo/mod.rs
pub struct Baz;
",
);
assert_snapshot!(map,
@r###"
⋮crate
⋮Foo: t v
⋮foo: t
⋮crate::foo
⋮Baz: t v
"###
crate::foo
Baz: t v
"#]],
);
}
#[test]
fn use_trees() {
let map = def_map(
"
//- /lib.rs
mod foo;
check(
r#"
//- /lib.rs
mod foo;
use crate::foo::bar::{Baz, Quux};
use crate::foo::bar::{Baz, Quux};
//- /foo/mod.rs
pub mod bar;
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
pub enum Quux {};
"#,
expect![[r#"
crate
Baz: t v
Quux: t
foo: t
//- /foo/bar.rs
pub struct Baz;
pub enum Quux {};
",
crate::foo
bar: t
crate::foo::bar
Baz: t v
Quux: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮Quux: t
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
⋮Quux: t
"###);
}
#[test]
fn re_exports() {
let map = def_map(
"
//- /lib.rs
mod foo;
check(
r#"
//- /lib.rs
mod foo;
use self::foo::Baz;
use self::foo::Baz;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::Baz;
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
foo: t
pub use self::bar::Baz;
crate::foo
Baz: t v
bar: t
//- /foo/bar.rs
pub struct Baz;
",
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn std_prelude() {
mark::check!(std_prelude);
let map = def_map(
"
//- /main.rs crate:main deps:test_crate
use Foo::*;
check(
r#"
//- /main.rs crate:main deps:test_crate
use Foo::*;
//- /lib.rs crate:test_crate
mod prelude;
#[prelude_import]
use prelude::*;
//- /lib.rs crate:test_crate
mod prelude;
#[prelude_import]
use prelude::*;
//- /prelude.rs
pub enum Foo { Bar, Baz };
",
//- /prelude.rs
pub enum Foo { Bar, Baz };
"#,
expect![[r#"
crate
Bar: t v
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Baz: t v
"###);
}
#[test]
fn can_import_enum_variant() {
mark::check!(can_import_enum_variant);
let map = def_map(
"
//- /lib.rs
enum E { V }
use self::E::V;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮E: t
⋮V: t v
"###
check(
r#"
enum E { V }
use self::E::V;
"#,
expect![[r#"
crate
E: t
V: t v
"#]],
);
}
#[test]
fn edition_2015_imports() {
let map = def_map(
"
//- /main.rs crate:main deps:other_crate edition:2015
mod foo;
mod bar;
check(
r#"
//- /main.rs crate:main deps:other_crate edition:2015
mod foo;
mod bar;
//- /bar.rs
struct Bar;
//- /bar.rs
struct Bar;
//- /foo.rs
use bar::Bar;
use other_crate::FromLib;
//- /foo.rs
use bar::Bar;
use other_crate::FromLib;
//- /lib.rs crate:other_crate edition:2018
struct FromLib;
",
//- /lib.rs crate:other_crate edition:2018
struct FromLib;
"#,
expect![[r#"
crate
bar: t
foo: t
crate::bar
Bar: t v
crate::foo
Bar: t v
FromLib: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮bar: t
⋮foo: t
⋮crate::bar
⋮Bar: t v
⋮crate::foo
⋮Bar: t v
⋮FromLib: t v
"###);
}
#[test]
fn item_map_using_self() {
let map = def_map(
"
//- /lib.rs
mod foo;
use crate::foo::bar::Baz::{self};
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
",
check(
r#"
//- /lib.rs
mod foo;
use crate::foo::bar::Baz::{self};
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn item_map_across_crates() {
let map = def_map(
"
//- /main.rs crate:main deps:test_crate
use test_crate::Baz;
check(
r#"
//- /main.rs crate:main deps:test_crate
use test_crate::Baz;
//- /lib.rs crate:test_crate
pub struct Baz;
",
//- /lib.rs crate:test_crate
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
"###);
}
#[test]
fn extern_crate_rename() {
let map = def_map(
"
//- /main.rs crate:main deps:alloc
extern crate alloc as alloc_crate;
check(
r#"
//- /main.rs crate:main deps:alloc
extern crate alloc as alloc_crate;
mod alloc;
mod sync;
mod alloc;
mod sync;
//- /sync.rs
use alloc_crate::Arc;
//- /sync.rs
use alloc_crate::Arc;
//- /lib.rs crate:alloc
struct Arc;
"#,
expect![[r#"
crate
alloc_crate: t
sync: t
//- /lib.rs crate:alloc
struct Arc;
",
crate::sync
Arc: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮alloc_crate: t
⋮sync: t
⋮crate::sync
⋮Arc: t v
"###);
}
#[test]
fn extern_crate_rename_2015_edition() {
let map = def_map(
"
//- /main.rs crate:main deps:alloc edition:2015
extern crate alloc as alloc_crate;
check(
r#"
//- /main.rs crate:main deps:alloc edition:2015
extern crate alloc as alloc_crate;
mod alloc;
mod sync;
mod alloc;
mod sync;
//- /sync.rs
use alloc_crate::Arc;
//- /sync.rs
use alloc_crate::Arc;
//- /lib.rs crate:alloc
struct Arc;
"#,
expect![[r#"
crate
alloc_crate: t
sync: t
//- /lib.rs crate:alloc
struct Arc;
",
);
assert_snapshot!(map,
@r###"
⋮crate
⋮alloc_crate: t
⋮sync: t
⋮crate::sync
⋮Arc: t v
"###
crate::sync
Arc: t v
"#]],
);
}
#[test]
fn reexport_across_crates() {
let map = def_map(
"
//- /main.rs crate:main deps:test_crate
use test_crate::Baz;
check(
r#"
//- /main.rs crate:main deps:test_crate
use test_crate::Baz;
//- /lib.rs crate:test_crate
pub use foo::Baz;
//- /lib.rs crate:test_crate
pub use foo::Baz;
mod foo;
mod foo;
//- /foo.rs
pub struct Baz;
",
//- /foo.rs
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
"###);
}
#[test]
fn values_dont_shadow_extern_crates() {
let map = def_map(
"
//- /main.rs crate:main deps:foo
fn foo() {}
use foo::Bar;
check(
r#"
//- /main.rs crate:main deps:foo
fn foo() {}
use foo::Bar;
//- /foo/lib.rs crate:foo
pub struct Bar;
",
//- /foo/lib.rs crate:foo
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
foo: v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮foo: v
"###);
}
#[test]
fn std_prelude_takes_precedence_above_core_prelude() {
let map = def_map(
check(
r#"
//- /main.rs crate:main deps:core,std
use {Foo, Bar};
//- /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;
}
//- /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;
}
"#,
//- /core.rs crate:core
#[prelude_import]
pub use self::prelude::*;
mod prelude {
pub struct Bar;
}
"#,
expect![[r#"
crate
Bar: t v
Foo: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Foo: t v
"###);
}
#[test]
fn cfg_not_test() {
let map = def_map(
check(
r#"
//- /main.rs crate:main deps:std
use {Foo, Bar, Baz};
//- /main.rs crate:main deps:std
use {Foo, Bar, Baz};
//- /lib.rs crate:std
#[prelude_import]
pub use self::prelude::*;
mod prelude {
#[cfg(test)]
pub struct Foo;
#[cfg(not(test))]
pub struct Bar;
#[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
pub struct Baz;
}
"#,
//- /lib.rs crate:std
#[prelude_import]
pub use self::prelude::*;
mod prelude {
#[cfg(test)]
pub struct Foo;
#[cfg(not(test))]
pub struct Bar;
#[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
pub struct Baz;
}
"#,
expect![[r#"
crate
Bar: t v
Baz: _
Foo: _
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Baz: _
⋮Foo: _
"###);
}
#[test]
fn cfg_test() {
let map = def_map(
check(
r#"
//- /main.rs crate:main deps:std
use {Foo, Bar, Baz};
//- /main.rs crate:main deps:std
use {Foo, Bar, Baz};
//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
#[prelude_import]
pub use self::prelude::*;
mod prelude {
#[cfg(test)]
pub struct Foo;
#[cfg(not(test))]
pub struct Bar;
#[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
pub struct Baz;
}
"#,
//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
#[prelude_import]
pub use self::prelude::*;
mod prelude {
#[cfg(test)]
pub struct Foo;
#[cfg(not(test))]
pub struct Bar;
#[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
pub struct Baz;
}
"#,
expect![[r#"
crate
Bar: _
Baz: t v
Foo: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: _
⋮Baz: t v
⋮Foo: t v
"###);
}
#[test]
fn infer_multiple_namespace() {
let map = def_map(
check(
r#"
//- /main.rs
mod a {
@@ -571,18 +544,17 @@ mod b {
pub const T: () = ();
}
"#,
);
expect![[r#"
crate
T: t v
a: t
b: t
assert_snapshot!(map, @r###"
⋮crate
⋮T: t v
⋮a: t
⋮b: t
⋮crate::b
⋮T: v
⋮crate::a
⋮T: t v
"###);
crate::b
T: v
crate::a
T: t v
"#]],
);
}
+258 -288
View File
@@ -2,367 +2,337 @@
#[test]
fn glob_1() {
let map = def_map(
r"
//- /lib.rs
mod foo;
use foo::*;
check(
r#"
//- /lib.rs
mod foo;
use foo::*;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::Baz;
pub struct Foo;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::Baz;
pub struct Foo;
//- /foo/bar.rs
pub struct Baz;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮Foo: t v
⋮bar: t
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮Foo: t v
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###
//- /foo/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
Foo: t v
bar: t
foo: t
crate::foo
Baz: t v
Foo: t v
bar: t
crate::foo::bar
Baz: t v
"#]],
);
}
#[test]
fn glob_2() {
let map = def_map(
"
//- /lib.rs
mod foo;
use foo::*;
check(
r#"
//- /lib.rs
mod foo;
use foo::*;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::*;
pub struct Foo;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::*;
pub struct Foo;
//- /foo/bar.rs
pub struct Baz;
pub use super::*;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮Foo: t v
⋮bar: t
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮Foo: t v
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
⋮Foo: t v
⋮bar: t
"###
//- /foo/bar.rs
pub struct Baz;
pub use super::*;
"#,
expect![[r#"
crate
Baz: t v
Foo: t v
bar: t
foo: t
crate::foo
Baz: t v
Foo: t v
bar: t
crate::foo::bar
Baz: t v
Foo: t v
bar: t
"#]],
);
}
#[test]
fn glob_privacy_1() {
let map = def_map(
check(
r"
//- /lib.rs
mod foo;
use foo::*;
//- /lib.rs
mod foo;
use foo::*;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::*;
struct PrivateStructFoo;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::*;
struct PrivateStructFoo;
//- /foo/bar.rs
pub struct Baz;
struct PrivateStructBar;
pub use super::*;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮bar: t
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮PrivateStructFoo: t v
⋮bar: t
⋮crate::foo::bar
Baz: t v
PrivateStructBar: t v
⋮PrivateStructFoo: t v
⋮bar: t
"###
//- /foo/bar.rs
pub struct Baz;
struct PrivateStructBar;
pub use super::*;
",
expect![[r#"
crate
Baz: t v
bar: t
foo: t
crate::foo
Baz: t v
PrivateStructFoo: t v
bar: t
crate::foo::bar
Baz: t v
PrivateStructBar: t v
PrivateStructFoo: t v
bar: t
"#]],
);
}
#[test]
fn glob_privacy_2() {
let map = def_map(
check(
r"
//- /lib.rs
mod foo;
use foo::*;
use foo::bar::*;
//- /lib.rs
mod foo;
use foo::*;
use foo::bar::*;
//- /foo/mod.rs
mod bar;
fn Foo() {};
pub struct Foo {};
//- /foo/mod.rs
mod bar;
fn Foo() {};
pub struct Foo {};
//- /foo/bar.rs
pub(super) struct PrivateBaz;
struct PrivateBar;
pub(crate) struct PubCrateStruct;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Foo: t
⋮PubCrateStruct: t v
⋮foo: t
⋮crate::foo
⋮Foo: t v
⋮bar: t
⋮crate::foo::bar
PrivateBar: t v
⋮PrivateBaz: t v
⋮PubCrateStruct: t v
"###
//- /foo/bar.rs
pub(super) struct PrivateBaz;
struct PrivateBar;
pub(crate) struct PubCrateStruct;
",
expect![[r#"
crate
Foo: t
PubCrateStruct: t v
foo: t
crate::foo
Foo: t v
bar: t
crate::foo::bar
PrivateBar: t v
PrivateBaz: t v
PubCrateStruct: t v
"#]],
);
}
#[test]
fn glob_across_crates() {
mark::check!(glob_across_crates);
let map = def_map(
r"
//- /main.rs crate:main deps:test_crate
use test_crate::*;
check(
r#"
//- /main.rs crate:main deps:test_crate
use test_crate::*;
//- /lib.rs crate:test_crate
pub struct Baz;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
"###
//- /lib.rs crate:test_crate
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
"#]],
);
}
#[test]
fn glob_privacy_across_crates() {
let map = def_map(
r"
//- /main.rs crate:main deps:test_crate
use test_crate::*;
check(
r#"
//- /main.rs crate:main deps:test_crate
use test_crate::*;
//- /lib.rs crate:test_crate
pub struct Baz;
struct Foo;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
"###
//- /lib.rs crate:test_crate
pub struct Baz;
struct Foo;
"#,
expect![[r#"
crate
Baz: t v
"#]],
);
}
#[test]
fn glob_enum() {
mark::check!(glob_enum);
let map = def_map(
"
//- /lib.rs
enum Foo {
Bar, Baz
}
use self::Foo::*;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Baz: t v
⋮Foo: t
"###
check(
r#"
enum Foo { Bar, Baz }
use self::Foo::*;
"#,
expect![[r#"
crate
Bar: t v
Baz: t v
Foo: t
"#]],
);
}
#[test]
fn glob_enum_group() {
mark::check!(glob_enum_group);
let map = def_map(
r"
//- /lib.rs
enum Foo {
Bar, Baz
}
use self::Foo::{*};
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Baz: t v
⋮Foo: t
"###
check(
r#"
enum Foo { Bar, Baz }
use self::Foo::{*};
"#,
expect![[r#"
crate
Bar: t v
Baz: t v
Foo: t
"#]],
);
}
#[test]
fn glob_shadowed_def() {
mark::check!(import_shadowed);
let map = def_map(
r###"
//- /lib.rs
mod foo;
mod bar;
check(
r#"
//- /lib.rs
mod foo;
mod bar;
use foo::*;
use bar::baz;
use baz::Bar;
use foo::*;
use bar::baz;
//- /foo.rs
pub mod baz { pub struct Foo; }
use baz::Bar;
//- /bar.rs
pub mod baz { pub struct Bar; }
"#,
expect![[r#"
crate
Bar: t v
bar: t
baz: t
foo: t
//- /foo.rs
pub mod baz {
pub struct Foo;
}
crate::bar
baz: t
//- /bar.rs
pub mod baz {
pub struct Bar;
}
"###,
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮bar: t
⋮baz: t
⋮foo: t
⋮crate::bar
⋮baz: t
⋮crate::bar::baz
⋮Bar: t v
⋮crate::foo
⋮baz: t
⋮crate::foo::baz
⋮Foo: t v
"###
crate::bar::baz
Bar: t v
crate::foo
baz: t
crate::foo::baz
Foo: t v
"#]],
);
}
#[test]
fn glob_shadowed_def_reversed() {
let map = def_map(
r###"
//- /lib.rs
mod foo;
mod bar;
check(
r#"
//- /lib.rs
mod foo;
mod bar;
use bar::baz;
use foo::*;
use baz::Bar;
use bar::baz;
use foo::*;
//- /foo.rs
pub mod baz { pub struct Foo; }
use baz::Bar;
//- /bar.rs
pub mod baz { pub struct Bar; }
"#,
expect![[r#"
crate
Bar: t v
bar: t
baz: t
foo: t
//- /foo.rs
pub mod baz {
pub struct Foo;
}
crate::bar
baz: t
//- /bar.rs
pub mod baz {
pub struct Bar;
}
"###,
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮bar: t
⋮baz: t
⋮foo: t
⋮crate::bar
⋮baz: t
⋮crate::bar::baz
⋮Bar: t v
⋮crate::foo
⋮baz: t
⋮crate::foo::baz
⋮Foo: t v
"###
crate::bar::baz
Bar: t v
crate::foo
baz: t
crate::foo::baz
Foo: t v
"#]],
);
}
#[test]
fn glob_shadowed_def_dependencies() {
let map = def_map(
r###"
//- /lib.rs
mod a { pub mod foo { pub struct X; } }
mod b { pub use super::a::foo; }
mod c { pub mod foo { pub struct Y; } }
mod d {
use super::c::foo;
use super::b::*;
use foo::Y;
}
"###,
);
assert_snapshot!(map, @r###"
⋮crate
⋮a: t
⋮b: t
⋮c: t
⋮d: t
⋮crate::d
⋮Y: t v
⋮foo: t
⋮crate::c
⋮foo: t
⋮crate::c::foo
⋮Y: t v
⋮crate::b
⋮foo: t
⋮crate::a
⋮foo: t
⋮crate::a::foo
⋮X: t v
"###
check(
r#"
mod a { pub mod foo { pub struct X; } }
mod b { pub use super::a::foo; }
mod c { pub mod foo { pub struct Y; } }
mod d {
use super::c::foo;
use super::b::*;
use foo::Y;
}
"#,
expect![[r#"
crate
a: t
b: t
c: t
d: t
crate::d
Y: t v
foo: t
crate::c
foo: t
crate::c::foo
Y: t v
crate::b
foo: t
crate::a
foo: t
crate::a::foo
X: t v
"#]],
);
}
+497 -514
View File
@@ -2,655 +2,635 @@
#[test]
fn macro_rules_are_globally_visible() {
let map = def_map(
r"
//- /lib.rs
macro_rules! structs {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
structs!(Foo);
mod nested;
check(
r#"
//- /lib.rs
macro_rules! structs {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
structs!(Foo);
mod nested;
//- /nested.rs
structs!(Bar, Baz);
",
//- /nested.rs
structs!(Bar, Baz);
"#,
expect![[r#"
crate
Foo: t
nested: t
crate::nested
Bar: t
Baz: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Foo: t
⋮nested: t
⋮crate::nested
⋮Bar: t
⋮Baz: t
"###);
}
#[test]
fn macro_rules_can_define_modules() {
let map = def_map(
r"
//- /lib.rs
macro_rules! m {
($name:ident) => { mod $name; }
}
m!(n1);
check(
r#"
//- /lib.rs
macro_rules! m {
($name:ident) => { mod $name; }
}
m!(n1);
mod m { m!(n3) }
mod m {
m!(n3)
}
//- /n1.rs
m!(n2)
//- /n1/n2.rs
struct X;
//- /m/n3.rs
struct Y;
"#,
expect![[r#"
crate
m: t
n1: t
//- /n1.rs
m!(n2)
//- /n1/n2.rs
struct X;
//- /m/n3.rs
struct Y;
",
crate::m
n3: t
crate::m::n3
Y: t v
crate::n1
n2: t
crate::n1::n2
X: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮m: t
⋮n1: t
⋮crate::m
⋮n3: t
⋮crate::m::n3
⋮Y: t v
⋮crate::n1
⋮n2: t
⋮crate::n1::n2
⋮X: t v
"###);
}
#[test]
fn macro_rules_from_other_crates_are_visible() {
let map = def_map(
"
//- /main.rs crate:main deps:foo
foo::structs!(Foo, Bar)
mod bar;
check(
r#"
//- /main.rs crate:main deps:foo
foo::structs!(Foo, Bar)
mod bar;
//- /bar.rs
use crate::*;
//- /bar.rs
use crate::*;
//- /lib.rs crate:foo
#[macro_export]
macro_rules! structs {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
",
//- /lib.rs crate:foo
#[macro_export]
macro_rules! structs {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
"#,
expect![[r#"
crate
Bar: t
Foo: t
bar: t
crate::bar
Bar: t
Foo: t
bar: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t
⋮Foo: t
⋮bar: t
⋮crate::bar
⋮Bar: t
⋮Foo: t
⋮bar: t
"###);
}
#[test]
fn macro_rules_export_with_local_inner_macros_are_visible() {
let map = def_map(
"
//- /main.rs crate:main deps:foo
foo::structs!(Foo, Bar)
mod bar;
check(
r#"
//- /main.rs crate:main deps:foo
foo::structs!(Foo, Bar)
mod bar;
//- /bar.rs
use crate::*;
//- /bar.rs
use crate::*;
//- /lib.rs crate:foo
#[macro_export(local_inner_macros)]
macro_rules! structs {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
",
//- /lib.rs crate:foo
#[macro_export(local_inner_macros)]
macro_rules! structs {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
"#,
expect![[r#"
crate
Bar: t
Foo: t
bar: t
crate::bar
Bar: t
Foo: t
bar: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t
⋮Foo: t
⋮bar: t
⋮crate::bar
⋮Bar: t
⋮Foo: t
⋮bar: t
"###);
}
#[test]
fn local_inner_macros_makes_local_macros_usable() {
let map = def_map(
"
//- /main.rs crate:main deps:foo
foo::structs!(Foo, Bar);
mod bar;
//- /bar.rs
use crate::*;
//- /lib.rs crate:foo
#[macro_export(local_inner_macros)]
macro_rules! structs {
($($i:ident),*) => {
inner!($($i),*);
}
}
#[macro_export]
macro_rules! inner {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
",
check(
r#"
//- /main.rs crate:main deps:foo
foo::structs!(Foo, Bar);
mod bar;
//- /bar.rs
use crate::*;
//- /lib.rs crate:foo
#[macro_export(local_inner_macros)]
macro_rules! structs {
($($i:ident),*) => {
inner!($($i),*);
}
}
#[macro_export]
macro_rules! inner {
($($i:ident),*) => {
$(struct $i { field: u32 } )*
}
}
"#,
expect![[r#"
crate
Bar: t
Foo: t
bar: t
crate::bar
Bar: t
Foo: t
bar: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t
⋮Foo: t
⋮bar: t
⋮crate::bar
⋮Bar: t
⋮Foo: t
⋮bar: t
"###);
}
#[test]
fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
let map = def_map(
"
//- /main.rs crate:main deps:foo
macro_rules! baz {
() => {
use foo::bar;
}
}
check(
r#"
//- /main.rs crate:main deps:foo
macro_rules! baz {
() => {
use foo::bar;
}
}
foo!();
bar!();
baz!();
foo!();
bar!();
baz!();
//- /lib.rs crate:foo
#[macro_export]
macro_rules! foo {
() => {
struct Foo { field: u32 }
}
}
#[macro_export]
macro_rules! bar {
() => {
use foo::foo;
}
}
",
//- /lib.rs crate:foo
#[macro_export]
macro_rules! foo {
() => {
struct Foo { field: u32 }
}
}
#[macro_export]
macro_rules! bar {
() => {
use foo::foo;
}
}
"#,
expect![[r#"
crate
Foo: t
bar: m
foo: m
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Foo: t
⋮bar: m
⋮foo: m
"###);
}
#[test]
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use);
let map = def_map(
"
//- /main.rs crate:main deps:foo
structs!(Foo);
structs_priv!(Bar);
structs_not_exported!(MacroNotResolved1);
crate::structs!(MacroNotResolved2);
check(
r#"
//- /main.rs crate:main deps:foo
structs!(Foo);
structs_priv!(Bar);
structs_not_exported!(MacroNotResolved1);
crate::structs!(MacroNotResolved2);
mod bar;
mod bar;
#[macro_use]
extern crate foo;
#[macro_use]
extern crate foo;
//- /bar.rs
structs!(Baz);
crate::structs!(MacroNotResolved3);
//- /bar.rs
structs!(Baz);
crate::structs!(MacroNotResolved3);
//- /lib.rs crate:foo
#[macro_export]
macro_rules! structs {
($i:ident) => { struct $i; }
}
//- /lib.rs crate:foo
#[macro_export]
macro_rules! structs {
($i:ident) => { struct $i; }
}
macro_rules! structs_not_exported {
($i:ident) => { struct $i; }
}
macro_rules! structs_not_exported {
($i:ident) => { struct $i; }
}
mod priv_mod {
#[macro_export]
macro_rules! structs_priv {
($i:ident) => { struct $i; }
}
}
",
mod priv_mod {
#[macro_export]
macro_rules! structs_priv {
($i:ident) => { struct $i; }
}
}
"#,
expect![[r#"
crate
Bar: t v
Foo: t v
bar: t
foo: t
crate::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Foo: t v
⋮bar: t
⋮foo: t
⋮crate::bar
⋮Baz: t v
"###);
}
#[test]
fn prelude_is_macro_use() {
mark::check!(prelude_is_macro_use);
let map = def_map(
"
//- /main.rs crate:main deps:foo
structs!(Foo);
structs_priv!(Bar);
structs_outside!(Out);
crate::structs!(MacroNotResolved2);
check(
r#"
//- /main.rs crate:main deps:foo
structs!(Foo);
structs_priv!(Bar);
structs_outside!(Out);
crate::structs!(MacroNotResolved2);
mod bar;
mod bar;
//- /bar.rs
structs!(Baz);
crate::structs!(MacroNotResolved3);
//- /bar.rs
structs!(Baz);
crate::structs!(MacroNotResolved3);
//- /lib.rs crate:foo
#[prelude_import]
use self::prelude::*;
//- /lib.rs crate:foo
#[prelude_import]
use self::prelude::*;
mod prelude {
#[macro_export]
macro_rules! structs {
($i:ident) => { struct $i; }
}
mod priv_mod {
#[macro_export]
macro_rules! structs_priv {
($i:ident) => { struct $i; }
}
}
}
mod prelude {
#[macro_export]
macro_rules! structs {
($i:ident) => { struct $i; }
}
mod priv_mod {
#[macro_export]
macro_rules! structs_outside {
macro_rules! structs_priv {
($i:ident) => { struct $i; }
}
",
}
}
#[macro_export]
macro_rules! structs_outside {
($i:ident) => { struct $i; }
}
"#,
expect![[r#"
crate
Bar: t v
Foo: t v
Out: t v
bar: t
crate::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Foo: t v
⋮Out: t v
⋮bar: t
⋮crate::bar
⋮Baz: t v
"###);
}
#[test]
fn prelude_cycle() {
let map = def_map(
"
//- /lib.rs
#[prelude_import]
use self::prelude::*;
check(
r#"
#[prelude_import]
use self::prelude::*;
declare_mod!();
declare_mod!();
mod prelude {
macro_rules! declare_mod {
() => (mod foo {})
}
}
",
mod prelude {
macro_rules! declare_mod {
() => (mod foo {})
}
}
"#,
expect![[r#"
crate
prelude: t
crate::prelude
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮prelude: t
⋮crate::prelude
"###);
}
#[test]
fn plain_macros_are_legacy_textual_scoped() {
let map = def_map(
check(
r#"
//- /main.rs
mod m1;
bar!(NotFoundNotMacroUse);
//- /main.rs
mod m1;
bar!(NotFoundNotMacroUse);
mod m2 {
foo!(NotFoundBeforeInside2);
}
mod m2 { foo!(NotFoundBeforeInside2); }
macro_rules! foo {
($x:ident) => { struct $x; }
}
foo!(Ok);
macro_rules! foo {
($x:ident) => { struct $x; }
}
foo!(Ok);
mod m3;
foo!(OkShadowStop);
bar!(NotFoundMacroUseStop);
mod m3;
foo!(OkShadowStop);
bar!(NotFoundMacroUseStop);
#[macro_use]
mod m5 {
#[macro_use]
mod m6 {
macro_rules! foo {
($x:ident) => { fn $x() {} }
}
}
}
foo!(ok_double_macro_use_shadow);
baz!(NotFoundBefore);
#[macro_use]
mod m7 {
macro_rules! baz {
($x:ident) => { struct $x; }
}
}
baz!(OkAfter);
//- /m1.rs
foo!(NotFoundBeforeInside1);
macro_rules! bar {
($x:ident) => { struct $x; }
}
//- /m3/mod.rs
foo!(OkAfterInside);
#[macro_use]
mod m5 {
#[macro_use]
mod m6 {
macro_rules! foo {
($x:ident) => { fn $x() {} }
}
foo!(ok_shadow);
}
}
foo!(ok_double_macro_use_shadow);
#[macro_use]
mod m4;
bar!(OkMacroUse);
baz!(NotFoundBefore);
#[macro_use]
mod m7 {
macro_rules! baz {
($x:ident) => { struct $x; }
}
}
baz!(OkAfter);
//- /m3/m4.rs
foo!(ok_shadow_deep);
macro_rules! bar {
($x:ident) => { struct $x; }
}
"#,
//- /m1.rs
foo!(NotFoundBeforeInside1);
macro_rules! bar {
($x:ident) => { struct $x; }
}
//- /m3/mod.rs
foo!(OkAfterInside);
macro_rules! foo {
($x:ident) => { fn $x() {} }
}
foo!(ok_shadow);
#[macro_use]
mod m4;
bar!(OkMacroUse);
//- /m3/m4.rs
foo!(ok_shadow_deep);
macro_rules! bar {
($x:ident) => { struct $x; }
}
"#,
expect![[r#"
crate
Ok: t v
OkAfter: t v
OkShadowStop: t v
m1: t
m2: t
m3: t
m5: t
m7: t
ok_double_macro_use_shadow: v
crate::m7
crate::m1
crate::m5
m6: t
crate::m5::m6
crate::m2
crate::m3
OkAfterInside: t v
OkMacroUse: t v
m4: t
ok_shadow: v
crate::m3::m4
ok_shadow_deep: v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Ok: t v
⋮OkAfter: t v
⋮OkShadowStop: t v
⋮m1: t
⋮m2: t
⋮m3: t
⋮m5: t
⋮m7: t
⋮ok_double_macro_use_shadow: v
⋮crate::m7
⋮crate::m1
⋮crate::m5
⋮m6: t
⋮crate::m5::m6
⋮crate::m2
⋮crate::m3
⋮OkAfterInside: t v
⋮OkMacroUse: t v
⋮m4: t
⋮ok_shadow: v
⋮crate::m3::m4
⋮ok_shadow_deep: v
"###);
}
#[test]
fn type_value_macro_live_in_different_scopes() {
let map = def_map(
"
//- /main.rs
#[macro_export]
macro_rules! foo {
($x:ident) => { type $x = (); }
}
check(
r#"
#[macro_export]
macro_rules! foo {
($x:ident) => { type $x = (); }
}
foo!(foo);
use foo as bar;
foo!(foo);
use foo as bar;
use self::foo as baz;
fn baz() {}
",
use self::foo as baz;
fn baz() {}
"#,
expect![[r#"
crate
bar: t m
baz: t v m
foo: t m
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮bar: t m
⋮baz: t v m
⋮foo: t m
"###);
}
#[test]
fn macro_use_can_be_aliased() {
let map = def_map(
"
//- /main.rs crate:main deps:foo
#[macro_use]
extern crate foo;
check(
r#"
//- /main.rs crate:main deps:foo
#[macro_use]
extern crate foo;
foo!(Direct);
bar!(Alias);
foo!(Direct);
bar!(Alias);
//- /lib.rs crate:foo
use crate::foo as bar;
//- /lib.rs crate:foo
use crate::foo as bar;
mod m {
#[macro_export]
macro_rules! foo {
($x:ident) => { struct $x; }
}
}
",
mod m {
#[macro_export]
macro_rules! foo {
($x:ident) => { struct $x; }
}
}
"#,
expect![[r#"
crate
Alias: t v
Direct: t v
foo: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Alias: t v
⋮Direct: t v
⋮foo: t
"###);
}
#[test]
fn path_qualified_macros() {
let map = def_map(
"
//- /main.rs
macro_rules! foo {
($x:ident) => { struct $x; }
}
check(
r#"
macro_rules! foo {
($x:ident) => { struct $x; }
}
crate::foo!(NotResolved);
crate::foo!(NotResolved);
crate::bar!(OkCrate);
bar!(OkPlain);
alias1!(NotHere);
m::alias1!(OkAliasPlain);
m::alias2!(OkAliasSuper);
m::alias3!(OkAliasCrate);
not_found!(NotFound);
crate::bar!(OkCrate);
bar!(OkPlain);
alias1!(NotHere);
m::alias1!(OkAliasPlain);
m::alias2!(OkAliasSuper);
m::alias3!(OkAliasCrate);
not_found!(NotFound);
mod m {
#[macro_export]
macro_rules! bar {
($x:ident) => { struct $x; }
}
mod m {
#[macro_export]
macro_rules! bar {
($x:ident) => { struct $x; }
}
pub use bar as alias1;
pub use super::bar as alias2;
pub use crate::bar as alias3;
pub use self::bar as not_found;
}
"#,
expect![[r#"
crate
OkAliasCrate: t v
OkAliasPlain: t v
OkAliasSuper: t v
OkCrate: t v
OkPlain: t v
bar: m
m: t
pub use bar as alias1;
pub use super::bar as alias2;
pub use crate::bar as alias3;
pub use self::bar as not_found;
}
",
crate::m
alias1: m
alias2: m
alias3: m
not_found: _
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮OkAliasCrate: t v
⋮OkAliasPlain: t v
⋮OkAliasSuper: t v
⋮OkCrate: t v
⋮OkPlain: t v
⋮bar: m
⋮m: t
⋮crate::m
⋮alias1: m
⋮alias2: m
⋮alias3: m
⋮not_found: _
"###);
}
#[test]
fn macro_dollar_crate_is_correct_in_item() {
mark::check!(macro_dollar_crate_self);
let map = def_map(
"
//- /main.rs crate:main deps:foo
#[macro_use]
extern crate foo;
check(
r#"
//- /main.rs crate:main deps:foo
#[macro_use]
extern crate foo;
#[macro_use]
mod m {
macro_rules! current {
() => {
use $crate::Foo as FooSelf;
}
}
#[macro_use]
mod m {
macro_rules! current {
() => {
use $crate::Foo as FooSelf;
}
}
}
struct Foo;
struct Foo;
current!();
not_current1!();
foo::not_current2!();
current!();
not_current1!();
foo::not_current2!();
//- /lib.rs crate:foo
mod m {
#[macro_export]
macro_rules! not_current1 {
() => {
use $crate::Bar;
}
}
//- /lib.rs crate:foo
mod m {
#[macro_export]
macro_rules! not_current1 {
() => {
use $crate::Bar;
}
}
}
#[macro_export]
macro_rules! not_current2 {
() => {
use $crate::Baz;
}
}
#[macro_export]
macro_rules! not_current2 {
() => {
use $crate::Baz;
}
}
struct Bar;
struct Baz;
",
struct Bar;
struct Baz;
"#,
expect![[r#"
crate
Bar: t v
Baz: t v
Foo: t v
FooSelf: t v
foo: t
m: t
crate::m
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮Baz: t v
⋮Foo: t v
⋮FooSelf: t v
⋮foo: t
⋮m: t
⋮crate::m
"###);
}
#[test]
fn macro_dollar_crate_is_correct_in_indirect_deps() {
mark::check!(macro_dollar_crate_other);
// From std
let map = def_map(
check(
r#"
//- /main.rs crate:main deps:std
foo!();
//- /main.rs crate:main deps:std
foo!();
//- /std.rs crate:std deps:core
#[prelude_import]
use self::prelude::*;
//- /std.rs crate:std deps:core
#[prelude_import]
use self::prelude::*;
pub use core::foo;
pub use core::foo;
mod prelude {}
mod prelude {}
#[macro_use]
mod std_macros;
#[macro_use]
mod std_macros;
//- /core.rs crate:core
#[macro_export]
macro_rules! foo {
() => {
use $crate::bar;
}
}
//- /core.rs crate:core
#[macro_export]
macro_rules! foo {
() => {
use $crate::bar;
}
}
pub struct bar;
"#,
pub struct bar;
"#,
expect![[r#"
crate
bar: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮bar: t v
"###);
}
#[test]
fn expand_derive() {
let map = compute_crate_def_map(
"
//- /main.rs
#[derive(Clone)]
struct Foo;
",
);
assert_eq!(map.modules[map.root].scope.impls().len(), 1);
}
#[test]
fn expand_multiple_derive() {
let map = compute_crate_def_map(
"
//- /main.rs
@@ -664,8 +644,8 @@ fn expand_multiple_derive() {
#[test]
fn macro_expansion_overflow() {
mark::check!(macro_expansion_overflow);
compute_crate_def_map(
"
check(
r#"
macro_rules! a {
($e:expr; $($t:tt)*) => {
b!($($t)*);
@@ -681,6 +661,9 @@ macro_rules! b {
}
b! { static = #[] (); }
",
"#,
expect![[r#"
crate
"#]],
);
}
@@ -3,710 +3,672 @@
#[test]
fn name_res_works_for_broken_modules() {
mark::check!(name_res_works_for_broken_modules);
let map = def_map(
check(
r"
//- /lib.rs
mod foo // no `;`, no body
//- /lib.rs
mod foo // no `;`, no body
use self::foo::Baz;
use self::foo::Baz;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::Baz;
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
",
expect![[r#"
crate
Baz: _
foo: t
pub use self::bar::Baz;
//- /foo/bar.rs
pub struct Baz;
",
crate::foo
"#]],
);
assert_snapshot!(map, @r###"
crate
Baz: _
foo: t
crate::foo
"###);
}
#[test]
fn nested_module_resolution() {
let map = def_map(
r"
//- /lib.rs
mod n1;
check(
r#"
//- /lib.rs
mod n1;
//- /n1.rs
mod n2;
//- /n1.rs
mod n2;
//- /n1/n2.rs
struct X;
",
//- /n1/n2.rs
struct X;
"#,
expect![[r#"
crate
n1: t
crate::n1
n2: t
crate::n1::n2
X: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮n1: t
⋮crate::n1
⋮n2: t
⋮crate::n1::n2
⋮X: t v
"###);
}
#[test]
fn nested_module_resolution_2() {
let map = def_map(
r"
//- /lib.rs
mod prelude;
mod iter;
check(
r#"
//- /lib.rs
mod prelude;
mod iter;
//- /prelude.rs
pub use crate::iter::Iterator;
//- /prelude.rs
pub use crate::iter::Iterator;
//- /iter.rs
pub use self::traits::Iterator;
mod traits;
//- /iter.rs
pub use self::traits::Iterator;
mod traits;
//- /iter/traits.rs
pub use self::iterator::Iterator;
mod iterator;
//- /iter/traits.rs
pub use self::iterator::Iterator;
mod iterator;
//- /iter/traits/iterator.rs
pub trait Iterator;
",
//- /iter/traits/iterator.rs
pub trait Iterator;
"#,
expect![[r#"
crate
iter: t
prelude: t
crate::iter
Iterator: t
traits: t
crate::iter::traits
Iterator: t
iterator: t
crate::iter::traits::iterator
Iterator: t
crate::prelude
Iterator: t
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮iter: t
⋮prelude: t
⋮crate::iter
⋮Iterator: t
⋮traits: t
⋮crate::iter::traits
⋮Iterator: t
⋮iterator: t
⋮crate::iter::traits::iterator
⋮Iterator: t
⋮crate::prelude
⋮Iterator: t
"###);
}
#[test]
fn module_resolution_works_for_non_standard_filenames() {
let map = def_map(
"
//- /my_library.rs crate:my_library
mod foo;
use self::foo::Bar;
check(
r#"
//- /my_library.rs crate:my_library
mod foo;
use self::foo::Bar;
//- /foo/mod.rs
pub struct Bar;
",
//- /foo/mod.rs
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
foo: t
crate::foo
Bar: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮foo: t
⋮crate::foo
⋮Bar: t v
"###);
}
#[test]
fn module_resolution_works_for_raw_modules() {
let map = def_map(
"
//- /lib.rs
mod r#async;
use self::r#async::Bar;
check(
r#"
//- /lib.rs
mod r#async;
use self::r#async::Bar;
//- /async.rs
pub struct Bar;
",
//- /async.rs
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
async: t
crate::async
Bar: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮async: t
⋮crate::async
⋮Bar: t v
"###);
}
#[test]
fn module_resolution_decl_path() {
let map = def_map(
r###"
//- /lib.rs
#[path = "bar/baz/foo.rs"]
mod foo;
use self::foo::Bar;
check(
r#"
//- /lib.rs
#[path = "bar/baz/foo.rs"]
mod foo;
use self::foo::Bar;
//- /bar/baz/foo.rs
pub struct Bar;
"###,
//- /bar/baz/foo.rs
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
foo: t
crate::foo
Bar: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Bar: t v
⋮foo: t
⋮crate::foo
⋮Bar: t v
"###);
}
#[test]
fn module_resolution_module_with_path_in_mod_rs() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo/mod.rs
#[path = "baz.rs"]
pub mod bar;
//- /foo/mod.rs
#[path = "baz.rs"]
pub mod bar;
use self::bar::Baz;
use self::bar::Baz;
//- /foo/baz.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
//- /foo/baz.rs
pub struct Baz;
"###,
crate::foo
Baz: t v
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_module_with_path_non_crate_root() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
#[path = "baz.rs"]
pub mod bar;
//- /foo.rs
#[path = "baz.rs"]
pub mod bar;
use self::bar::Baz;
use self::bar::Baz;
//- /baz.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
//- /baz.rs
pub struct Baz;
"###,
crate::foo
Baz: t v
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_module_decl_path_super() {
let map = def_map(
r###"
//- /main.rs
#[path = "bar/baz/module.rs"]
mod foo;
pub struct Baz;
check(
r#"
//- /main.rs
#[path = "bar/baz/module.rs"]
mod foo;
pub struct Baz;
//- /bar/baz/module.rs
use super::Baz;
"###,
//- /bar/baz/module.rs
use super::Baz;
"#,
expect![[r#"
crate
Baz: t v
foo: t
crate::foo
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮foo: t
⋮crate::foo
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_explicit_path_mod_rs() {
let map = def_map(
r###"
//- /main.rs
#[path = "module/mod.rs"]
mod foo;
check(
r#"
//- /main.rs
#[path = "module/mod.rs"]
mod foo;
//- /module/mod.rs
pub struct Baz;
"###,
//- /module/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_relative_path() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
#[path = "./sub.rs"]
pub mod foo_bar;
//- /foo.rs
#[path = "./sub.rs"]
pub mod foo_bar;
//- /sub.rs
pub struct Baz;
"###,
//- /sub.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
foo_bar: t
crate::foo::foo_bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮foo_bar: t
⋮crate::foo::foo_bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_relative_path_2() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo/mod.rs
#[path="../sub.rs"]
pub mod foo_bar;
//- /foo/mod.rs
#[path="../sub.rs"]
pub mod foo_bar;
//- /sub.rs
pub struct Baz;
"###,
//- /sub.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
foo_bar: t
crate::foo::foo_bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮foo_bar: t
⋮crate::foo::foo_bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_relative_path_outside_root() {
let map = def_map(
r###"
//- /main.rs
#[path="../../../../../outside.rs"]
mod foo;
"###,
check(
r#"
//- /main.rs
#[path="../../../../../outside.rs"]
mod foo;
"#,
expect![[r#"
crate
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
"###);
}
#[test]
fn module_resolution_explicit_path_mod_rs_2() {
let map = def_map(
r###"
//- /main.rs
#[path = "module/bar/mod.rs"]
mod foo;
check(
r#"
//- /main.rs
#[path = "module/bar/mod.rs"]
mod foo;
//- /module/bar/mod.rs
pub struct Baz;
"###,
//- /module/bar/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_explicit_path_mod_rs_with_win_separator() {
let map = def_map(
r###"
//- /main.rs
#[path = "module\bar\mod.rs"]
mod foo;
check(
r#"
//- /main.rs
#[path = "module\bar\mod.rs"]
mod foo;
//- /module/bar/mod.rs
pub struct Baz;
"###,
//- /module/bar/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_with_path_attribute() {
let map = def_map(
r###"
//- /main.rs
#[path = "models"]
mod foo {
mod bar;
}
check(
r#"
//- /main.rs
#[path = "models"]
mod foo { mod bar; }
//- /models/bar.rs
pub struct Baz;
"###,
//- /models/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module() {
let map = def_map(
r###"
//- /main.rs
mod foo {
mod bar;
}
check(
r#"
//- /main.rs
mod foo { mod bar; }
//- /foo/bar.rs
pub struct Baz;
"###,
//- /foo/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
let map = def_map(
r###"
//- /main.rs
#[path = "models/db"]
mod foo {
mod bar;
}
check(
r#"
//- /main.rs
#[path = "models/db"]
mod foo { mod bar; }
//- /models/db/bar.rs
pub struct Baz;
"###,
//- /models/db/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_3() {
let map = def_map(
r###"
//- /main.rs
#[path = "models/db"]
mod foo {
#[path = "users.rs"]
mod bar;
}
check(
r#"
//- /main.rs
#[path = "models/db"]
mod foo {
#[path = "users.rs"]
mod bar;
}
//- /models/db/users.rs
pub struct Baz;
"###,
//- /models/db/users.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_empty_path() {
let map = def_map(
r###"
//- /main.rs
#[path = ""]
mod foo {
#[path = "users.rs"]
mod bar;
}
check(
r#"
//- /main.rs
#[path = ""]
mod foo {
#[path = "users.rs"]
mod bar;
}
//- /users.rs
pub struct Baz;
"###,
//- /users.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_empty_path() {
let map = def_map(
r###"
//- /main.rs
#[path = ""] // Should try to read `/` (a directory)
mod foo;
check(
r#"
//- /main.rs
#[path = ""] // Should try to read `/` (a directory)
mod foo;
//- /foo.rs
pub struct Baz;
"###,
//- /foo.rs
pub struct Baz;
"#,
expect![[r#"
crate
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_relative_path() {
let map = def_map(
r###"
//- /main.rs
#[path = "./models"]
mod foo {
mod bar;
}
check(
r#"
//- /main.rs
#[path = "./models"]
mod foo { mod bar; }
//- /models/bar.rs
pub struct Baz;
"###,
//- /models/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_crate_root() {
let map = def_map(
r###"
//- /main.rs
mod foo {
#[path = "baz.rs"]
mod bar;
}
use self::foo::bar::Baz;
check(
r#"
//- /main.rs
mod foo {
#[path = "baz.rs"]
mod bar;
}
use self::foo::bar::Baz;
//- /foo/baz.rs
pub struct Baz;
"###,
//- /foo/baz.rs
pub struct Baz;
"#,
expect![[r#"
crate
Baz: t v
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮Baz: t v
⋮foo: t
⋮crate::foo
⋮bar: t
⋮crate::foo::bar
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_mod_rs() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo/mod.rs
mod bar {
#[path = "qwe.rs"]
pub mod baz;
}
use self::bar::baz::Baz;
//- /foo/mod.rs
mod bar {
#[path = "qwe.rs"]
pub mod baz;
}
use self::bar::baz::Baz;
//- /foo/bar/qwe.rs
pub struct Baz;
"###,
//- /foo/bar/qwe.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
bar: t
crate::foo::bar
baz: t
crate::foo::bar::baz
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮bar: t
⋮crate::foo::bar
⋮baz: t
⋮crate::foo::bar::baz
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
mod bar {
#[path = "qwe.rs"]
pub mod baz;
}
use self::bar::baz::Baz;
//- /foo.rs
mod bar {
#[path = "qwe.rs"]
pub mod baz;
}
use self::bar::baz::Baz;
//- /foo/bar/qwe.rs
pub struct Baz;
"###,
//- /foo/bar/qwe.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
bar: t
crate::foo::bar
baz: t
crate::foo::bar::baz
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮bar: t
⋮crate::foo::bar
⋮baz: t
⋮crate::foo::bar::baz
⋮Baz: t v
"###);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
let map = def_map(
r###"
//- /main.rs
mod foo;
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
#[path = "bar"]
mod bar {
pub mod baz;
}
use self::bar::baz::Baz;
//- /foo.rs
#[path = "bar"]
mod bar {
pub mod baz;
}
use self::bar::baz::Baz;
//- /bar/baz.rs
pub struct Baz;
"###,
//- /bar/baz.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
bar: t
crate::foo::bar
baz: t
crate::foo::bar::baz
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮crate::foo
⋮Baz: t v
⋮bar: t
⋮crate::foo::bar
⋮baz: t
⋮crate::foo::bar::baz
⋮Baz: t v
"###);
}
#[test]
@@ -749,91 +711,88 @@ mod baz {}
#[test]
fn module_resolution_decl_inside_module_in_non_crate_root_2() {
let map = def_map(
r###"
//- /main.rs
#[path="module/m2.rs"]
mod module;
check(
r#"
//- /main.rs
#[path="module/m2.rs"]
mod module;
//- /module/m2.rs
pub mod submod;
//- /module/m2.rs
pub mod submod;
//- /module/submod.rs
pub struct Baz;
"###,
//- /module/submod.rs
pub struct Baz;
"#,
expect![[r#"
crate
module: t
crate::module
submod: t
crate::module::submod
Baz: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮module: t
⋮crate::module
⋮submod: t
⋮crate::module::submod
⋮Baz: t v
"###);
}
#[test]
fn nested_out_of_line_module() {
let map = def_map(
r###"
//- /lib.rs
mod a {
mod b {
mod c;
}
}
check(
r#"
//- /lib.rs
mod a {
mod b {
mod c;
}
}
//- /a/b/c.rs
struct X;
"###,
//- /a/b/c.rs
struct X;
"#,
expect![[r#"
crate
a: t
crate::a
b: t
crate::a::b
c: t
crate::a::b::c
X: t v
"#]],
);
assert_snapshot!(map, @r###"
⋮crate
⋮a: t
⋮crate::a
⋮b: t
⋮crate::a::b
⋮c: t
⋮crate::a::b::c
⋮X: t v
"###);
}
#[test]
fn nested_out_of_line_module_with_path() {
let map = def_map(
r###"
//- /lib.rs
mod a {
#[path = "d/e"]
mod b {
mod c;
}
}
//- /a/d/e/c.rs
struct X;
"###,
);
assert_snapshot!(map, @r###"
⋮crate
⋮a: t
⋮crate::a
⋮b: t
⋮crate::a::b
⋮c: t
⋮crate::a::b::c
⋮X: t v
"###);
check(
r#"
//- /lib.rs
mod a {
#[path = "d/e"]
mod b {
mod c;
}
}
//- /a/d/e/c.rs
struct X;
"#,
expect![[r#"
crate
a: t
crate::a
b: t
crate::a::b
c: t
crate::a::b::c
X: t v
"#]],
);
}
@@ -2,23 +2,22 @@
#[test]
fn primitive_reexport() {
let map = def_map(
"
//- /lib.rs
mod foo;
use foo::int;
check(
r#"
//- /lib.rs
mod foo;
use foo::int;
//- /foo.rs
pub use i32 as int;
",
);
assert_snapshot!(map, @r###"
⋮crate
⋮foo: t
⋮int: t
⋮crate::foo
⋮int: t
"###
//- /foo.rs
pub use i32 as int;
"#,
expect![[r#"
crate
foo: t
int: t
crate::foo
int: t
"#]],
);
}
@@ -418,3 +418,74 @@ pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) ->
}
}
}
#[cfg(test)]
mod tests {
use expect::expect;
use crate::{mock_analysis::single_file, Query};
#[test]
fn test_nav_for_symbol() {
let (analysis, _) = single_file(
r#"
enum FooInner { }
fn foo() { enum FooInner { } }
"#,
);
let navs = analysis.symbol_search(Query::new("FooInner".to_string())).unwrap();
expect![[r#"
[
NavigationTarget {
file_id: FileId(
1,
),
full_range: 0..17,
focus_range: Some(
5..13,
),
name: "FooInner",
kind: ENUM_DEF,
container_name: None,
description: Some(
"enum FooInner",
),
docs: None,
},
NavigationTarget {
file_id: FileId(
1,
),
full_range: 29..46,
focus_range: Some(
34..42,
),
name: "FooInner",
kind: ENUM_DEF,
container_name: Some(
"foo",
),
description: Some(
"enum FooInner",
),
docs: None,
},
]
"#]]
.assert_debug_eq(&navs);
}
#[test]
fn test_world_symbols_are_case_sensitive() {
let (analysis, _) = single_file(
r#"
fn foo() {}
struct Foo;
"#,
);
let navs = analysis.symbol_search(Query::new("foo".to_string())).unwrap();
assert_eq!(navs.len(), 2)
}
}
-74
View File
@@ -526,77 +526,3 @@ fn analysis_is_send() {
fn is_send<T: Send>() {}
is_send::<Analysis>();
}
#[cfg(test)]
mod tests {
use crate::{display::NavigationTarget, mock_analysis::single_file, Query};
use ra_syntax::{
SmolStr,
SyntaxKind::{FN_DEF, STRUCT_DEF},
};
#[test]
fn test_world_symbols_with_no_container() {
let code = r#"
enum FooInner { }
"#;
let mut symbols = get_symbols_matching(code, "FooInner");
let s = symbols.pop().unwrap();
assert_eq!(s.name, "FooInner");
assert!(s.container_name.is_none());
}
#[test]
fn test_world_symbols_include_container_name() {
let code = r#"
fn foo() {
enum FooInner { }
}
"#;
let mut symbols = get_symbols_matching(code, "FooInner");
let s = symbols.pop().unwrap();
assert_eq!(s.name, "FooInner");
assert_eq!(s.container_name, Some(SmolStr::new("foo")));
let code = r#"
mod foo {
struct FooInner;
}
"#;
let mut symbols = get_symbols_matching(code, "FooInner");
let s = symbols.pop().unwrap();
assert_eq!(s.name, "FooInner");
assert_eq!(s.container_name, Some(SmolStr::new("foo")));
}
#[test]
fn test_world_symbols_are_case_sensitive() {
let code = r#"
fn foo() {}
struct Foo;
"#;
let symbols = get_symbols_matching(code, "Foo");
let fn_match = symbols.iter().find(|s| s.name == "foo").map(|s| s.kind);
let struct_match = symbols.iter().find(|s| s.name == "Foo").map(|s| s.kind);
assert_eq!(fn_match, Some(FN_DEF));
assert_eq!(struct_match, Some(STRUCT_DEF));
}
fn get_symbols_matching(text: &str, query: &str) -> Vec<NavigationTarget> {
let (analysis, _) = single_file(text);
analysis.symbol_search(Query::new(query.into())).unwrap()
}
}