From 8d96db3417fdabb1bad7a9919ea8ae1db25296f1 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 00:17:22 +0800 Subject: [PATCH 1/7] Favor types for Record in name resolution --- crates/ra_hir_def/src/body/lower.rs | 15 +++++++++++---- crates/ra_hir_def/src/item_scope.rs | 11 +++++++++-- crates/ra_hir_def/src/nameres/collector.rs | 13 ++++++++++--- crates/ra_hir_def/src/nameres/raw.rs | 18 +++++++++++++++--- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 687216dc35e..49f5420d14d 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -18,7 +18,7 @@ use test_utils::tested_by; use crate::{ - adt::StructKind, + adt::{self, StructKind}, body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax}, builtin_type::{BuiltinFloat, BuiltinInt}, db::DefDatabase, @@ -575,9 +575,16 @@ fn collect_block_items(&mut self, block: &ast::BlockExpr) { self.body.item_scope.define_def(def); if let Some(name) = name { let vis = crate::visibility::Visibility::Public; // FIXME determine correctly - self.body - .item_scope - .push_res(name.as_name(), crate::per_ns::PerNs::from_def(def, vis)); + let favor_types = match def { + ModuleDefId::AdtId(AdtId::StructId(s)) => { + self.db.struct_data(s).variant_data.kind() == adt::StructKind::Record + } + _ => false, + }; + self.body.item_scope.push_res( + name.as_name(), + crate::per_ns::PerNs::from_def(def, vis, favor_types), + ); } } } diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 259b9ff035d..6d8d1f8a385 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -151,13 +151,20 @@ pub(crate) fn collect_legacy_macros(&self) -> FxHashMap { } impl PerNs { - pub(crate) fn from_def(def: ModuleDefId, v: Visibility) -> PerNs { + pub(crate) fn from_def(def: ModuleDefId, v: Visibility, favor_types: bool) -> PerNs { match def { ModuleDefId::ModuleId(_) => PerNs::types(def, v), ModuleDefId::FunctionId(_) => PerNs::values(def, v), ModuleDefId::AdtId(adt) => match adt { - AdtId::StructId(_) | AdtId::UnionId(_) => PerNs::both(def, def, v), + AdtId::UnionId(_) => PerNs::both(def, def, v), AdtId::EnumId(_) => PerNs::types(def, v), + AdtId::StructId(_) => { + if favor_types { + PerNs::types(def, v) + } else { + PerNs::both(def, def, v) + } + } }, ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v), ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v), diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index bf3968bd62a..49b33ca9423 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -830,7 +830,7 @@ fn push_child_module( let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; let def: ModuleDefId = module.into(); 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))], vis); + self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis, false))], vis); res } @@ -844,6 +844,8 @@ fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { let name = def.name.clone(); let container = ContainerId::ModuleId(module); let vis = &def.visibility; + let mut favor_types = false; + let def: ModuleDefId = match def.kind { raw::DefKind::Function(ast_id) => FunctionLoc { container: container.into(), @@ -851,7 +853,8 @@ fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { } .intern(self.def_collector.db) .into(), - raw::DefKind::Struct(ast_id) => { + raw::DefKind::Struct(ast_id, mode) => { + favor_types = mode == raw::StructDefKind::Record; StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db) .into() @@ -894,7 +897,11 @@ fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { .def_map .resolve_visibility(self.def_collector.db, self.module_id, vis) .unwrap_or(Visibility::Public); - self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis))], vis) + self.def_collector.update( + self.module_id, + &[(name, PerNs::from_def(def, vis, favor_types))], + vis, + ) } fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index a71503c76ec..f2716a2950b 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -155,10 +155,17 @@ pub(super) struct DefData { pub(super) visibility: RawVisibility, } +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub(super) enum StructDefKind { + Record, + Tuple, + Unit, +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(super) enum DefKind { Function(FileAstId), - Struct(FileAstId), + Struct(FileAstId, StructDefKind), Union(FileAstId), Enum(FileAstId), Const(FileAstId), @@ -171,7 +178,7 @@ impl DefKind { pub fn ast_id(&self) -> FileAstId { match self { DefKind::Function(it) => it.upcast(), - DefKind::Struct(it) => it.upcast(), + DefKind::Struct(it, _) => it.upcast(), DefKind::Union(it) => it.upcast(), DefKind::Enum(it) => it.upcast(), DefKind::Const(it) => it.upcast(), @@ -236,9 +243,14 @@ fn add_item(&mut self, current_module: Option>, item: ast::Modul return; } ast::ModuleItem::StructDef(it) => { + let kind = match it.kind() { + ast::StructKind::Record(_) => StructDefKind::Record, + ast::StructKind::Tuple(_) => StructDefKind::Tuple, + ast::StructKind::Unit => StructDefKind::Unit, + }; let id = self.source_ast_id_map.ast_id(&it); let name = it.name(); - (DefKind::Struct(id), name) + (DefKind::Struct(id, kind), name) } ast::ModuleItem::UnionDef(it) => { let id = self.source_ast_id_map.ast_id(&it); From af001677d103a3e0f5cf1bfde44982171faf34b9 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 00:17:30 +0800 Subject: [PATCH 2/7] Fix test --- crates/ra_hir_def/src/nameres/tests/macros.rs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index 9bc0e628747..40289e3ca52 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -19,12 +19,12 @@ macro_rules! structs { ); assert_snapshot!(map, @r###" ⋮crate - ⋮Foo: t v + ⋮Foo: t ⋮nested: t ⋮ ⋮crate::nested - ⋮Bar: t v - ⋮Baz: t v + ⋮Bar: t + ⋮Baz: t "###); } @@ -91,13 +91,13 @@ macro_rules! structs { ); assert_snapshot!(map, @r###" ⋮crate - ⋮Bar: t v - ⋮Foo: t v + ⋮Bar: t + ⋮Foo: t ⋮bar: t ⋮ ⋮crate::bar - ⋮Bar: t v - ⋮Foo: t v + ⋮Bar: t + ⋮Foo: t ⋮bar: t "###); } @@ -124,13 +124,13 @@ macro_rules! structs { ); assert_snapshot!(map, @r###" ⋮crate - ⋮Bar: t v - ⋮Foo: t v + ⋮Bar: t + ⋮Foo: t ⋮bar: t ⋮ ⋮crate::bar - ⋮Bar: t v - ⋮Foo: t v + ⋮Bar: t + ⋮Foo: t ⋮bar: t "###); } @@ -161,13 +161,13 @@ macro_rules! inner { ); assert_snapshot!(map, @r###" ⋮crate - ⋮Bar: t v - ⋮Foo: t v + ⋮Bar: t + ⋮Foo: t ⋮bar: t ⋮ ⋮crate::bar - ⋮Bar: t v - ⋮Foo: t v + ⋮Bar: t + ⋮Foo: t ⋮bar: t "###); } @@ -204,7 +204,7 @@ macro_rules! bar { ); assert_snapshot!(map, @r###" ⋮crate - ⋮Foo: t v + ⋮Foo: t ⋮bar: m ⋮foo: m "###); From 204c8de3bfc5a8c21e0104a68356bf90f7762527 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 00:29:47 +0800 Subject: [PATCH 3/7] Add test for issue --- crates/ra_hir_ty/src/tests/regression.rs | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 8a1292c7aa0..115ad832891 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -534,6 +534,35 @@ fn foo(b: Bar) { ); } +#[test] +fn issue_4235_name_conflicts() { + assert_snapshot!( + infer(r#" +struct FOO {} +static FOO:FOO = FOO {}; + +impl FOO { + fn foo(&self) {} +} + +fn main() { + let a = &FOO; + a.foo(); +} +"#), @r###" + 32..38 'FOO {}': FOO + 64..68 'self': &FOO + 70..72 '{}': () + 86..120 '{ ...o(); }': () + 96..97 'a': &FOO + 100..104 '&FOO': &FOO + 101..104 'FOO': FOO + 110..111 'a': &FOO + 110..117 'a.foo()': () +"### + ); +} + #[test] fn issue_4053_diesel_where_clauses() { assert_snapshot!( From 5ae18f4f814501ccd96a277c320e919159c91fac Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 00:34:54 +0800 Subject: [PATCH 4/7] Remove unused import --- crates/ra_hir_def/src/body/lower.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 49f5420d14d..ea0ddeebcc3 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -18,7 +18,7 @@ use test_utils::tested_by; use crate::{ - adt::{self, StructKind}, + adt::StructKind, body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax}, builtin_type::{BuiltinFloat, BuiltinInt}, db::DefDatabase, @@ -577,7 +577,7 @@ fn collect_block_items(&mut self, block: &ast::BlockExpr) { let vis = crate::visibility::Visibility::Public; // FIXME determine correctly let favor_types = match def { ModuleDefId::AdtId(AdtId::StructId(s)) => { - self.db.struct_data(s).variant_data.kind() == adt::StructKind::Record + self.db.struct_data(s).variant_data.kind() == StructKind::Record } _ => false, }; From e921195d93c443b20a6fcb3cb1c5b8117fe2fa1b Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 01:15:27 +0800 Subject: [PATCH 5/7] Change favor_types to has_constructor --- crates/ra_hir_def/src/body/lower.rs | 8 ++++---- crates/ra_hir_def/src/item_scope.rs | 4 ++-- crates/ra_hir_def/src/nameres/collector.rs | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index ea0ddeebcc3..4671b72e9d8 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -575,15 +575,15 @@ fn collect_block_items(&mut self, block: &ast::BlockExpr) { self.body.item_scope.define_def(def); if let Some(name) = name { let vis = crate::visibility::Visibility::Public; // FIXME determine correctly - let favor_types = match def { + let has_constructor = match def { ModuleDefId::AdtId(AdtId::StructId(s)) => { - self.db.struct_data(s).variant_data.kind() == StructKind::Record + self.db.struct_data(s).variant_data.kind() != StructKind::Record } - _ => false, + _ => true, }; self.body.item_scope.push_res( name.as_name(), - crate::per_ns::PerNs::from_def(def, vis, favor_types), + crate::per_ns::PerNs::from_def(def, vis, has_constructor), ); } } diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 6d8d1f8a385..954f2542a03 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -151,7 +151,7 @@ pub(crate) fn collect_legacy_macros(&self) -> FxHashMap { } impl PerNs { - pub(crate) fn from_def(def: ModuleDefId, v: Visibility, favor_types: bool) -> PerNs { + pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs { match def { ModuleDefId::ModuleId(_) => PerNs::types(def, v), ModuleDefId::FunctionId(_) => PerNs::values(def, v), @@ -159,7 +159,7 @@ pub(crate) fn from_def(def: ModuleDefId, v: Visibility, favor_types: bool) -> Pe AdtId::UnionId(_) => PerNs::both(def, def, v), AdtId::EnumId(_) => PerNs::types(def, v), AdtId::StructId(_) => { - if favor_types { + if !has_constructor { PerNs::types(def, v) } else { PerNs::both(def, def, v) diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 49b33ca9423..db994122ae9 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -844,7 +844,7 @@ fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { let name = def.name.clone(); let container = ContainerId::ModuleId(module); let vis = &def.visibility; - let mut favor_types = false; + let mut has_constructor = false; let def: ModuleDefId = match def.kind { raw::DefKind::Function(ast_id) => FunctionLoc { @@ -854,7 +854,7 @@ fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { .intern(self.def_collector.db) .into(), raw::DefKind::Struct(ast_id, mode) => { - favor_types = mode == raw::StructDefKind::Record; + has_constructor = mode != raw::StructDefKind::Record; StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db) .into() @@ -899,7 +899,7 @@ fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { .unwrap_or(Visibility::Public); self.def_collector.update( self.module_id, - &[(name, PerNs::from_def(def, vis, favor_types))], + &[(name, PerNs::from_def(def, vis, has_constructor))], vis, ) } From cf821cc33271b3a133ea3b3775f86573aa2514cb Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 01:19:54 +0800 Subject: [PATCH 6/7] Change union resolve types only --- crates/ra_hir_def/src/item_scope.rs | 2 +- crates/ra_hir_def/src/nameres/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 954f2542a03..7792ed709a7 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -156,7 +156,7 @@ pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) - ModuleDefId::ModuleId(_) => PerNs::types(def, v), ModuleDefId::FunctionId(_) => PerNs::values(def, v), ModuleDefId::AdtId(adt) => match adt { - AdtId::UnionId(_) => PerNs::both(def, def, v), + AdtId::UnionId(_) => PerNs::types(def, v), AdtId::EnumId(_) => PerNs::types(def, v), AdtId::StructId(_) => { if !has_constructor { diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 83120fa365d..1b66c1aacfa 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -67,7 +67,7 @@ enum E { V } ⋮Baz: t v ⋮E: t ⋮EXT: v - ⋮U: t v + ⋮U: t ⋮ext: v "###) } From 07de8ea165deb37ca9c42e66d2d3ecac57756ec6 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 5 May 2020 23:01:07 +0800 Subject: [PATCH 7/7] invert if --- crates/ra_hir_def/src/item_scope.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 7792ed709a7..fc15948adf4 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -159,10 +159,10 @@ pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) - AdtId::UnionId(_) => PerNs::types(def, v), AdtId::EnumId(_) => PerNs::types(def, v), AdtId::StructId(_) => { - if !has_constructor { - PerNs::types(def, v) - } else { + if has_constructor { PerNs::both(def, def, v) + } else { + PerNs::types(def, v) } } },