use super::*;
#[test]
fn name_res_works_for_broken_modules() {
cov_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 : type
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 : type
crate::n1
- n2 : type
crate::n1::n2
- X : type value
"#]],
);
}
#[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 : type
- prelude : type
crate::iter
- Iterator : type (import)
- traits : type
crate::iter::traits
- Iterator : type (import)
- iterator : type
crate::iter::traits::iterator
- Iterator : type
crate::prelude
- Iterator : type (import)
"#]],
);
}
#[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 : type (import) value (import)
- foo : type
crate::foo
- Bar : type value
"#]],
);
}
#[test]
fn module_resolution_works_for_raw_modules() {
check(
r#"
//- /lib.rs
mod r#async;
use self::r#async::Bar;
//- /async.rs
mod foo;
mod r#async;
pub struct Bar;
//- /async/foo.rs
pub struct Foo;
//- /async/async.rs
pub struct Baz;
"#,
expect![[r#"
crate
- Bar : type (import) value (import)
- r#async : type
crate::r#async
- Bar : type value
- r#async : type
- foo : type
crate::r#async::r#async
- Baz : type value
crate::r#async::foo
- Foo : type value
"#]],
);
}
#[test]
fn module_resolution_works_for_inline_raw_modules() {
check(
r#"
//- /lib.rs
mod r#async {
pub mod a;
pub mod r#async;
}
use self::r#async::a::Foo;
use self::r#async::r#async::Bar;
//- /async/a.rs
pub struct Foo;
//- /async/async.rs
pub struct Bar;
"#,
expect![[r#"
crate
- Bar : type (import) value (import)
- Foo : type (import) value (import)
- r#async : type
crate::r#async
- a : type
- r#async : type
crate::r#async::a
- Foo : type value
crate::r#async::r#async
- Bar : type value
"#]],
);
}
#[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 : type (import) value (import)
- foo : type
crate::foo
- Bar : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type (import) value (import)
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type (import) value (import)
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type value
- foo : type
crate::foo
- Baz : type (import) value (import)
"#]],
);
}
#[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 : type
crate::foo
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- foo_bar : type
crate::foo::foo_bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- foo_bar : type
crate::foo::foo_bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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
- foo : type
crate::foo
"#]],
);
}
#[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 : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[test]
fn module_resolution_decl_inside_inline_module_in_crate_root() {
check(
r#"
//- /main.rs
mod foo {
#[path = "baz.rs"]
pub mod bar;
}
use self::foo::bar::Baz;
//- /foo/baz.rs
pub struct Baz;
"#,
expect![[r#"
crate
- Baz : type (import) value (import)
- foo : type
crate::foo
- bar : type
crate::foo::bar
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type (import) value (import)
- bar : type
crate::foo::bar
- baz : type
crate::foo::bar::baz
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type (import) value (import)
- bar : type
crate::foo::bar
- baz : type
crate::foo::bar::baz
- Baz : type value
"#]],
);
}
#[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 : type
crate::foo
- Baz : type (import) value (import)
- bar : type
crate::foo::bar
- baz : type
crate::foo::bar::baz
- Baz : type value
"#]],
);
}
#[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 : type
crate::module
- submod : type
crate::module::submod
- Baz : type value
"#]],
);
}
#[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 : type
crate::a
- b : type
crate::a::b
- c : type
crate::a::b::c
- X : type value
"#]],
);
}
#[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 : type
crate::a
- b : type
crate::a::b
- c : type
crate::a::b::c
- X : type value
"#]],
);
}
#[test]
fn circular_mods() {
cov_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 : type (import)
- core : type
crate::core
"#]],
);
}
#[test]
fn cfg_in_module_file() {
// Inner `#![cfg]` in a module file makes the whole module disappear.
check(
r#"
//- /main.rs
mod module;
//- /module.rs
#![cfg(NEVER)]
struct AlsoShouldNotAppear;
"#,
expect![[r#"
crate
"#]],
)
}
#[test]
fn invalid_imports() {
check(
r#"
//- /main.rs
mod module;
use self::module::S::new;
use self::module::unresolved;
use self::module::C::const_based;
use self::module::Enum::Variant::NoAssoc;
//- /module.rs
pub struct S;
impl S {
pub fn new() {}
}
pub const C: () = ();
pub enum Enum {
Variant,
}
"#,
expect![[r#"
crate
- NoAssoc : _
- const_based : _
- module : type
- new : _
- unresolved : _
crate::module
- C : value
- Enum : type
- S : type value
"#]],
);
}
#[test]
fn trait_item_imports_same_crate() {
check(
r#"
//- /main.rs
mod module;
use self::module::Trait::{AssocType, ASSOC_CONST, MACRO_CONST, method};
//- /module.rs
macro_rules! m {
($name:ident) => { const $name: () = (); };
}
pub trait Trait {
type AssocType;
const ASSOC_CONST: ();
fn method(&self);
m!(MACRO_CONST);
}
"#,
expect![[r#"
crate
- ASSOC_CONST : _
- AssocType : _
- MACRO_CONST : _
- method : _
- module : type
crate::module
- Trait : type
- (legacy) m : macro!
"#]],
);
check(
r#"
//- /main.rs
mod module;
use self::module::Trait::*;
//- /module.rs
macro_rules! m {
($name:ident) => { const $name: () = (); };
}
pub trait Trait {
type AssocType;
const ASSOC_CONST: ();
fn method(&self);
m!(MACRO_CONST);
}
"#,
expect![[r#"
crate
- module : type
crate::module
- Trait : type
- (legacy) m : macro!
"#]],
);
}
#[test]
fn trait_item_imports_differing_crate() {
check(
r#"
//- /main.rs deps:lib crate:main
use lib::Trait::{AssocType, ASSOC_CONST, MACRO_CONST, method};
//- /lib.rs crate:lib
macro_rules! m {
($name:ident) => { const $name: () = (); };
}
pub trait Trait {
type AssocType;
const ASSOC_CONST: ();
fn method(&self);
m!(MACRO_CONST);
}
"#,
expect![[r#"
crate
- ASSOC_CONST : _
- AssocType : _
- MACRO_CONST : _
- method : _
"#]],
);
check(
r#"
//- /main.rs deps:lib crate:main
use lib::Trait::*;
//- /lib.rs crate:lib
macro_rules! m {
($name:ident) => { const $name: () = (); };
}
pub trait Trait {
type AssocType;
const ASSOC_CONST: ();
fn method(&self);
m!(MACRO_CONST);
}
"#,
expect![[r#"
crate
"#]],
);
}