summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs933
1 files changed, 933 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
new file mode 100644
index 000000000..70dd2eb3a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
@@ -0,0 +1,933 @@
+mod globs;
+mod incremental;
+mod macros;
+mod mod_resolution;
+mod primitives;
+
+use std::sync::Arc;
+
+use base_db::{fixture::WithFixture, SourceDatabase};
+use expect_test::{expect, Expect};
+
+use crate::{db::DefDatabase, test_db::TestDB};
+
+use super::DefMap;
+
+fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> {
+ let db = TestDB::with_files(ra_fixture);
+ let krate = db.crate_graph().iter().next().unwrap();
+ db.crate_def_map(krate)
+}
+
+fn render_crate_def_map(ra_fixture: &str) -> String {
+ let db = TestDB::with_files(ra_fixture);
+ let krate = db.crate_graph().iter().next().unwrap();
+ db.crate_def_map(krate).dump(&db)
+}
+
+fn check(ra_fixture: &str, expect: Expect) {
+ let actual = render_crate_def_map(ra_fixture);
+ expect.assert_eq(&actual);
+}
+
+#[test]
+fn crate_def_map_smoke_test() {
+ 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/bar.rs
+pub struct Baz;
+
+union U { to_be: bool, not_to_be: u8 }
+enum E { V }
+
+extern {
+ type Ext;
+ static EXT: u8;
+ fn ext();
+}
+"#,
+ expect![[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
+ Ext: t
+ U: t
+ ext: v
+ "#]],
+ );
+}
+
+#[test]
+fn crate_def_map_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
+ "#]],
+ );
+}
+
+#[test]
+fn crate_def_map_fn_mod_same_name() {
+ check(
+ r#"
+mod m {
+ pub mod z {}
+ pub fn z() {}
+}
+"#,
+ expect![[r#"
+ crate
+ m: t
+
+ crate::m
+ z: t v
+
+ crate::m::z
+ "#]],
+ );
+}
+
+#[test]
+fn bogus_paths() {
+ cov_mark::check!(bogus_paths);
+ check(
+ r#"
+//- /lib.rs
+mod foo;
+struct S;
+use self;
+
+//- /foo/mod.rs
+use super;
+use crate;
+"#,
+ expect![[r#"
+ crate
+ S: t v
+ foo: t
+
+ crate::foo
+ "#]],
+ );
+}
+
+#[test]
+fn use_as() {
+ check(
+ r#"
+//- /lib.rs
+mod foo;
+use crate::foo::Baz as Foo;
+
+//- /foo/mod.rs
+pub struct Baz;
+"#,
+ expect![[r#"
+ crate
+ Foo: t v
+ foo: t
+
+ crate::foo
+ Baz: t v
+ "#]],
+ );
+}
+
+#[test]
+fn use_trees() {
+ check(
+ r#"
+//- /lib.rs
+mod foo;
+use crate::foo::bar::{Baz, Quux};
+
+//- /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
+
+ crate::foo
+ bar: t
+
+ crate::foo::bar
+ Baz: t v
+ Quux: t
+ "#]],
+ );
+}
+
+#[test]
+fn re_exports() {
+ check(
+ r#"
+//- /lib.rs
+mod foo;
+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: t v
+ foo: t
+
+ crate::foo
+ Baz: t v
+ bar: t
+
+ crate::foo::bar
+ Baz: t v
+ "#]],
+ );
+}
+
+#[test]
+fn std_prelude() {
+ cov_mark::check!(std_prelude);
+ check(
+ r#"
+//- /main.rs crate:main deps:test_crate
+#[prelude_import]
+use ::test_crate::prelude::*;
+
+use Foo::*;
+
+//- /lib.rs crate:test_crate
+pub mod prelude;
+
+//- /prelude.rs
+pub enum Foo { Bar, Baz }
+"#,
+ expect![[r#"
+ crate
+ Bar: t v
+ Baz: t v
+ "#]],
+ );
+}
+
+#[test]
+fn can_import_enum_variant() {
+ cov_mark::check!(can_import_enum_variant);
+ check(
+ r#"
+enum E { V }
+use self::E::V;
+"#,
+ expect![[r#"
+ crate
+ E: t
+ V: t v
+ "#]],
+ );
+}
+
+#[test]
+fn edition_2015_imports() {
+ check(
+ r#"
+//- /main.rs crate:main deps:other_crate edition:2015
+mod foo;
+mod bar;
+
+//- /bar.rs
+struct Bar;
+
+//- /foo.rs
+use bar::Bar;
+use other_crate::FromLib;
+
+//- /lib.rs crate:other_crate edition:2018
+pub struct FromLib;
+"#,
+ expect![[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() {
+ 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
+ foo: t
+
+ crate::foo
+ bar: t
+
+ crate::foo::bar
+ Baz: t v
+ "#]],
+ );
+}
+
+#[test]
+fn item_map_across_crates() {
+ check(
+ r#"
+//- /main.rs crate:main deps:test_crate
+use test_crate::Baz;
+
+//- /lib.rs crate:test_crate
+pub struct Baz;
+"#,
+ expect![[r#"
+ crate
+ Baz: t v
+ "#]],
+ );
+}
+
+#[test]
+fn extern_crate_rename() {
+ check(
+ r#"
+//- /main.rs crate:main deps:alloc
+extern crate alloc as alloc_crate;
+mod alloc;
+mod sync;
+
+//- /sync.rs
+use alloc_crate::Arc;
+
+//- /lib.rs crate:alloc
+pub struct Arc;
+"#,
+ expect![[r#"
+ crate
+ alloc: t
+ alloc_crate: t
+ sync: t
+
+ crate::alloc
+
+ crate::sync
+ Arc: t v
+ "#]],
+ );
+}
+
+#[test]
+fn extern_crate_rename_2015_edition() {
+ check(
+ r#"
+//- /main.rs crate:main deps:alloc edition:2015
+extern crate alloc as alloc_crate;
+mod alloc;
+mod sync;
+
+//- /sync.rs
+use alloc_crate::Arc;
+
+//- /lib.rs crate:alloc
+pub struct Arc;
+"#,
+ expect![[r#"
+ crate
+ alloc: t
+ alloc_crate: t
+ sync: t
+
+ crate::alloc
+
+ crate::sync
+ Arc: t v
+ "#]],
+ );
+}
+
+#[test]
+fn macro_use_extern_crate_self() {
+ cov_mark::check!(ignore_macro_use_extern_crate_self);
+ check(
+ r#"
+//- /main.rs crate:main
+#[macro_use]
+extern crate self as bla;
+"#,
+ expect![[r#"
+ crate
+ bla: t
+ "#]],
+ );
+}
+
+#[test]
+fn reexport_across_crates() {
+ check(
+ r#"
+//- /main.rs crate:main deps:test_crate
+use test_crate::Baz;
+
+//- /lib.rs crate:test_crate
+pub use foo::Baz;
+mod foo;
+
+//- /foo.rs
+pub struct Baz;
+"#,
+ expect![[r#"
+ crate
+ Baz: t v
+ "#]],
+ );
+}
+
+#[test]
+fn values_dont_shadow_extern_crates() {
+ check(
+ r#"
+//- /main.rs crate:main deps:foo
+fn foo() {}
+use foo::Bar;
+
+//- /foo/lib.rs crate:foo
+pub struct Bar;
+"#,
+ expect![[r#"
+ crate
+ Bar: t v
+ foo: v
+ "#]],
+ );
+}
+
+#[test]
+fn no_std_prelude() {
+ check(
+ r#"
+ //- /main.rs crate:main deps:core,std
+ #![cfg_attr(not(never), no_std)]
+ use Rust;
+
+ //- /core.rs crate:core
+ pub mod prelude {
+ pub mod rust_2018 {
+ pub struct Rust;
+ }
+ }
+ //- /std.rs crate:std deps:core
+ pub mod prelude {
+ pub mod rust_2018 {
+ }
+ }
+ "#,
+ expect![[r#"
+ crate
+ Rust: t v
+ "#]],
+ );
+}
+
+#[test]
+fn edition_specific_preludes() {
+ // We can't test the 2015 prelude here since you can't reexport its contents with 2015's
+ // absolute paths.
+
+ check(
+ r#"
+ //- /main.rs edition:2018 crate:main deps:std
+ use Rust2018;
+
+ //- /std.rs crate:std
+ pub mod prelude {
+ pub mod rust_2018 {
+ pub struct Rust2018;
+ }
+ }
+ "#,
+ expect![[r#"
+ crate
+ Rust2018: t v
+ "#]],
+ );
+ check(
+ r#"
+ //- /main.rs edition:2021 crate:main deps:std
+ use Rust2021;
+
+ //- /std.rs crate:std
+ pub mod prelude {
+ pub mod rust_2021 {
+ pub struct Rust2021;
+ }
+ }
+ "#,
+ expect![[r#"
+ crate
+ Rust2021: t v
+ "#]],
+ );
+}
+
+#[test]
+fn std_prelude_takes_precedence_above_core_prelude() {
+ check(
+ r#"
+//- /main.rs crate:main deps:core,std
+use {Foo, Bar};
+
+//- /std.rs crate:std deps:core
+pub mod prelude {
+ pub mod rust_2018 {
+ pub struct Foo;
+ pub use core::prelude::rust_2018::Bar;
+ }
+}
+
+//- /core.rs crate:core
+pub mod prelude {
+ pub mod rust_2018 {
+ pub struct Bar;
+ }
+}
+"#,
+ expect![[r#"
+ crate
+ Bar: t v
+ Foo: t v
+ "#]],
+ );
+}
+
+#[test]
+fn cfg_not_test() {
+ check(
+ r#"
+//- /main.rs crate:main deps:std
+use {Foo, Bar, Baz};
+
+//- /lib.rs crate:std
+pub mod prelude {
+ pub mod rust_2018 {
+ #[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: _
+ "#]],
+ );
+}
+
+#[test]
+fn cfg_test() {
+ check(
+ r#"
+//- /main.rs crate:main deps:std
+use {Foo, Bar, Baz};
+
+//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
+pub mod prelude {
+ pub mod rust_2018 {
+ #[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
+ "#]],
+ );
+}
+
+#[test]
+fn infer_multiple_namespace() {
+ check(
+ r#"
+//- /main.rs
+mod a {
+ pub type T = ();
+ pub use crate::b::*;
+}
+
+use crate::a::T;
+
+mod b {
+ pub const T: () = ();
+}
+"#,
+ expect![[r#"
+ crate
+ T: t v
+ a: t
+ b: t
+
+ crate::a
+ T: t v
+
+ crate::b
+ T: v
+ "#]],
+ );
+}
+
+#[test]
+fn underscore_import() {
+ check(
+ r#"
+//- /main.rs
+use tr::Tr as _;
+use tr::Tr2 as _;
+
+mod tr {
+ pub trait Tr {}
+ pub trait Tr2 {}
+}
+ "#,
+ expect![[r#"
+ crate
+ _: t
+ _: t
+ tr: t
+
+ crate::tr
+ Tr: t
+ Tr2: t
+ "#]],
+ );
+}
+
+#[test]
+fn underscore_reexport() {
+ check(
+ r#"
+//- /main.rs
+mod tr {
+ pub trait PubTr {}
+ pub trait PrivTr {}
+}
+mod reex {
+ use crate::tr::PrivTr as _;
+ pub use crate::tr::PubTr as _;
+}
+use crate::reex::*;
+ "#,
+ expect![[r#"
+ crate
+ _: t
+ reex: t
+ tr: t
+
+ crate::reex
+ _: t
+ _: t
+
+ crate::tr
+ PrivTr: t
+ PubTr: t
+ "#]],
+ );
+}
+
+#[test]
+fn underscore_pub_crate_reexport() {
+ cov_mark::check!(upgrade_underscore_visibility);
+ check(
+ r#"
+//- /main.rs crate:main deps:lib
+use lib::*;
+
+//- /lib.rs crate:lib
+use tr::Tr as _;
+pub use tr::Tr as _;
+
+mod tr {
+ pub trait Tr {}
+}
+ "#,
+ expect![[r#"
+ crate
+ _: t
+ "#]],
+ );
+}
+
+#[test]
+fn underscore_nontrait() {
+ check(
+ r#"
+//- /main.rs
+mod m {
+ pub struct Struct;
+ pub enum Enum {}
+ pub const CONST: () = ();
+}
+use crate::m::{Struct as _, Enum as _, CONST as _};
+ "#,
+ expect![[r#"
+ crate
+ m: t
+
+ crate::m
+ CONST: v
+ Enum: t
+ Struct: t v
+ "#]],
+ );
+}
+
+#[test]
+fn underscore_name_conflict() {
+ check(
+ r#"
+//- /main.rs
+struct Tr;
+
+use tr::Tr as _;
+
+mod tr {
+ pub trait Tr {}
+}
+ "#,
+ expect![[r#"
+ crate
+ _: t
+ Tr: t v
+ tr: t
+
+ crate::tr
+ Tr: t
+ "#]],
+ );
+}
+
+#[test]
+fn cfg_the_entire_crate() {
+ check(
+ r#"
+//- /main.rs
+#![cfg(never)]
+
+pub struct S;
+pub enum E {}
+pub fn f() {}
+ "#,
+ expect![[r#"
+ crate
+ "#]],
+ );
+}
+
+#[test]
+fn use_crate_as() {
+ check(
+ r#"
+use crate as foo;
+
+use foo::bar as baz;
+
+fn bar() {}
+ "#,
+ expect![[r#"
+ crate
+ bar: v
+ baz: v
+ foo: t
+ "#]],
+ );
+}
+
+#[test]
+fn self_imports_only_types() {
+ check(
+ r#"
+//- /main.rs
+mod m {
+ pub macro S() {}
+ pub struct S;
+}
+
+use self::m::S::{self};
+ "#,
+ expect![[r#"
+ crate
+ S: t
+ m: t
+
+ crate::m
+ S: t v m
+ "#]],
+ );
+}
+
+#[test]
+fn import_from_extern_crate_only_imports_public_items() {
+ check(
+ r#"
+//- /lib.rs crate:lib deps:settings,macros
+use macros::settings;
+use settings::Settings;
+//- /settings.rs crate:settings
+pub struct Settings;
+//- /macros.rs crate:macros
+mod settings {}
+pub const settings: () = ();
+ "#,
+ expect![[r#"
+ crate
+ Settings: t v
+ settings: v
+ "#]],
+ )
+}
+
+#[test]
+fn non_prelude_deps() {
+ check(
+ r#"
+//- /lib.rs crate:lib deps:dep extern-prelude:
+use dep::Struct;
+//- /dep.rs crate:dep
+pub struct Struct;
+ "#,
+ expect![[r#"
+ crate
+ Struct: _
+ "#]],
+ );
+ check(
+ r#"
+//- /lib.rs crate:lib deps:dep extern-prelude:
+extern crate dep;
+use dep::Struct;
+//- /dep.rs crate:dep
+pub struct Struct;
+ "#,
+ expect![[r#"
+ crate
+ Struct: t v
+ dep: t
+ "#]],
+ );
+}
+
+#[test]
+fn braced_supers_in_use_tree() {
+ cov_mark::check!(concat_super_mod_paths);
+ check(
+ r#"
+mod some_module {
+ pub fn unknown_func() {}
+}
+
+mod other_module {
+ mod some_submodule {
+ use { super::{ super::unknown_func, }, };
+ }
+}
+
+use some_module::unknown_func;
+ "#,
+ expect![[r#"
+ crate
+ other_module: t
+ some_module: t
+ unknown_func: v
+
+ crate::other_module
+ some_submodule: t
+
+ crate::other_module::some_submodule
+ unknown_func: v
+
+ crate::some_module
+ unknown_func: v
+ "#]],
+ )
+}