mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-10 12:18:49 +00:00
821 lines
12 KiB
Rust
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
|
|
"#]],
|
|
);
|
|
}
|