From dab7f3d2c6cd035f446fbdcda2442954da4afd3a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 8 Jul 2020 19:09:42 +0200 Subject: Remove relative_path dependency --- crates/ra_hir_def/src/nameres/mod_resolution.rs | 116 ++++++++++++++++++------ 1 file changed, 87 insertions(+), 29 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/mod_resolution.rs b/crates/ra_hir_def/src/nameres/mod_resolution.rs index 39e9a6d97..953961632 100644 --- a/crates/ra_hir_def/src/nameres/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/mod_resolution.rs @@ -1,23 +1,24 @@ //! This module resolves `mod foo;` declaration to file. use hir_expand::name::Name; -use ra_db::{FileId, RelativePathBuf}; +use ra_db::FileId; use ra_syntax::SmolStr; use crate::{db::DefDatabase, HirFileId}; #[derive(Clone, Debug)] pub(super) struct ModDir { - /// `.` for `mod.rs`, `lib.rs` - /// `./foo` for `foo.rs` - /// `./foo/bar` for `mod bar { mod x; }` nested in `foo.rs` - path: RelativePathBuf, + /// `` for `mod.rs`, `lib.rs` + /// `foo/` for `foo.rs` + /// `foo/bar/` for `mod bar { mod x; }` nested in `foo.rs` + /// Invariant: path.is_empty() || path.ends_with('/') + dir_path: DirPath, /// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/` root_non_dir_owner: bool, } impl ModDir { pub(super) fn root() -> ModDir { - ModDir { path: RelativePathBuf::default(), root_non_dir_owner: false } + ModDir { dir_path: DirPath::empty(), root_non_dir_owner: false } } pub(super) fn descend_into_definition( @@ -25,17 +26,21 @@ impl ModDir { name: &Name, attr_path: Option<&SmolStr>, ) -> ModDir { - let mut path = self.path.clone(); - match attr_to_path(attr_path) { - None => path.push(&name.to_string()), + let path = match attr_path.map(|it| it.as_str()) { + None => { + let mut path = self.dir_path.clone(); + path.push(&name.to_string()); + path + } Some(attr_path) => { - if self.root_non_dir_owner { - assert!(path.pop()); + let mut path = self.dir_path.join_attr(attr_path, self.root_non_dir_owner); + if !(path.is_empty() || path.ends_with('/')) { + path.push('/') } - path.push(attr_path); + DirPath::new(path) } - } - ModDir { path, root_non_dir_owner: false } + }; + ModDir { dir_path: path, root_non_dir_owner: false } } pub(super) fn resolve_declaration( @@ -48,34 +53,87 @@ impl ModDir { let file_id = file_id.original_file(db.upcast()); let mut candidate_files = Vec::new(); - match attr_to_path(attr_path) { + match attr_path { Some(attr_path) => { - let base = - if self.root_non_dir_owner { self.path.parent().unwrap() } else { &self.path }; - candidate_files.push(base.join(attr_path).to_string()) + candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner)) } None => { - candidate_files.push(self.path.join(&format!("{}.rs", name)).to_string()); - candidate_files.push(self.path.join(&format!("{}/mod.rs", name)).to_string()); + candidate_files.push(format!("{}{}.rs", self.dir_path.0, name)); + candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name)); } }; for candidate in candidate_files.iter() { if let Some(file_id) = db.resolve_path(file_id, candidate.as_str()) { - let mut root_non_dir_owner = false; - let mut mod_path = RelativePathBuf::new(); let is_mod_rs = candidate.ends_with("mod.rs"); - if !(is_mod_rs || attr_path.is_some()) { - root_non_dir_owner = true; - mod_path.push(&name.to_string()); - } - return Ok((file_id, is_mod_rs, ModDir { path: mod_path, root_non_dir_owner })); + + let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() { + (DirPath::empty(), false) + } else { + (DirPath::new(format!("{}/", name)), true) + }; + return Ok((file_id, is_mod_rs, ModDir { dir_path, root_non_dir_owner })); } } Err(candidate_files.remove(0)) } } -fn attr_to_path(attr: Option<&SmolStr>) -> Option { - attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok()) +#[derive(Clone, Debug)] +struct DirPath(String); + +impl DirPath { + fn assert_invariant(&self) { + assert!(self.0.is_empty() || self.0.ends_with('/')); + } + fn new(repr: String) -> DirPath { + let res = DirPath(repr); + res.assert_invariant(); + res + } + fn empty() -> DirPath { + DirPath::new(String::new()) + } + fn push(&mut self, name: &str) { + self.0.push_str(name); + self.0.push('/'); + self.assert_invariant(); + } + fn parent(&self) -> Option<&str> { + if self.0.is_empty() { + return None; + }; + let idx = + self.0[..self.0.len() - '/'.len_utf8()].rfind('/').map_or(0, |it| it + '/'.len_utf8()); + Some(&self.0[..idx]) + } + /// So this is the case which doesn't really work I think if we try to be + /// 100% platform agnostic: + /// + /// ``` + /// mod a { + /// #[path="C://sad/face"] + /// mod b { mod c; } + /// } + /// ``` + /// + /// Here, we need to join logical dir path to a string path from an + /// attribute. Ideally, we should somehow losslessly communicate the whole + /// construction to `FileLoader`. + fn join_attr(&self, mut attr: &str, relative_to_parent: bool) -> String { + let base = if relative_to_parent { self.parent().unwrap() } else { &self.0 }; + + if attr.starts_with("./") { + attr = &attr["./".len()..]; + } + let tmp; + let attr = if attr.contains('\\') { + tmp = attr.replace('\\', "/"); + &tmp + } else { + attr + }; + let res = format!("{}{}", base, attr); + res + } } -- cgit v1.2.3 From d47834ee1b8fce7956272e27c9403021940fec8e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 14 Jul 2020 18:31:48 +0200 Subject: Guard against infinite macro expansions closes #4463 --- crates/ra_hir_def/src/nameres/collector.rs | 5 +++++ crates/ra_hir_def/src/nameres/tests/macros.rs | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index a35ac1024..e55cc1e55 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -717,6 +717,11 @@ impl DefCollector<'_> { macro_call_id: MacroCallId, depth: usize, ) { + if depth > 100 { + mark::hit!(macro_expansion_overflow); + log::warn!("macro expansion is too deep"); + return; + } let file_id: HirFileId = macro_call_id.as_file(); let item_tree = self.db.item_tree(file_id); let mod_dir = self.mod_dirs[&module_id].clone(); diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index 84480d9f6..c52341a07 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -660,3 +660,27 @@ fn expand_multiple_derive() { ); assert_eq!(map.modules[map.root].scope.impls().len(), 2); } + +#[test] +fn macro_expansion_overflow() { + mark::check!(macro_expansion_overflow); + compute_crate_def_map( + " +macro_rules! a { + ($e:expr; $($t:tt)*) => { + b!($($t)*); + }; + () => {}; +} + +macro_rules! b { + (static = $e:expr; $($t:tt)*) => { + a!($e; $($t)*); + }; + () => {}; +} + +b! { static = #[] (); } +", + ); +} -- cgit v1.2.3 From 760ee8173c59976ca111040bc017b57df105768d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 15 Jul 2020 15:45:34 +0200 Subject: Micro-optimize update --- crates/ra_hir_def/src/nameres/collector.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index e55cc1e55..99ac730ba 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -609,14 +609,15 @@ impl DefCollector<'_> { .get(&module_id) .into_iter() .flat_map(|v| v.iter()) + .filter(|(glob_importing_module, _)| { + // we know all resolutions have the same visibility (`vis`), so we + // just need to check that once + vis.is_visible_from_def_map(&self.def_map, *glob_importing_module) + }) .cloned() .collect::>(); + for (glob_importing_module, glob_import_vis) in glob_imports { - // we know all resolutions have the same visibility (`vis`), so we - // just need to check that once - if !vis.is_visible_from_def_map(&self.def_map, glob_importing_module) { - continue; - } self.update_recursive( glob_importing_module, resolutions, -- cgit v1.2.3 From 8baa2b727ddca404e65560de61ac2fb5e1224a5b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 15 Jul 2020 15:49:20 +0200 Subject: Check cancellation when updating imports recursively For winapi, this takes a lot of CPU time without doing queries and causes the main event loop to stall on cancellation. --- crates/ra_hir_def/src/nameres/collector.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 99ac730ba..6494b653a 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -573,6 +573,7 @@ impl DefCollector<'_> { vis: Visibility, import_type: ImportType, ) { + self.db.check_canceled(); self.update_recursive(module_id, resolutions, vis, import_type, 0) } -- cgit v1.2.3 From 4c08fc9be3f7b79e3040a154aa97c29c97ee5a49 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 15 Jul 2020 15:52:32 +0200 Subject: Cleanup limits --- crates/ra_hir_def/src/nameres/collector.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 6494b653a..d85a86c0a 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -36,6 +36,10 @@ use crate::{ TraitLoc, TypeAliasLoc, UnionLoc, }; +const GLOB_RECURSION_LIMIT: usize = 100; +const EXPANSION_DEPTH_LIMIT: usize = 128; +const FIXED_POINT_LIMIT: usize = 8192; + pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { let crate_graph = db.crate_graph(); @@ -217,7 +221,7 @@ impl DefCollector<'_> { ReachedFixedPoint::Yes => break, ReachedFixedPoint::No => i += 1, } - if i == 10000 { + if i == FIXED_POINT_LIMIT { log::error!("name resolution is stuck"); break; } @@ -587,7 +591,7 @@ impl DefCollector<'_> { import_type: ImportType, depth: usize, ) { - if depth > 100 { + if depth > GLOB_RECURSION_LIMIT { // prevent stack overflows (but this shouldn't be possible) panic!("infinite recursion in glob imports!"); } @@ -679,10 +683,6 @@ impl DefCollector<'_> { self.unexpanded_attribute_macros = attribute_macros; for (module_id, macro_call_id, depth) in resolved { - if depth > 1024 { - log::debug!("Max macro expansion depth reached"); - continue; - } self.collect_macro_expansion(module_id, macro_call_id, depth); } @@ -719,7 +719,7 @@ impl DefCollector<'_> { macro_call_id: MacroCallId, depth: usize, ) { - if depth > 100 { + if depth > EXPANSION_DEPTH_LIMIT { mark::hit!(macro_expansion_overflow); log::warn!("macro expansion is too deep"); return; -- cgit v1.2.3 From ff0312fa32715ce42f134fd9f049c4df5956d042 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Jul 2020 13:00:56 +0200 Subject: Semantical call info --- crates/ra_hir_def/src/nameres/path_resolution.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 19692e70c..dbfa7fccb 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -226,7 +226,15 @@ impl CrateDefMap { match enum_data.variant(&segment) { Some(local_id) => { let variant = EnumVariantId { parent: e, local_id }; - PerNs::both(variant.into(), variant.into(), Visibility::Public) + match &*enum_data.variants[local_id].variant_data { + crate::adt::VariantData::Record(_) => { + PerNs::types(variant.into(), Visibility::Public) + } + crate::adt::VariantData::Tuple(_) + | crate::adt::VariantData::Unit => { + PerNs::both(variant.into(), variant.into(), Visibility::Public) + } + } } None => { return ResolvePathResult::with( -- cgit v1.2.3 From fcdac030335ba58e8267f3414101d4c2edb3797c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Jul 2020 14:37:51 +0200 Subject: Rewrite def map tests from insta to expect Those indentation markers are annoying... --- crates/ra_hir_def/src/nameres/tests.rs | 844 +++++++------ crates/ra_hir_def/src/nameres/tests/globs.rs | 578 +++++---- crates/ra_hir_def/src/nameres/tests/macros.rs | 1047 ++++++++-------- .../ra_hir_def/src/nameres/tests/mod_resolution.rs | 1257 ++++++++++---------- crates/ra_hir_def/src/nameres/tests/primitives.rs | 33 +- 5 files changed, 1821 insertions(+), 1938 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 503099fb7..02dca80c2 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -6,558 +6,531 @@ mod primitives; use std::sync::Arc; -use insta::assert_snapshot; +use expect::{expect, Expect}; use ra_db::{fixture::WithFixture, SourceDatabase}; use test_utils::mark; use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; -fn def_map(ra_fixture: &str) -> String { - compute_crate_def_map(ra_fixture).dump() -} - fn compute_crate_def_map(fixture: &str) -> Arc { let db = TestDB::with_files(fixture); let krate = db.crate_graph().iter().next().unwrap(); db.crate_def_map(krate) } +fn check(ra_fixture: &str, expect: Expect) { + let db = TestDB::with_files(ra_fixture); + let krate = db.crate_graph().iter().next().unwrap(); + let actual = db.crate_def_map(krate).dump() + "\n"; + expect.assert_eq(&actual); +} + #[test] fn crate_def_map_smoke_test() { - let map = def_map( - 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, - } + check( + r#" +//- /lib.rs +mod foo; +struct S; +use crate::foo::bar::E; +use self::E::V; - enum E { V } +//- /foo/mod.rs +pub mod bar; +fn f() {} - extern { - static EXT: u8; - fn ext(); - } - ", +//- /foo/bar.rs +pub struct Baz; + +union U { to_be: bool, not_to_be: u8 } +enum E { V } + +extern { + 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 + U: t + ext: v + "#]], ); - assert_snapshot!(map, @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 - ⋮U: t - ⋮ext: v - "###) } #[test] fn crate_def_map_super_super() { - let map = def_map( - " - //- /lib.rs - mod a { - const A: usize = 0; - - mod b { - const B: usize = 0; - - mod c { - use 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 + "#]], ); - assert_snapshot!(map, @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() { - let map = def_map( - " - //- /lib.rs - mod m { - pub mod z {} - pub fn z() {} - } - ", + check( + r#" +mod m { + pub mod z {} + pub fn z() {} +} +"#, + expect![[r#" + crate + m: t + + crate::m + z: t v + + crate::m::z + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮m: t - ⋮ - ⋮crate::m - ⋮z: t v - ⋮ - ⋮crate::m::z - "###) } #[test] fn bogus_paths() { mark::check!(bogus_paths); - let map = def_map( - " - //- /lib.rs - mod foo; - struct S; - use self; - - //- /foo/mod.rs - use super; - use crate; - - ", + 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 + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮S: t v - ⋮foo: t - ⋮ - ⋮crate::foo - "### - ) } #[test] fn use_as() { - let map = def_map( - " - //- /lib.rs - mod foo; - - use crate::foo::Baz as Foo; + check( + r#" +//- /lib.rs +mod foo; +use crate::foo::Baz as Foo; - //- /foo/mod.rs - pub struct Baz; - ", - ); - assert_snapshot!(map, - @r###" - ⋮crate - ⋮Foo: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "### +//- /foo/mod.rs +pub struct Baz; +"#, + expect![[r#" + crate + Foo: t v + foo: t + + crate::foo + Baz: t v + "#]], ); } #[test] fn use_trees() { - let map = def_map( - " - //- /lib.rs - mod foo; - - use crate::foo::bar::{Baz, Quux}; + check( + r#" +//- /lib.rs +mod foo; +use crate::foo::bar::{Baz, Quux}; - //- /foo/mod.rs - pub mod bar; +//- /foo/mod.rs +pub mod bar; - //- /foo/bar.rs - pub struct Baz; - pub enum Quux {}; - ", +//- /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 + "#]], ); - assert_snapshot!(map, @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() { - let map = def_map( - " - //- /lib.rs - mod foo; - - use self::foo::Baz; - - //- /foo/mod.rs - pub mod bar; + check( + r#" +//- /lib.rs +mod foo; +use self::foo::Baz; - pub use self::bar::Baz; +//- /foo/mod.rs +pub mod bar; +pub use self::bar::Baz; - //- /foo/bar.rs - pub struct 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 + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); } #[test] fn std_prelude() { mark::check!(std_prelude); - let map = def_map( - " - //- /main.rs crate:main deps:test_crate - use Foo::*; - - //- /lib.rs crate:test_crate - mod prelude; - #[prelude_import] - use prelude::*; - - //- /prelude.rs - pub enum Foo { Bar, Baz }; - ", + check( + r#" +//- /main.rs crate:main deps:test_crate +use Foo::*; + +//- /lib.rs crate:test_crate +mod prelude; +#[prelude_import] +use prelude::*; + +//- /prelude.rs +pub enum Foo { Bar, Baz }; +"#, + expect![[r#" + crate + Bar: t v + Baz: t v + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Baz: t v - "###); } #[test] fn can_import_enum_variant() { mark::check!(can_import_enum_variant); - let map = def_map( - " - //- /lib.rs - enum E { V } - use self::E::V; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮E: t - ⋮V: t v - "### + check( + r#" +enum E { V } +use self::E::V; +"#, + expect![[r#" + crate + E: t + V: t v + "#]], ); } #[test] fn edition_2015_imports() { - let map = def_map( - " - //- /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 - struct FromLib; - ", - ); + check( + r#" +//- /main.rs crate:main deps:other_crate edition:2015 +mod foo; +mod bar; + +//- /bar.rs +struct Bar; - assert_snapshot!(map, @r###" - ⋮crate - ⋮bar: t - ⋮foo: t - ⋮ - ⋮crate::bar - ⋮Bar: t v - ⋮ - ⋮crate::foo - ⋮Bar: t v - ⋮FromLib: t v - "###); +//- /foo.rs +use bar::Bar; +use other_crate::FromLib; + +//- /lib.rs crate:other_crate edition:2018 +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() { - let map = def_map( - " - //- /lib.rs - mod foo; - use crate::foo::bar::Baz::{self}; - //- /foo/mod.rs - pub mod bar; - //- /foo/bar.rs - pub struct Baz; - ", + 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 v + foo: t + + crate::foo + bar: t + + crate::foo::bar + Baz: t v + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); } #[test] fn item_map_across_crates() { - let map = def_map( - " - //- /main.rs crate:main deps:test_crate - use test_crate::Baz; - - //- /lib.rs crate:test_crate - pub struct Baz; - ", - ); + check( + r#" +//- /main.rs crate:main deps:test_crate +use test_crate::Baz; - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - "###); +//- /lib.rs crate:test_crate +pub struct Baz; +"#, + expect![[r#" + crate + Baz: t v + "#]], + ); } #[test] fn extern_crate_rename() { - let map = def_map( - " - //- /main.rs crate:main deps:alloc - extern crate alloc as alloc_crate; - - mod alloc; - mod sync; + check( + r#" +//- /main.rs crate:main deps:alloc +extern crate alloc as alloc_crate; +mod alloc; +mod sync; - //- /sync.rs - use alloc_crate::Arc; +//- /sync.rs +use alloc_crate::Arc; - //- /lib.rs crate:alloc - struct Arc; - ", +//- /lib.rs crate:alloc +struct Arc; +"#, + expect![[r#" + crate + alloc_crate: t + sync: t + + crate::sync + Arc: t v + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮alloc_crate: t - ⋮sync: t - ⋮ - ⋮crate::sync - ⋮Arc: t v - "###); } #[test] fn extern_crate_rename_2015_edition() { - let map = def_map( - " - //- /main.rs crate:main deps:alloc edition:2015 - extern crate alloc as alloc_crate; - - mod alloc; - mod sync; - - //- /sync.rs - use alloc_crate::Arc; + check( + r#" +//- /main.rs crate:main deps:alloc edition:2015 +extern crate alloc as alloc_crate; +mod alloc; +mod sync; - //- /lib.rs crate:alloc - struct Arc; - ", - ); +//- /sync.rs +use alloc_crate::Arc; - assert_snapshot!(map, - @r###" - ⋮crate - ⋮alloc_crate: t - ⋮sync: t - ⋮ - ⋮crate::sync - ⋮Arc: t v - "### +//- /lib.rs crate:alloc +struct Arc; +"#, + expect![[r#" + crate + alloc_crate: t + sync: t + + crate::sync + Arc: t v + "#]], ); } #[test] fn reexport_across_crates() { - let map = def_map( - " - //- /main.rs crate:main deps:test_crate - use test_crate::Baz; - - //- /lib.rs crate:test_crate - pub use foo::Baz; + check( + r#" +//- /main.rs crate:main deps:test_crate +use test_crate::Baz; - mod foo; +//- /lib.rs crate:test_crate +pub use foo::Baz; +mod foo; - //- /foo.rs - pub struct Baz; - ", +//- /foo.rs +pub struct Baz; +"#, + expect![[r#" + crate + Baz: t v + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - "###); } #[test] fn values_dont_shadow_extern_crates() { - let map = def_map( - " - //- /main.rs crate:main deps:foo - fn foo() {} - use foo::Bar; - - //- /foo/lib.rs crate:foo - pub struct Bar; - ", - ); + check( + r#" +//- /main.rs crate:main deps:foo +fn foo() {} +use foo::Bar; - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮foo: v - "###); +//- /foo/lib.rs crate:foo +pub struct Bar; +"#, + expect![[r#" + crate + Bar: t v + foo: v + "#]], + ); } #[test] fn std_prelude_takes_precedence_above_core_prelude() { - let map = def_map( + check( r#" - //- /main.rs crate:main deps:core,std - use {Foo, Bar}; - - //- /std.rs crate:std deps:core - #[prelude_import] - pub use self::prelude::*; - mod prelude { - pub struct Foo; - pub use core::prelude::Bar; - } +//- /main.rs crate:main deps:core,std +use {Foo, Bar}; + +//- /std.rs crate:std deps:core +#[prelude_import] +pub use self::prelude::*; +mod prelude { + pub struct Foo; + pub use core::prelude::Bar; +} - //- /core.rs crate:core - #[prelude_import] - pub use self::prelude::*; - mod prelude { - pub struct Bar; - } - "#, +//- /core.rs crate:core +#[prelude_import] +pub use self::prelude::*; +mod prelude { + pub struct Bar; +} +"#, + expect![[r#" + crate + Bar: t v + Foo: t v + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Foo: t v - "###); } #[test] fn cfg_not_test() { - let map = def_map( + check( r#" - //- /main.rs crate:main deps:std - use {Foo, Bar, Baz}; - - //- /lib.rs crate:std - #[prelude_import] - pub use self::prelude::*; - mod prelude { - #[cfg(test)] - pub struct Foo; - #[cfg(not(test))] - pub struct Bar; - #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] - pub struct Baz; - } - "#, +//- /main.rs crate:main deps:std +use {Foo, Bar, Baz}; + +//- /lib.rs crate:std +#[prelude_import] +pub use self::prelude::*; +mod prelude { + #[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: _ + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Baz: _ - ⋮Foo: _ - "###); } #[test] fn cfg_test() { - let map = def_map( + check( r#" - //- /main.rs crate:main deps:std - use {Foo, Bar, Baz}; - - //- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42 - #[prelude_import] - pub use self::prelude::*; - mod prelude { - #[cfg(test)] - pub struct Foo; - #[cfg(not(test))] - pub struct Bar; - #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] - pub struct Baz; - } - "#, +//- /main.rs crate:main deps:std +use {Foo, Bar, Baz}; + +//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42 +#[prelude_import] +pub use self::prelude::*; +mod prelude { + #[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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: _ - ⋮Baz: t v - ⋮Foo: t v - "###); } #[test] fn infer_multiple_namespace() { - let map = def_map( + check( r#" //- /main.rs mod a { @@ -571,18 +544,17 @@ mod b { pub const T: () = (); } "#, + expect![[r#" + crate + T: t v + a: t + b: t + + crate::b + T: v + + crate::a + T: t v + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮T: t v - ⋮a: t - ⋮b: t - ⋮ - ⋮crate::b - ⋮T: v - ⋮ - ⋮crate::a - ⋮T: t v -"###); } diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs index 7f3d7509c..2ae836e3c 100644 --- a/crates/ra_hir_def/src/nameres/tests/globs.rs +++ b/crates/ra_hir_def/src/nameres/tests/globs.rs @@ -2,367 +2,337 @@ use super::*; #[test] fn glob_1() { - let map = def_map( - r" - //- /lib.rs - mod foo; - use foo::*; - - //- /foo/mod.rs - pub mod bar; - pub use self::bar::Baz; - pub struct Foo; - - //- /foo/bar.rs - pub struct Baz; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮Foo: t v - ⋮bar: t - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮Foo: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "### + check( + r#" +//- /lib.rs +mod foo; +use foo::*; + +//- /foo/mod.rs +pub mod bar; +pub use self::bar::Baz; +pub struct Foo; + +//- /foo/bar.rs +pub struct Baz; +"#, + expect![[r#" + crate + Baz: t v + Foo: t v + bar: t + foo: t + + crate::foo + Baz: t v + Foo: t v + bar: t + + crate::foo::bar + Baz: t v + "#]], ); } #[test] fn glob_2() { - let map = def_map( - " - //- /lib.rs - mod foo; - use foo::*; - - //- /foo/mod.rs - pub mod bar; - pub use self::bar::*; - pub struct Foo; - - //- /foo/bar.rs - pub struct Baz; - pub use super::*; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮Foo: t v - ⋮bar: t - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮Foo: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - ⋮Foo: t v - ⋮bar: t - "### + check( + r#" +//- /lib.rs +mod foo; +use foo::*; + +//- /foo/mod.rs +pub mod bar; +pub use self::bar::*; +pub struct Foo; + +//- /foo/bar.rs +pub struct Baz; +pub use super::*; +"#, + expect![[r#" + crate + Baz: t v + Foo: t v + bar: t + foo: t + + crate::foo + Baz: t v + Foo: t v + bar: t + + crate::foo::bar + Baz: t v + Foo: t v + bar: t + "#]], ); } #[test] fn glob_privacy_1() { - let map = def_map( + check( r" - //- /lib.rs - mod foo; - use foo::*; - - //- /foo/mod.rs - pub mod bar; - pub use self::bar::*; - struct PrivateStructFoo; - - //- /foo/bar.rs - pub struct Baz; - struct PrivateStructBar; - pub use super::*; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮bar: t - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮PrivateStructFoo: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - ⋮PrivateStructBar: t v - ⋮PrivateStructFoo: t v - ⋮bar: t - "### +//- /lib.rs +mod foo; +use foo::*; + +//- /foo/mod.rs +pub mod bar; +pub use self::bar::*; +struct PrivateStructFoo; + +//- /foo/bar.rs +pub struct Baz; +struct PrivateStructBar; +pub use super::*; +", + expect![[r#" + crate + Baz: t v + bar: t + foo: t + + crate::foo + Baz: t v + PrivateStructFoo: t v + bar: t + + crate::foo::bar + Baz: t v + PrivateStructBar: t v + PrivateStructFoo: t v + bar: t + "#]], ); } #[test] fn glob_privacy_2() { - let map = def_map( + check( r" - //- /lib.rs - mod foo; - use foo::*; - use foo::bar::*; - - //- /foo/mod.rs - mod bar; - fn Foo() {}; - pub struct Foo {}; - - //- /foo/bar.rs - pub(super) struct PrivateBaz; - struct PrivateBar; - pub(crate) struct PubCrateStruct; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Foo: t - ⋮PubCrateStruct: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Foo: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮PrivateBar: t v - ⋮PrivateBaz: t v - ⋮PubCrateStruct: t v - "### +//- /lib.rs +mod foo; +use foo::*; +use foo::bar::*; + +//- /foo/mod.rs +mod bar; +fn Foo() {}; +pub struct Foo {}; + +//- /foo/bar.rs +pub(super) struct PrivateBaz; +struct PrivateBar; +pub(crate) struct PubCrateStruct; +", + expect![[r#" + crate + Foo: t + PubCrateStruct: t v + foo: t + + crate::foo + Foo: t v + bar: t + + crate::foo::bar + PrivateBar: t v + PrivateBaz: t v + PubCrateStruct: t v + "#]], ); } #[test] fn glob_across_crates() { mark::check!(glob_across_crates); - let map = def_map( - r" - //- /main.rs crate:main deps:test_crate - use test_crate::*; + check( + r#" +//- /main.rs crate:main deps:test_crate +use test_crate::*; - //- /lib.rs crate:test_crate - pub struct Baz; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - "### +//- /lib.rs crate:test_crate +pub struct Baz; +"#, + expect![[r#" + crate + Baz: t v + "#]], ); } #[test] fn glob_privacy_across_crates() { - let map = def_map( - r" - //- /main.rs crate:main deps:test_crate - use test_crate::*; + check( + r#" +//- /main.rs crate:main deps:test_crate +use test_crate::*; - //- /lib.rs crate:test_crate - pub struct Baz; - struct Foo; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - "### +//- /lib.rs crate:test_crate +pub struct Baz; +struct Foo; +"#, + expect![[r#" + crate + Baz: t v + "#]], ); } #[test] fn glob_enum() { mark::check!(glob_enum); - let map = def_map( - " - //- /lib.rs - enum Foo { - Bar, Baz - } - use self::Foo::*; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Baz: t v - ⋮Foo: t - "### + check( + r#" +enum Foo { Bar, Baz } +use self::Foo::*; +"#, + expect![[r#" + crate + Bar: t v + Baz: t v + Foo: t + "#]], ); } #[test] fn glob_enum_group() { mark::check!(glob_enum_group); - let map = def_map( - r" - //- /lib.rs - enum Foo { - Bar, Baz - } - use self::Foo::{*}; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Baz: t v - ⋮Foo: t - "### + check( + r#" +enum Foo { Bar, Baz } +use self::Foo::{*}; +"#, + expect![[r#" + crate + Bar: t v + Baz: t v + Foo: t + "#]], ); } #[test] fn glob_shadowed_def() { mark::check!(import_shadowed); - let map = def_map( - r###" - //- /lib.rs - mod foo; - mod bar; - - use foo::*; - use bar::baz; - - use baz::Bar; - - //- /foo.rs - pub mod baz { - pub struct Foo; - } - - //- /bar.rs - pub mod baz { - pub struct Bar; - } - "###, - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮bar: t - ⋮baz: t - ⋮foo: t - ⋮ - ⋮crate::bar - ⋮baz: t - ⋮ - ⋮crate::bar::baz - ⋮Bar: t v - ⋮ - ⋮crate::foo - ⋮baz: t - ⋮ - ⋮crate::foo::baz - ⋮Foo: t v - "### + check( + r#" +//- /lib.rs +mod foo; +mod bar; +use foo::*; +use bar::baz; +use baz::Bar; + +//- /foo.rs +pub mod baz { pub struct Foo; } + +//- /bar.rs +pub mod baz { pub struct Bar; } +"#, + expect![[r#" + crate + Bar: t v + bar: t + baz: t + foo: t + + crate::bar + baz: t + + crate::bar::baz + Bar: t v + + crate::foo + baz: t + + crate::foo::baz + Foo: t v + "#]], ); } #[test] fn glob_shadowed_def_reversed() { - let map = def_map( - r###" - //- /lib.rs - mod foo; - mod bar; - - use bar::baz; - use foo::*; - - use baz::Bar; - - //- /foo.rs - pub mod baz { - pub struct Foo; - } - - //- /bar.rs - pub mod baz { - pub struct Bar; - } - "###, - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮bar: t - ⋮baz: t - ⋮foo: t - ⋮ - ⋮crate::bar - ⋮baz: t - ⋮ - ⋮crate::bar::baz - ⋮Bar: t v - ⋮ - ⋮crate::foo - ⋮baz: t - ⋮ - ⋮crate::foo::baz - ⋮Foo: t v - "### + check( + r#" +//- /lib.rs +mod foo; +mod bar; +use bar::baz; +use foo::*; +use baz::Bar; + +//- /foo.rs +pub mod baz { pub struct Foo; } + +//- /bar.rs +pub mod baz { pub struct Bar; } +"#, + expect![[r#" + crate + Bar: t v + bar: t + baz: t + foo: t + + crate::bar + baz: t + + crate::bar::baz + Bar: t v + + crate::foo + baz: t + + crate::foo::baz + Foo: t v + "#]], ); } #[test] fn glob_shadowed_def_dependencies() { - let map = def_map( - r###" - //- /lib.rs - mod a { pub mod foo { pub struct X; } } - mod b { pub use super::a::foo; } - mod c { pub mod foo { pub struct Y; } } - mod d { - use super::c::foo; - use super::b::*; - use foo::Y; - } - "###, - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮a: t - ⋮b: t - ⋮c: t - ⋮d: t - ⋮ - ⋮crate::d - ⋮Y: t v - ⋮foo: t - ⋮ - ⋮crate::c - ⋮foo: t - ⋮ - ⋮crate::c::foo - ⋮Y: t v - ⋮ - ⋮crate::b - ⋮foo: t - ⋮ - ⋮crate::a - ⋮foo: t - ⋮ - ⋮crate::a::foo - ⋮X: t v - "### + check( + r#" +mod a { pub mod foo { pub struct X; } } +mod b { pub use super::a::foo; } +mod c { pub mod foo { pub struct Y; } } +mod d { + use super::c::foo; + use super::b::*; + use foo::Y; +} +"#, + expect![[r#" + crate + a: t + b: t + c: t + d: t + + crate::d + Y: t v + foo: t + + crate::c + foo: t + + crate::c::foo + Y: t v + + crate::b + foo: t + + crate::a + foo: t + + crate::a::foo + X: t v + "#]], ); } diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index c52341a07..e0fb8bdef 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -2,655 +2,635 @@ use super::*; #[test] fn macro_rules_are_globally_visible() { - let map = def_map( - r" - //- /lib.rs - macro_rules! structs { - ($($i:ident),*) => { - $(struct $i { field: u32 } )* - } - } - structs!(Foo); - mod nested; - - //- /nested.rs - structs!(Bar, Baz); - ", + check( + r#" +//- /lib.rs +macro_rules! structs { + ($($i:ident),*) => { + $(struct $i { field: u32 } )* + } +} +structs!(Foo); +mod nested; + +//- /nested.rs +structs!(Bar, Baz); +"#, + expect![[r#" + crate + Foo: t + nested: t + + crate::nested + Bar: t + Baz: t + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Foo: t - ⋮nested: t - ⋮ - ⋮crate::nested - ⋮Bar: t - ⋮Baz: t - "###); } #[test] fn macro_rules_can_define_modules() { - let map = def_map( - r" - //- /lib.rs - macro_rules! m { - ($name:ident) => { mod $name; } - } - m!(n1); - - mod m { - m!(n3) - } - - //- /n1.rs - m!(n2) - //- /n1/n2.rs - struct X; - //- /m/n3.rs - struct Y; - ", + check( + r#" +//- /lib.rs +macro_rules! m { + ($name:ident) => { mod $name; } +} +m!(n1); +mod m { m!(n3) } + +//- /n1.rs +m!(n2) +//- /n1/n2.rs +struct X; +//- /m/n3.rs +struct Y; +"#, + expect![[r#" + crate + m: t + n1: t + + crate::m + n3: t + + crate::m::n3 + Y: t v + + crate::n1 + n2: t + + crate::n1::n2 + X: t v + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮m: t - ⋮n1: t - ⋮ - ⋮crate::m - ⋮n3: t - ⋮ - ⋮crate::m::n3 - ⋮Y: t v - ⋮ - ⋮crate::n1 - ⋮n2: t - ⋮ - ⋮crate::n1::n2 - ⋮X: t v - "###); } #[test] fn macro_rules_from_other_crates_are_visible() { - let map = def_map( - " - //- /main.rs crate:main deps:foo - foo::structs!(Foo, Bar) - mod bar; - - //- /bar.rs - use crate::*; - - //- /lib.rs crate:foo - #[macro_export] - macro_rules! structs { - ($($i:ident),*) => { - $(struct $i { field: u32 } )* - } - } - ", + check( + r#" +//- /main.rs crate:main deps:foo +foo::structs!(Foo, Bar) +mod bar; + +//- /bar.rs +use crate::*; + +//- /lib.rs crate:foo +#[macro_export] +macro_rules! structs { + ($($i:ident),*) => { + $(struct $i { field: u32 } )* + } +} +"#, + expect![[r#" + crate + Bar: t + Foo: t + bar: t + + crate::bar + Bar: t + Foo: t + bar: t + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t - ⋮Foo: t - ⋮bar: t - ⋮ - ⋮crate::bar - ⋮Bar: t - ⋮Foo: t - ⋮bar: t - "###); } #[test] fn macro_rules_export_with_local_inner_macros_are_visible() { - let map = def_map( - " - //- /main.rs crate:main deps:foo - foo::structs!(Foo, Bar) - mod bar; - - //- /bar.rs - use crate::*; - - //- /lib.rs crate:foo - #[macro_export(local_inner_macros)] - macro_rules! structs { - ($($i:ident),*) => { - $(struct $i { field: u32 } )* - } - } - ", + check( + r#" +//- /main.rs crate:main deps:foo +foo::structs!(Foo, Bar) +mod bar; + +//- /bar.rs +use crate::*; + +//- /lib.rs crate:foo +#[macro_export(local_inner_macros)] +macro_rules! structs { + ($($i:ident),*) => { + $(struct $i { field: u32 } )* + } +} +"#, + expect![[r#" + crate + Bar: t + Foo: t + bar: t + + crate::bar + Bar: t + Foo: t + bar: t + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t - ⋮Foo: t - ⋮bar: t - ⋮ - ⋮crate::bar - ⋮Bar: t - ⋮Foo: t - ⋮bar: t - "###); } #[test] fn local_inner_macros_makes_local_macros_usable() { - let map = def_map( - " - //- /main.rs crate:main deps:foo - foo::structs!(Foo, Bar); - mod bar; - //- /bar.rs - use crate::*; - //- /lib.rs crate:foo - #[macro_export(local_inner_macros)] - macro_rules! structs { - ($($i:ident),*) => { - inner!($($i),*); - } - } - #[macro_export] - macro_rules! inner { - ($($i:ident),*) => { - $(struct $i { field: u32 } )* - } - } - ", + check( + r#" +//- /main.rs crate:main deps:foo +foo::structs!(Foo, Bar); +mod bar; + +//- /bar.rs +use crate::*; + +//- /lib.rs crate:foo +#[macro_export(local_inner_macros)] +macro_rules! structs { + ($($i:ident),*) => { + inner!($($i),*); + } +} +#[macro_export] +macro_rules! inner { + ($($i:ident),*) => { + $(struct $i { field: u32 } )* + } +} +"#, + expect![[r#" + crate + Bar: t + Foo: t + bar: t + + crate::bar + Bar: t + Foo: t + bar: t + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t - ⋮Foo: t - ⋮bar: t - ⋮ - ⋮crate::bar - ⋮Bar: t - ⋮Foo: t - ⋮bar: t - "###); } #[test] fn unexpanded_macro_should_expand_by_fixedpoint_loop() { - let map = def_map( - " - //- /main.rs crate:main deps:foo - macro_rules! baz { - () => { - use foo::bar; - } - } - - foo!(); - bar!(); - baz!(); - - //- /lib.rs crate:foo - #[macro_export] - macro_rules! foo { - () => { - struct Foo { field: u32 } - } - } - #[macro_export] - macro_rules! bar { - () => { - use foo::foo; - } - } - ", + check( + r#" +//- /main.rs crate:main deps:foo +macro_rules! baz { + () => { + use foo::bar; + } +} +foo!(); +bar!(); +baz!(); + +//- /lib.rs crate:foo +#[macro_export] +macro_rules! foo { + () => { + struct Foo { field: u32 } + } +} +#[macro_export] +macro_rules! bar { + () => { + use foo::foo; + } +} +"#, + expect![[r#" + crate + Foo: t + bar: m + foo: m + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Foo: t - ⋮bar: m - ⋮foo: m - "###); } #[test] fn macro_rules_from_other_crates_are_visible_with_macro_use() { mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use); - let map = def_map( - " - //- /main.rs crate:main deps:foo - structs!(Foo); - structs_priv!(Bar); - structs_not_exported!(MacroNotResolved1); - crate::structs!(MacroNotResolved2); + check( + r#" +//- /main.rs crate:main deps:foo +structs!(Foo); +structs_priv!(Bar); +structs_not_exported!(MacroNotResolved1); +crate::structs!(MacroNotResolved2); - mod bar; +mod bar; - #[macro_use] - extern crate foo; +#[macro_use] +extern crate foo; - //- /bar.rs - structs!(Baz); - crate::structs!(MacroNotResolved3); +//- /bar.rs +structs!(Baz); +crate::structs!(MacroNotResolved3); - //- /lib.rs crate:foo - #[macro_export] - macro_rules! structs { - ($i:ident) => { struct $i; } - } +//- /lib.rs crate:foo +#[macro_export] +macro_rules! structs { + ($i:ident) => { struct $i; } +} - macro_rules! structs_not_exported { - ($i:ident) => { struct $i; } - } +macro_rules! structs_not_exported { + ($i:ident) => { struct $i; } +} - mod priv_mod { - #[macro_export] - macro_rules! structs_priv { - ($i:ident) => { struct $i; } - } - } - ", +mod priv_mod { + #[macro_export] + macro_rules! structs_priv { + ($i:ident) => { struct $i; } + } +} +"#, + expect![[r#" + crate + Bar: t v + Foo: t v + bar: t + foo: t + + crate::bar + Baz: t v + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Foo: t v - ⋮bar: t - ⋮foo: t - ⋮ - ⋮crate::bar - ⋮Baz: t v - "###); } #[test] fn prelude_is_macro_use() { mark::check!(prelude_is_macro_use); - let map = def_map( - " - //- /main.rs crate:main deps:foo - structs!(Foo); - structs_priv!(Bar); - structs_outside!(Out); - crate::structs!(MacroNotResolved2); - - mod bar; - - //- /bar.rs - structs!(Baz); - crate::structs!(MacroNotResolved3); - - //- /lib.rs crate:foo - #[prelude_import] - use self::prelude::*; - - mod prelude { - #[macro_export] - macro_rules! structs { - ($i:ident) => { struct $i; } - } - - mod priv_mod { - #[macro_export] - macro_rules! structs_priv { - ($i:ident) => { struct $i; } - } - } - } + check( + r#" +//- /main.rs crate:main deps:foo +structs!(Foo); +structs_priv!(Bar); +structs_outside!(Out); +crate::structs!(MacroNotResolved2); +mod bar; + +//- /bar.rs +structs!(Baz); +crate::structs!(MacroNotResolved3); + +//- /lib.rs crate:foo +#[prelude_import] +use self::prelude::*; + +mod prelude { + #[macro_export] + macro_rules! structs { + ($i:ident) => { struct $i; } + } + + mod priv_mod { #[macro_export] - macro_rules! structs_outside { + macro_rules! structs_priv { ($i:ident) => { struct $i; } } - ", + } +} + +#[macro_export] +macro_rules! structs_outside { + ($i:ident) => { struct $i; } +} +"#, + expect![[r#" + crate + Bar: t v + Foo: t v + Out: t v + bar: t + + crate::bar + Baz: t v + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Foo: t v - ⋮Out: t v - ⋮bar: t - ⋮ - ⋮crate::bar - ⋮Baz: t v - "###); } #[test] fn prelude_cycle() { - let map = def_map( - " - //- /lib.rs - #[prelude_import] - use self::prelude::*; + check( + r#" +#[prelude_import] +use self::prelude::*; - declare_mod!(); +declare_mod!(); - mod prelude { - macro_rules! declare_mod { - () => (mod foo {}) - } - } - ", +mod prelude { + macro_rules! declare_mod { + () => (mod foo {}) + } +} +"#, + expect![[r#" + crate + prelude: t + + crate::prelude + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮prelude: t - ⋮ - ⋮crate::prelude - "###); } #[test] fn plain_macros_are_legacy_textual_scoped() { - let map = def_map( + check( r#" - //- /main.rs - mod m1; - bar!(NotFoundNotMacroUse); +//- /main.rs +mod m1; +bar!(NotFoundNotMacroUse); - mod m2 { - foo!(NotFoundBeforeInside2); - } +mod m2 { foo!(NotFoundBeforeInside2); } - macro_rules! foo { - ($x:ident) => { struct $x; } - } - foo!(Ok); - - mod m3; - foo!(OkShadowStop); - bar!(NotFoundMacroUseStop); - - #[macro_use] - mod m5 { - #[macro_use] - mod m6 { - macro_rules! foo { - ($x:ident) => { fn $x() {} } - } - } - } - foo!(ok_double_macro_use_shadow); - - baz!(NotFoundBefore); - #[macro_use] - mod m7 { - macro_rules! baz { - ($x:ident) => { struct $x; } - } - } - baz!(OkAfter); +macro_rules! foo { + ($x:ident) => { struct $x; } +} +foo!(Ok); - //- /m1.rs - foo!(NotFoundBeforeInside1); - macro_rules! bar { - ($x:ident) => { struct $x; } - } +mod m3; +foo!(OkShadowStop); +bar!(NotFoundMacroUseStop); - //- /m3/mod.rs - foo!(OkAfterInside); +#[macro_use] +mod m5 { + #[macro_use] + mod m6 { macro_rules! foo { ($x:ident) => { fn $x() {} } } - foo!(ok_shadow); + } +} +foo!(ok_double_macro_use_shadow); + +baz!(NotFoundBefore); +#[macro_use] +mod m7 { + macro_rules! baz { + ($x:ident) => { struct $x; } + } +} +baz!(OkAfter); - #[macro_use] - mod m4; - bar!(OkMacroUse); +//- /m1.rs +foo!(NotFoundBeforeInside1); +macro_rules! bar { + ($x:ident) => { struct $x; } +} - //- /m3/m4.rs - foo!(ok_shadow_deep); - macro_rules! bar { - ($x:ident) => { struct $x; } - } - "#, +//- /m3/mod.rs +foo!(OkAfterInside); +macro_rules! foo { + ($x:ident) => { fn $x() {} } +} +foo!(ok_shadow); + +#[macro_use] +mod m4; +bar!(OkMacroUse); + +//- /m3/m4.rs +foo!(ok_shadow_deep); +macro_rules! bar { + ($x:ident) => { struct $x; } +} +"#, + expect![[r#" + crate + Ok: t v + OkAfter: t v + OkShadowStop: t v + m1: t + m2: t + m3: t + m5: t + m7: t + ok_double_macro_use_shadow: v + + crate::m7 + + crate::m1 + + crate::m5 + m6: t + + crate::m5::m6 + + crate::m2 + + crate::m3 + OkAfterInside: t v + OkMacroUse: t v + m4: t + ok_shadow: v + + crate::m3::m4 + ok_shadow_deep: v + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Ok: t v - ⋮OkAfter: t v - ⋮OkShadowStop: t v - ⋮m1: t - ⋮m2: t - ⋮m3: t - ⋮m5: t - ⋮m7: t - ⋮ok_double_macro_use_shadow: v - ⋮ - ⋮crate::m7 - ⋮ - ⋮crate::m1 - ⋮ - ⋮crate::m5 - ⋮m6: t - ⋮ - ⋮crate::m5::m6 - ⋮ - ⋮crate::m2 - ⋮ - ⋮crate::m3 - ⋮OkAfterInside: t v - ⋮OkMacroUse: t v - ⋮m4: t - ⋮ok_shadow: v - ⋮ - ⋮crate::m3::m4 - ⋮ok_shadow_deep: v - "###); } #[test] fn type_value_macro_live_in_different_scopes() { - let map = def_map( - " - //- /main.rs - #[macro_export] - macro_rules! foo { - ($x:ident) => { type $x = (); } - } - - foo!(foo); - use foo as bar; + check( + r#" +#[macro_export] +macro_rules! foo { + ($x:ident) => { type $x = (); } +} - use self::foo as baz; - fn baz() {} - ", +foo!(foo); +use foo as bar; + +use self::foo as baz; +fn baz() {} +"#, + expect![[r#" + crate + bar: t m + baz: t v m + foo: t m + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮bar: t m - ⋮baz: t v m - ⋮foo: t m - "###); } #[test] fn macro_use_can_be_aliased() { - let map = def_map( - " - //- /main.rs crate:main deps:foo - #[macro_use] - extern crate foo; + check( + r#" +//- /main.rs crate:main deps:foo +#[macro_use] +extern crate foo; - foo!(Direct); - bar!(Alias); +foo!(Direct); +bar!(Alias); - //- /lib.rs crate:foo - use crate::foo as bar; +//- /lib.rs crate:foo +use crate::foo as bar; - mod m { - #[macro_export] - macro_rules! foo { - ($x:ident) => { struct $x; } - } - } - ", +mod m { + #[macro_export] + macro_rules! foo { + ($x:ident) => { struct $x; } + } +} +"#, + expect![[r#" + crate + Alias: t v + Direct: t v + foo: t + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Alias: t v - ⋮Direct: t v - ⋮foo: t - "###); } #[test] fn path_qualified_macros() { - let map = def_map( - " - //- /main.rs - macro_rules! foo { - ($x:ident) => { struct $x; } - } + check( + r#" +macro_rules! foo { + ($x:ident) => { struct $x; } +} - crate::foo!(NotResolved); - - crate::bar!(OkCrate); - bar!(OkPlain); - alias1!(NotHere); - m::alias1!(OkAliasPlain); - m::alias2!(OkAliasSuper); - m::alias3!(OkAliasCrate); - not_found!(NotFound); - - mod m { - #[macro_export] - macro_rules! bar { - ($x:ident) => { struct $x; } - } - - pub use bar as alias1; - pub use super::bar as alias2; - pub use crate::bar as alias3; - pub use self::bar as not_found; - } - ", +crate::foo!(NotResolved); + +crate::bar!(OkCrate); +bar!(OkPlain); +alias1!(NotHere); +m::alias1!(OkAliasPlain); +m::alias2!(OkAliasSuper); +m::alias3!(OkAliasCrate); +not_found!(NotFound); + +mod m { + #[macro_export] + macro_rules! bar { + ($x:ident) => { struct $x; } + } + pub use bar as alias1; + pub use super::bar as alias2; + pub use crate::bar as alias3; + pub use self::bar as not_found; +} +"#, + expect![[r#" + crate + OkAliasCrate: t v + OkAliasPlain: t v + OkAliasSuper: t v + OkCrate: t v + OkPlain: t v + bar: m + m: t + + crate::m + alias1: m + alias2: m + alias3: m + not_found: _ + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮OkAliasCrate: t v - ⋮OkAliasPlain: t v - ⋮OkAliasSuper: t v - ⋮OkCrate: t v - ⋮OkPlain: t v - ⋮bar: m - ⋮m: t - ⋮ - ⋮crate::m - ⋮alias1: m - ⋮alias2: m - ⋮alias3: m - ⋮not_found: _ - "###); } #[test] fn macro_dollar_crate_is_correct_in_item() { mark::check!(macro_dollar_crate_self); - let map = def_map( - " - //- /main.rs crate:main deps:foo - #[macro_use] - extern crate foo; - - #[macro_use] - mod m { - macro_rules! current { - () => { - use $crate::Foo as FooSelf; - } - } + check( + r#" +//- /main.rs crate:main deps:foo +#[macro_use] +extern crate foo; + +#[macro_use] +mod m { + macro_rules! current { + () => { + use $crate::Foo as FooSelf; } + } +} - struct Foo; +struct Foo; - current!(); - not_current1!(); - foo::not_current2!(); - - //- /lib.rs crate:foo - mod m { - #[macro_export] - macro_rules! not_current1 { - () => { - use $crate::Bar; - } - } - } +current!(); +not_current1!(); +foo::not_current2!(); - #[macro_export] - macro_rules! not_current2 { - () => { - use $crate::Baz; - } +//- /lib.rs crate:foo +mod m { + #[macro_export] + macro_rules! not_current1 { + () => { + use $crate::Bar; } + } +} - struct Bar; - struct Baz; - ", +#[macro_export] +macro_rules! not_current2 { + () => { + use $crate::Baz; + } +} + +struct Bar; +struct Baz; +"#, + expect![[r#" + crate + Bar: t v + Baz: t v + Foo: t v + FooSelf: t v + foo: t + m: t + + crate::m + "#]], ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮Baz: t v - ⋮Foo: t v - ⋮FooSelf: t v - ⋮foo: t - ⋮m: t - ⋮ - ⋮crate::m - "###); } #[test] fn macro_dollar_crate_is_correct_in_indirect_deps() { mark::check!(macro_dollar_crate_other); // From std - let map = def_map( + check( r#" - //- /main.rs crate:main deps:std - foo!(); +//- /main.rs crate:main deps:std +foo!(); - //- /std.rs crate:std deps:core - #[prelude_import] - use self::prelude::*; +//- /std.rs crate:std deps:core +#[prelude_import] +use self::prelude::*; - pub use core::foo; +pub use core::foo; - mod prelude {} +mod prelude {} - #[macro_use] - mod std_macros; +#[macro_use] +mod std_macros; - //- /core.rs crate:core - #[macro_export] - macro_rules! foo { - () => { - use $crate::bar; - } - } - - pub struct bar; - "#, - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮bar: t v - "###); +//- /core.rs crate:core +#[macro_export] +macro_rules! foo { + () => { + use $crate::bar; + } } -#[test] -fn expand_derive() { - let map = compute_crate_def_map( - " - //- /main.rs - #[derive(Clone)] - struct Foo; - ", +pub struct bar; +"#, + expect![[r#" + crate + bar: t v + "#]], ); - assert_eq!(map.modules[map.root].scope.impls().len(), 1); } #[test] -fn expand_multiple_derive() { +fn expand_derive() { let map = compute_crate_def_map( " //- /main.rs @@ -664,8 +644,8 @@ fn expand_multiple_derive() { #[test] fn macro_expansion_overflow() { mark::check!(macro_expansion_overflow); - compute_crate_def_map( - " + check( + r#" macro_rules! a { ($e:expr; $($t:tt)*) => { b!($($t)*); @@ -681,6 +661,9 @@ macro_rules! b { } b! { static = #[] (); } -", +"#, + expect![[r#" + crate + "#]], ); } diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs index 753684201..3da16fbe3 100644 --- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs @@ -3,710 +3,672 @@ use super::*; #[test] fn name_res_works_for_broken_modules() { mark::check!(name_res_works_for_broken_modules); - let map = def_map( + 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; - ", +//- /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 + "#]], ); - assert_snapshot!(map, @r###" -crate -Baz: _ -foo: t - -crate::foo - "###); } #[test] fn nested_module_resolution() { - let map = def_map( - r" - //- /lib.rs - mod n1; - - //- /n1.rs - mod n2; - - //- /n1/n2.rs - struct X; - ", + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮n1: t - ⋮ - ⋮crate::n1 - ⋮n2: t - ⋮ - ⋮crate::n1::n2 - ⋮X: t v - "###); } #[test] fn nested_module_resolution_2() { - let map = def_map( - 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; - ", + 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 + "#]], ); - - assert_snapshot!(map, @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() { - let map = def_map( - " - //- /my_library.rs crate:my_library - mod foo; - use self::foo::Bar; - - //- /foo/mod.rs - pub struct Bar; - ", + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Bar: t v - "###); } #[test] fn module_resolution_works_for_raw_modules() { - let map = def_map( - " - //- /lib.rs - mod r#async; - use self::r#async::Bar; - - //- /async.rs - pub struct Bar; - ", + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮async: t - ⋮ - ⋮crate::async - ⋮Bar: t v - "###); } #[test] fn module_resolution_decl_path() { - let map = def_map( - r###" - //- /lib.rs - #[path = "bar/baz/foo.rs"] - mod foo; - use self::foo::Bar; - - //- /bar/baz/foo.rs - pub struct Bar; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Bar: t v - "###); } #[test] fn module_resolution_module_with_path_in_mod_rs() { - let map = def_map( - r###" - //- /main.rs - mod foo; - - //- /foo/mod.rs - #[path = "baz.rs"] - pub mod bar; - - use self::bar::Baz; - - //- /foo/baz.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @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() { - let map = def_map( - r###" - //- /main.rs - mod foo; - - //- /foo.rs - #[path = "baz.rs"] - pub mod bar; - - use self::bar::Baz; - - //- /baz.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @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() { - let map = def_map( - r###" - //- /main.rs - #[path = "bar/baz/module.rs"] - mod foo; - pub struct Baz; - - //- /bar/baz/module.rs - use super::Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "###); } #[test] fn module_resolution_explicit_path_mod_rs() { - let map = def_map( - r###" - //- /main.rs - #[path = "module/mod.rs"] - mod foo; - - //- /module/mod.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "###); } #[test] fn module_resolution_relative_path() { - let map = def_map( - r###" - //- /main.rs - mod foo; - - //- /foo.rs - #[path = "./sub.rs"] - pub mod foo_bar; - - //- /sub.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮foo_bar: t - ⋮ - ⋮crate::foo::foo_bar - ⋮Baz: t v - "###); } #[test] fn module_resolution_relative_path_2() { - let map = def_map( - r###" - //- /main.rs - mod foo; - - //- /foo/mod.rs - #[path="../sub.rs"] - pub mod foo_bar; - - //- /sub.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮foo_bar: t - ⋮ - ⋮crate::foo::foo_bar - ⋮Baz: t v - "###); } #[test] fn module_resolution_relative_path_outside_root() { - let map = def_map( - r###" - //- /main.rs - - #[path="../../../../../outside.rs"] - mod foo; - "###, + check( + r#" +//- /main.rs +#[path="../../../../../outside.rs"] +mod foo; +"#, + expect![[r#" + crate + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - "###); } #[test] fn module_resolution_explicit_path_mod_rs_2() { - let map = def_map( - r###" - //- /main.rs - #[path = "module/bar/mod.rs"] - mod foo; - - //- /module/bar/mod.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "###); } #[test] fn module_resolution_explicit_path_mod_rs_with_win_separator() { - let map = def_map( - r###" - //- /main.rs - #[path = "module\bar\mod.rs"] - mod foo; - - //- /module/bar/mod.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "###); } #[test] fn module_resolution_decl_inside_inline_module_with_path_attribute() { - let map = def_map( - r###" - //- /main.rs - #[path = "models"] - mod foo { - mod bar; - } - - //- /models/bar.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); } #[test] fn module_resolution_decl_inside_inline_module() { - let map = def_map( - r###" - //- /main.rs - mod foo { - mod bar; - } - - //- /foo/bar.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @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() { - let map = def_map( - r###" - //- /main.rs - #[path = "models/db"] - mod foo { - mod bar; - } - - //- /models/db/bar.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); } #[test] fn module_resolution_decl_inside_inline_module_3() { - let map = def_map( - r###" - //- /main.rs - #[path = "models/db"] - mod foo { - #[path = "users.rs"] - mod bar; - } - - //- /models/db/users.rs - pub struct Baz; - "###, - ); + check( + r#" +//- /main.rs +#[path = "models/db"] +mod foo { + #[path = "users.rs"] + mod bar; +} - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); +//- /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() { - let map = def_map( - r###" - //- /main.rs - #[path = ""] - mod foo { - #[path = "users.rs"] - mod bar; - } - - //- /users.rs - pub struct Baz; - "###, - ); + check( + r#" +//- /main.rs +#[path = ""] +mod foo { + #[path = "users.rs"] + mod bar; +} + +//- /users.rs +pub struct Baz; +"#, + expect![[r#" + crate + foo: t - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); + crate::foo + bar: t + + crate::foo::bar + Baz: t v + "#]], + ); } #[test] fn module_resolution_decl_empty_path() { - let map = def_map( - r###" - //- /main.rs - #[path = ""] // Should try to read `/` (a directory) - mod foo; - - //- /foo.rs - pub struct Baz; - "###, + check( + r#" +//- /main.rs +#[path = ""] // Should try to read `/` (a directory) +mod foo; + +//- /foo.rs +pub struct Baz; +"#, + expect![[r#" + crate + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - "###); } #[test] fn module_resolution_decl_inside_inline_module_relative_path() { - let map = def_map( - r###" - //- /main.rs - #[path = "./models"] - mod foo { - mod bar; - } - - //- /models/bar.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @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() { - let map = def_map( - r###" - //- /main.rs - mod foo { - #[path = "baz.rs"] - mod bar; - } - use self::foo::bar::Baz; - - //- /foo/baz.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @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() { - let map = def_map( - r###" - //- /main.rs - mod foo; + check( + r#" +//- /main.rs +mod foo; + +//- /foo/mod.rs +mod bar { + #[path = "qwe.rs"] + pub mod baz; +} +use self::bar::baz::Baz; - //- /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 - //- /foo/bar/qwe.rs - pub struct Baz; - "###, - ); + crate::foo + Baz: t v + bar: t + + crate::foo::bar + baz: t - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮baz: t - ⋮ - ⋮crate::foo::bar::baz - ⋮Baz: t v - "###); + crate::foo::bar::baz + Baz: t v + "#]], + ); } #[test] fn module_resolution_decl_inside_inline_module_in_non_crate_root() { - let map = def_map( - r###" - //- /main.rs - mod foo; + check( + r#" +//- /main.rs +mod foo; + +//- /foo.rs +mod bar { + #[path = "qwe.rs"] + pub mod baz; +} +use self::bar::baz::Baz; - //- /foo.rs - mod bar { - #[path = "qwe.rs"] - pub mod baz; - } - use self::bar::baz::Baz; - - //- /foo/bar/qwe.rs - pub struct Baz; - "###, - ); +//- /foo/bar/qwe.rs +pub struct Baz; +"#, + expect![[r#" + crate + foo: t + + crate::foo + Baz: t v + bar: t - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮baz: t - ⋮ - ⋮crate::foo::bar::baz - ⋮Baz: t v - "###); + 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() { - let map = def_map( - r###" - //- /main.rs - mod foo; + check( + r#" +//- /main.rs +mod foo; + +//- /foo.rs +#[path = "bar"] +mod bar { + pub mod baz; +} +use self::bar::baz::Baz; - //- /foo.rs - #[path = "bar"] - mod bar { - pub mod baz; - } - use self::bar::baz::Baz; - - //- /bar/baz.rs - pub struct Baz; - "###, - ); +//- /bar/baz.rs +pub struct Baz; +"#, + expect![[r#" + crate + foo: t - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮baz: t - ⋮ - ⋮crate::foo::bar::baz - ⋮Baz: t v - "###); + crate::foo + Baz: t v + bar: t + + crate::foo::bar + baz: t + + crate::foo::bar::baz + Baz: t v + "#]], + ); } #[test] @@ -749,91 +711,88 @@ fn unresolved_module_diagnostics() { #[test] fn module_resolution_decl_inside_module_in_non_crate_root_2() { - let map = def_map( - r###" - //- /main.rs - #[path="module/m2.rs"] - mod module; - - //- /module/m2.rs - pub mod submod; - - //- /module/submod.rs - pub struct Baz; - "###, + 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 + "#]], ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮module: t - ⋮ - ⋮crate::module - ⋮submod: t - ⋮ - ⋮crate::module::submod - ⋮Baz: t v - "###); } #[test] fn nested_out_of_line_module() { - let map = def_map( - r###" - //- /lib.rs - mod a { - mod b { - mod c; - } - } - - //- /a/b/c.rs - struct X; - "###, - ); + check( + r#" +//- /lib.rs +mod a { + mod b { + mod c; + } +} - assert_snapshot!(map, @r###" - ⋮crate - ⋮a: t - ⋮ - ⋮crate::a - ⋮b: t - ⋮ - ⋮crate::a::b - ⋮c: t - ⋮ - ⋮crate::a::b::c - ⋮X: t v - "###); +//- /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() { - let map = def_map( - r###" - //- /lib.rs - mod a { - #[path = "d/e"] - mod b { - mod c; - } - } - - //- /a/d/e/c.rs - struct X; - "###, - ); + 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 - assert_snapshot!(map, @r###" - ⋮crate - ⋮a: t - ⋮ - ⋮crate::a - ⋮b: t - ⋮ - ⋮crate::a::b - ⋮c: t - ⋮ - ⋮crate::a::b::c - ⋮X: t v - "###); + crate::a + b: t + + crate::a::b + c: t + + crate::a::b::c + X: t v + "#]], + ); } diff --git a/crates/ra_hir_def/src/nameres/tests/primitives.rs b/crates/ra_hir_def/src/nameres/tests/primitives.rs index 0e2708658..215e8952d 100644 --- a/crates/ra_hir_def/src/nameres/tests/primitives.rs +++ b/crates/ra_hir_def/src/nameres/tests/primitives.rs @@ -2,23 +2,22 @@ use super::*; #[test] fn primitive_reexport() { - let map = def_map( - " - //- /lib.rs - mod foo; - use foo::int; + check( + r#" +//- /lib.rs +mod foo; +use foo::int; - //- /foo.rs - pub use i32 as int; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮int: t - ⋮ - ⋮crate::foo - ⋮int: t - "### +//- /foo.rs +pub use i32 as int; +"#, + expect![[r#" + crate + foo: t + int: t + + crate::foo + int: t + "#]], ); } -- cgit v1.2.3 From 19e78020bd54d97c670a1bcfb187dffd2b79a3fa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Jul 2020 15:54:40 +0200 Subject: Remove insta for ra_hir_def --- .../ra_hir_def/src/nameres/tests/mod_resolution.rs | 32 ++++++++++------------ 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs index 3da16fbe3..ae58948c4 100644 --- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs @@ -686,27 +686,25 @@ fn unresolved_module_diagnostics() { let crate_def_map = db.crate_def_map(krate); - insta::assert_debug_snapshot!( - crate_def_map.diagnostics, - @r###" - [ - UnresolvedModule { - module: Idx::(0), - declaration: InFile { - file_id: HirFileId( - FileId( + expect![[r#" + [ + UnresolvedModule { + module: Idx::(0), + declaration: InFile { + file_id: HirFileId( FileId( - 0, + FileId( + 0, + ), ), ), - ), - value: FileAstId::(1), + value: FileAstId::(1), + }, + candidate: "bar.rs", }, - candidate: "bar.rs", - }, - ] - "### - ); + ] + "#]] + .assert_debug_eq(&crate_def_map.diagnostics); } #[test] -- cgit v1.2.3 From c7ccfb072c0f8b8e7a47424c341103f48d4648e1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 20 Jul 2020 17:44:44 +0200 Subject: Simplify --- crates/ra_hir_def/src/nameres/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 02dca80c2..205d3528b 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -21,7 +21,7 @@ fn compute_crate_def_map(fixture: &str) -> Arc { fn check(ra_fixture: &str, expect: Expect) { let db = TestDB::with_files(ra_fixture); let krate = db.crate_graph().iter().next().unwrap(); - let actual = db.crate_def_map(krate).dump() + "\n"; + let actual = db.crate_def_map(krate).dump(); expect.assert_eq(&actual); } -- cgit v1.2.3 From c07eaf868dab86d061ae80c098798a767b910e91 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 21 Jul 2020 17:52:43 +0200 Subject: Support `Trait as _` imports --- crates/ra_hir_def/src/nameres/collector.rs | 67 +++++++++++---- crates/ra_hir_def/src/nameres/tests.rs | 131 +++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 18 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d85a86c0a..8913111f1 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -310,7 +310,7 @@ impl DefCollector<'_> { if export { self.update( self.def_map.root, - &[(name, PerNs::macros(macro_, Visibility::Public))], + &[(Some(name), PerNs::macros(macro_, Visibility::Public))], Visibility::Public, ImportType::Named, ); @@ -336,7 +336,7 @@ impl DefCollector<'_> { fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { self.update( self.def_map.root, - &[(name, PerNs::macros(macro_, Visibility::Public))], + &[(Some(name), PerNs::macros(macro_, Visibility::Public))], Visibility::Public, ImportType::Named, ); @@ -534,7 +534,7 @@ impl DefCollector<'_> { let name = variant_data.name.clone(); let variant = EnumVariantId { parent: e, local_id }; let res = PerNs::both(variant.into(), variant.into(), vis); - (name, res) + (Some(name), res) }) .collect::>(); self.update(module_id, &resolutions, vis, ImportType::Glob); @@ -550,15 +550,15 @@ impl DefCollector<'_> { match import.path.segments.last() { Some(last_segment) => { let name = match &import.alias { - Some(ImportAlias::Alias(name)) => name.clone(), - Some(ImportAlias::Underscore) => last_segment.clone(), // FIXME rust-analyzer#2736 - None => last_segment.clone(), + Some(ImportAlias::Alias(name)) => Some(name.clone()), + Some(ImportAlias::Underscore) => None, + None => Some(last_segment.clone()), }; log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 if import.is_extern_crate && module_id == self.def_map.root { - if let Some(def) = def.take_types() { + if let (Some(def), Some(name)) = (def.take_types(), name.as_ref()) { self.def_map.extern_prelude.insert(name.clone(), def); } } @@ -573,7 +573,7 @@ impl DefCollector<'_> { fn update( &mut self, module_id: LocalModuleId, - resolutions: &[(Name, PerNs)], + resolutions: &[(Option, PerNs)], vis: Visibility, import_type: ImportType, ) { @@ -584,7 +584,7 @@ impl DefCollector<'_> { fn update_recursive( &mut self, module_id: LocalModuleId, - resolutions: &[(Name, PerNs)], + resolutions: &[(Option, PerNs)], // All resolutions are imported with this visibility; the visibilies in // the `PerNs` values are ignored and overwritten vis: Visibility, @@ -595,15 +595,46 @@ impl DefCollector<'_> { // prevent stack overflows (but this shouldn't be possible) panic!("infinite recursion in glob imports!"); } - let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; + for (name, res) in resolutions { - changed |= scope.push_res_with_import( - &mut self.from_glob_import, - (module_id, name.clone()), - res.with_visibility(vis), - import_type, - ); + match name { + Some(name) => { + let scope = &mut self.def_map.modules[module_id].scope; + changed |= scope.push_res_with_import( + &mut self.from_glob_import, + (module_id, name.clone()), + res.with_visibility(vis), + import_type, + ); + } + None => { + let tr = match res.take_types() { + Some(ModuleDefId::TraitId(tr)) => tr, + Some(other) => { + log::debug!("non-trait `_` import of {:?}", other); + continue; + } + None => continue, + }; + let old_vis = self.def_map.modules[module_id].scope.unnamed_trait_vis(tr); + let should_update = match old_vis { + None => true, + Some(old_vis) => { + let max_vis = old_vis.max(vis, &self.def_map).unwrap_or_else(|| { + panic!("`Tr as _` imports with unrelated visibilities {:?} and {:?} (trait {:?})", old_vis, vis, tr); + }); + + max_vis != old_vis + } + }; + + if should_update { + changed = true; + self.def_map.modules[module_id].scope.push_unnamed_trait(tr, vis); + } + } + } } if !changed { @@ -950,7 +981,7 @@ impl ModCollector<'_, '_> { .unwrap_or(Visibility::Public); self.def_collector.update( self.module_id, - &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], + &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))], vis, ImportType::Named, ) @@ -1057,7 +1088,7 @@ impl ModCollector<'_, '_> { self.def_collector.def_map.modules[self.module_id].scope.define_def(def); self.def_collector.update( self.module_id, - &[(name, PerNs::from_def(def, vis, false))], + &[(Some(name), PerNs::from_def(def, vis, false))], vis, ImportType::Named, ); diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 205d3528b..502b1fb69 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -558,3 +558,134 @@ mod b { "#]], ); } + +#[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::tr + PrivTr: t + PubTr: t + + crate::reex + _: t + _: t + "#]], + ); +} + +#[test] +fn underscore_pub_crate_reexport() { + 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 { + fn method(&self) {} + } +} + "#, + 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 + "#]], + ); +} -- cgit v1.2.3 From dce99874368e3e42402b4443c5eb39495c8c162a Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 22 Jul 2020 14:01:50 +0200 Subject: Check that visibility upgrade path is hit --- crates/ra_hir_def/src/nameres/collector.rs | 7 ++++++- crates/ra_hir_def/src/nameres/tests.rs | 5 ++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 8913111f1..a030cab47 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -625,7 +625,12 @@ impl DefCollector<'_> { panic!("`Tr as _` imports with unrelated visibilities {:?} and {:?} (trait {:?})", old_vis, vis, tr); }); - max_vis != old_vis + if max_vis == old_vis { + false + } else { + mark::hit!(upgrade_underscore_visibility); + true + } } }; diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 502b1fb69..839b1de57 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -619,6 +619,7 @@ use crate::reex::*; #[test] fn underscore_pub_crate_reexport() { + mark::check!(upgrade_underscore_visibility); check( r#" //- /main.rs crate:main deps:lib @@ -629,9 +630,7 @@ use tr::Tr as _; pub use tr::Tr as _; mod tr { - pub trait Tr { - fn method(&self) {} - } + pub trait Tr {} } "#, expect![[r#" -- cgit v1.2.3 From 6636f56e79b55f22b88094b7edaed6ec88880500 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 00:23:03 +0200 Subject: Rename ModuleItem -> Item --- crates/ra_hir_def/src/nameres/collector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src/nameres') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index a030cab47..28b7a20c5 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -170,7 +170,7 @@ struct MacroDirective { #[derive(Clone, Debug, Eq, PartialEq)] struct DeriveDirective { module_id: LocalModuleId, - ast_id: AstIdWithPath, + ast_id: AstIdWithPath, } struct DefData<'a> { @@ -1100,7 +1100,7 @@ impl ModCollector<'_, '_> { res } - fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId) { + fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId) { for derive_subtree in attrs.by_key("derive").tt_values() { // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree for tt in &derive_subtree.token_trees { -- cgit v1.2.3