diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs new file mode 100644 index 000000000..3bba08cfc --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs @@ -0,0 +1,397 @@ +use super::*; +use expect_test::expect; + +#[test] +fn inner_item_smoke() { + check_at( + r#" +struct inner {} +fn outer() { + $0 + fn inner() {} +} +"#, + expect![[r#" + block scope + inner: v + + crate + inner: t + outer: v + "#]], + ); +} + +#[test] +fn use_from_crate() { + check_at( + r#" +struct Struct {} +fn outer() { + fn Struct() {} + use Struct as PlainStruct; + use crate::Struct as CrateStruct; + use self::Struct as SelfStruct; + use super::Struct as SuperStruct; + $0 +} +"#, + expect![[r#" + block scope + CrateStruct: t + PlainStruct: t v + SelfStruct: t + Struct: v + SuperStruct: _ + + crate + Struct: t + outer: v + "#]], + ); +} + +#[test] +fn merge_namespaces() { + check_at( + r#" +struct name {} +fn outer() { + fn name() {} + + use name as imported; // should import both `name`s + + $0 +} +"#, + expect![[r#" + block scope + imported: t v + name: v + + crate + name: t + outer: v + "#]], + ); +} + +#[test] +fn nested_blocks() { + check_at( + r#" +fn outer() { + struct inner1 {} + fn inner() { + use inner1; + use outer; + fn inner2() {} + $0 + } +} +"#, + expect![[r#" + block scope + inner1: t + inner2: v + outer: v + + block scope + inner: v + inner1: t + + crate + outer: v + "#]], + ); +} + +#[test] +fn super_imports() { + check_at( + r#" +mod module { + fn f() { + use super::Struct; + $0 + } +} + +struct Struct {} +"#, + expect![[r#" + block scope + Struct: t + + crate + Struct: t + module: t + + crate::module + f: v + "#]], + ); +} + +#[test] +fn nested_module_scoping() { + check_block_scopes_at( + r#" +fn f() { + mod module { + struct Struct {} + fn f() { + use self::Struct; + $0 + } + } +} + "#, + expect![[r#" + BlockId(1) in ModuleId { krate: CrateId(0), block: Some(BlockId(0)), local_id: Idx::<ModuleData>(1) } + BlockId(0) in ModuleId { krate: CrateId(0), block: None, local_id: Idx::<ModuleData>(0) } + crate scope + "#]], + ); +} + +#[test] +fn legacy_macro_items() { + // Checks that legacy-scoped `macro_rules!` from parent namespaces are resolved and expanded + // correctly. + check_at( + r#" +macro_rules! mark { + () => { + struct Hit {} + } +} + +fn f() { + mark!(); + $0 +} +"#, + expect![[r#" + block scope + Hit: t + + crate + f: v + "#]], + ); +} + +#[test] +fn macro_resolve() { + check_at( + r#" +//- /lib.rs crate:lib deps:core +use core::cov_mark; + +fn f() { + fn nested() { + cov_mark::mark!(Hit); + $0 + } +} +//- /core.rs crate:core +pub mod cov_mark { + #[macro_export] + macro_rules! _mark { + ($name:ident) => { + struct $name {} + } + } + + pub use crate::_mark as mark; +} +"#, + expect![[r#" + block scope + Hit: t + + block scope + nested: v + + crate + cov_mark: t + f: v + "#]], + ); +} + +#[test] +fn macro_resolve_legacy() { + check_at( + r#" +//- /lib.rs +mod module; + +//- /module.rs +macro_rules! m { + () => { + struct Def {} + }; +} + +fn f() { + { + m!(); + $0 + } +} + "#, + expect![[r#" + block scope + Def: t + + crate + module: t + + crate::module + f: v + "#]], + ) +} + +#[test] +fn super_does_not_resolve_to_block_module() { + check_at( + r#" +fn main() { + struct Struct {} + mod module { + use super::Struct; + + $0 + } +} + "#, + expect![[r#" + block scope + Struct: t + module: t + + block scope::module + Struct: _ + + crate + main: v + "#]], + ); +} + +#[test] +fn underscore_import() { + // This used to panic, because the default (private) visibility inside block expressions would + // point into the containing `DefMap`, which visibilities should never be able to do. + cov_mark::check!(adjust_vis_in_block_def_map); + check_at( + r#" +mod m { + fn main() { + use Tr as _; + trait Tr {} + $0 + } +} + "#, + expect![[r#" + block scope + _: t + Tr: t + + crate + m: t + + crate::m + main: v + "#]], + ); +} + +#[test] +fn nested_macro_item_decl() { + cov_mark::check!(macro_call_in_macro_stmts_is_added_to_item_tree); + check_at( + r#" +macro_rules! inner_declare { + ($ident:ident) => { + static $ident: u32 = 0; + }; +} +macro_rules! declare { + ($ident:ident) => { + inner_declare!($ident); + }; +} + +fn foo() { + declare!(bar); + bar; + $0 +} + "#, + expect![[r#" + block scope + bar: v + + crate + foo: v + "#]], + ) +} + +#[test] +fn is_visible_from_same_def_map() { + // Regression test for https://github.com/rust-lang/rust-analyzer/issues/9481 + cov_mark::check!(is_visible_from_same_block_def_map); + check_at( + r#" +fn outer() { + mod tests { + use super::*; + } + use crate::name; + $0 +} + "#, + expect![[r#" + block scope + name: _ + tests: t + + block scope::tests + name: _ + outer: v + + crate + outer: v + "#]], + ); +} + +#[test] +fn stmt_macro_expansion_with_trailing_expr() { + cov_mark::check!(macro_stmt_with_trailing_macro_expr); + check_at( + r#" +macro_rules! mac { + () => { mac!($) }; + ($x:tt) => { fn inner() {} }; +} +fn foo() { + mac!(); + $0 +} + "#, + expect![[r#" + block scope + inner: v + + crate + foo: v + "#]], + ) +} |