rust-analyzer/crates/hir_def/src/nameres/tests/mod_resolution.rs
2020-12-08 13:47:58 +01:00

821 lines
12 KiB
Rust

use super::*;
#[test]
fn name_res_works_for_broken_modules() {
mark::check!(name_res_works_for_broken_modules);
check(
r"
//- /lib.rs
mod foo // no `;`, no body
use self::foo::Baz;
//- /foo/mod.rs
pub mod bar;
pub use self::bar::Baz;
//- /foo/bar.rs
pub struct Baz;
",
expect![[r#"
crate
Baz: _
foo: t
crate::foo
"#]],
);
}
#[test]
fn nested_module_resolution() {
check(
r#"
//- /lib.rs
mod n1;
//- /n1.rs
mod n2;
//- /n1/n2.rs
struct X;
"#,
expect![[r#"
crate
n1: t
crate::n1
n2: t
crate::n1::n2
X: t v
"#]],
);
}
#[test]
fn nested_module_resolution_2() {
check(
r#"
//- /lib.rs
mod prelude;
mod iter;
//- /prelude.rs
pub use crate::iter::Iterator;
//- /iter.rs
pub use self::traits::Iterator;
mod traits;
//- /iter/traits.rs
pub use self::iterator::Iterator;
mod 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
"#]],
);
}
#[test]
fn module_resolution_works_for_non_standard_filenames() {
check(
r#"
//- /my_library.rs crate:my_library
mod foo;
use self::foo::Bar;
//- /foo/mod.rs
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
foo: t
crate::foo
Bar: t v
"#]],
);
}
#[test]
fn module_resolution_works_for_raw_modules() {
check(
r#"
//- /lib.rs
mod r#async;
use self::r#async::Bar;
//- /async.rs
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
async: t
crate::async
Bar: t v
"#]],
);
}
#[test]
fn module_resolution_decl_path() {
check(
r#"
//- /lib.rs
#[path = "bar/baz/foo.rs"]
mod foo;
use self::foo::Bar;
//- /bar/baz/foo.rs
pub struct Bar;
"#,
expect![[r#"
crate
Bar: t v
foo: t
crate::foo
Bar: t v
"#]],
);
}
#[test]
fn module_resolution_module_with_path_in_mod_rs() {
check(
r#"
//- /main.rs
mod foo;
//- /foo/mod.rs
#[path = "baz.rs"]
pub mod bar;
use self::bar::Baz;
//- /foo/baz.rs
pub struct Baz;
"#,
expect![[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() {
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
#[path = "baz.rs"]
pub mod bar;
use self::bar::Baz;
//- /baz.rs
pub struct Baz;
"#,
expect![[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() {
check(
r#"
//- /main.rs
#[path = "bar/baz/module.rs"]
mod foo;
pub struct Baz;
//- /bar/baz/module.rs
use super::Baz;
"#,
expect![[r#"
crate
Baz: t v
foo: t
crate::foo
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_explicit_path_mod_rs() {
check(
r#"
//- /main.rs
#[path = "module/mod.rs"]
mod foo;
//- /module/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_relative_path() {
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
#[path = "./sub.rs"]
pub mod foo_bar;
//- /sub.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
foo_bar: t
crate::foo::foo_bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_relative_path_2() {
check(
r#"
//- /main.rs
mod foo;
//- /foo/mod.rs
#[path="../sub.rs"]
pub mod foo_bar;
//- /sub.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
foo_bar: t
crate::foo::foo_bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_relative_path_outside_root() {
check(
r#"
//- /a/b/c/d/e/main.rs crate:main
#[path="../../../../../outside.rs"]
mod foo;
//- /outside.rs
mod bar;
//- /bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_explicit_path_mod_rs_2() {
check(
r#"
//- /main.rs
#[path = "module/bar/mod.rs"]
mod foo;
//- /module/bar/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_explicit_path_mod_rs_with_win_separator() {
check(
r#"
//- /main.rs
#[path = r"module\bar\mod.rs"]
mod foo;
//- /module/bar/mod.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_with_path_attribute() {
check(
r#"
//- /main.rs
#[path = "models"]
mod foo { mod bar; }
//- /models/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module() {
check(
r#"
//- /main.rs
mod foo { mod bar; }
//- /foo/bar.rs
pub struct Baz;
"#,
expect![[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() {
check(
r#"
//- /main.rs
#[path = "models/db"]
mod foo { mod bar; }
//- /models/db/bar.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_3() {
check(
r#"
//- /main.rs
#[path = "models/db"]
mod foo {
#[path = "users.rs"]
mod bar;
}
//- /models/db/users.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_empty_path() {
check(
r#"
//- /main.rs
#[path = ""]
mod foo {
#[path = "users.rs"]
mod bar;
}
//- /users.rs
pub struct Baz;
"#,
expect![[r#"
crate
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"#]],
);
}
#[test]
fn module_resolution_decl_empty_path() {
check(
r#"
//- /main.rs
#[path = ""] // Should try to read `/` (a directory)
mod foo;
//- /foo.rs
pub struct Baz;
"#,
expect![[r#"
crate
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_relative_path() {
check(
r#"
//- /main.rs
#[path = "./models"]
mod foo { mod bar; }
//- /models/bar.rs
pub struct Baz;
"#,
expect![[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() {
check(
r#"
//- /main.rs
mod foo {
#[path = "baz.rs"]
mod bar;
}
use self::foo::bar::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
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_mod_rs() {
check(
r#"
//- /main.rs
mod foo;
//- /foo/mod.rs
mod bar {
#[path = "qwe.rs"]
pub mod baz;
}
use self::bar::baz::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
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
mod bar {
#[path = "qwe.rs"]
pub mod baz;
}
use self::bar::baz::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
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
check(
r#"
//- /main.rs
mod foo;
//- /foo.rs
#[path = "bar"]
mod bar {
pub mod baz;
}
use self::bar::baz::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
"#]],
);
}
#[test]
fn module_resolution_decl_inside_module_in_non_crate_root_2() {
check(
r#"
//- /main.rs
#[path="module/m2.rs"]
mod module;
//- /module/m2.rs
pub mod submod;
//- /module/submod.rs
pub struct Baz;
"#,
expect![[r#"
crate
module: t
crate::module
submod: t
crate::module::submod
Baz: t v
"#]],
);
}
#[test]
fn nested_out_of_line_module() {
check(
r#"
//- /lib.rs
mod a {
mod b {
mod c;
}
}
//- /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
"#]],
);
}
#[test]
fn nested_out_of_line_module_with_path() {
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
"#]],
);
}
#[test]
fn circular_mods() {
mark::check!(circular_mods);
compute_crate_def_map(
r#"
//- /lib.rs
mod foo;
//- /foo.rs
#[path = "./foo.rs"]
mod foo;
"#,
);
compute_crate_def_map(
r#"
//- /lib.rs
mod foo;
//- /foo.rs
#[path = "./bar.rs"]
mod bar;
//- /bar.rs
#[path = "./foo.rs"]
mod foo;
"#,
);
}
#[test]
fn abs_path_ignores_local() {
check(
r#"
//- /main.rs crate:main deps:core
pub use ::core::hash::Hash;
pub mod core {}
//- /lib.rs crate:core
pub mod hash { pub trait Hash {} }
"#,
expect![[r#"
crate
Hash: t
core: t
crate::core
"#]],
);
}