mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #4305
4305: Favor types for record type struct in name resolution r=matklad a=edwin0cheng Fixed #4235 Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
756e91732b
7 changed files with 90 additions and 28 deletions
|
@ -573,9 +573,16 @@ impl ExprCollector<'_> {
|
||||||
self.body.item_scope.define_def(def);
|
self.body.item_scope.define_def(def);
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
let vis = crate::visibility::Visibility::Public; // FIXME determine correctly
|
let vis = crate::visibility::Visibility::Public; // FIXME determine correctly
|
||||||
self.body
|
let has_constructor = match def {
|
||||||
.item_scope
|
ModuleDefId::AdtId(AdtId::StructId(s)) => {
|
||||||
.push_res(name.as_name(), crate::per_ns::PerNs::from_def(def, vis));
|
self.db.struct_data(s).variant_data.kind() != StructKind::Record
|
||||||
|
}
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
self.body.item_scope.push_res(
|
||||||
|
name.as_name(),
|
||||||
|
crate::per_ns::PerNs::from_def(def, vis, has_constructor),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,13 +151,20 @@ impl ItemScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PerNs {
|
impl PerNs {
|
||||||
pub(crate) fn from_def(def: ModuleDefId, v: Visibility) -> PerNs {
|
pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs {
|
||||||
match def {
|
match def {
|
||||||
ModuleDefId::ModuleId(_) => PerNs::types(def, v),
|
ModuleDefId::ModuleId(_) => PerNs::types(def, v),
|
||||||
ModuleDefId::FunctionId(_) => PerNs::values(def, v),
|
ModuleDefId::FunctionId(_) => PerNs::values(def, v),
|
||||||
ModuleDefId::AdtId(adt) => match adt {
|
ModuleDefId::AdtId(adt) => match adt {
|
||||||
AdtId::StructId(_) | AdtId::UnionId(_) => PerNs::both(def, def, v),
|
AdtId::UnionId(_) => PerNs::types(def, v),
|
||||||
AdtId::EnumId(_) => PerNs::types(def, v),
|
AdtId::EnumId(_) => PerNs::types(def, v),
|
||||||
|
AdtId::StructId(_) => {
|
||||||
|
if has_constructor {
|
||||||
|
PerNs::both(def, def, v)
|
||||||
|
} else {
|
||||||
|
PerNs::types(def, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
|
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
|
||||||
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
|
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
|
||||||
|
|
|
@ -830,7 +830,7 @@ impl ModCollector<'_, '_> {
|
||||||
let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res };
|
let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res };
|
||||||
let def: ModuleDefId = module.into();
|
let def: ModuleDefId = module.into();
|
||||||
self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
|
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
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,6 +844,8 @@ impl ModCollector<'_, '_> {
|
||||||
let name = def.name.clone();
|
let name = def.name.clone();
|
||||||
let container = ContainerId::ModuleId(module);
|
let container = ContainerId::ModuleId(module);
|
||||||
let vis = &def.visibility;
|
let vis = &def.visibility;
|
||||||
|
let mut has_constructor = false;
|
||||||
|
|
||||||
let def: ModuleDefId = match def.kind {
|
let def: ModuleDefId = match def.kind {
|
||||||
raw::DefKind::Function(ast_id) => FunctionLoc {
|
raw::DefKind::Function(ast_id) => FunctionLoc {
|
||||||
container: container.into(),
|
container: container.into(),
|
||||||
|
@ -851,7 +853,8 @@ impl ModCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
.intern(self.def_collector.db)
|
.intern(self.def_collector.db)
|
||||||
.into(),
|
.into(),
|
||||||
raw::DefKind::Struct(ast_id) => {
|
raw::DefKind::Struct(ast_id, mode) => {
|
||||||
|
has_constructor = mode != raw::StructDefKind::Record;
|
||||||
StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
|
StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
|
||||||
.intern(self.def_collector.db)
|
.intern(self.def_collector.db)
|
||||||
.into()
|
.into()
|
||||||
|
@ -894,7 +897,11 @@ impl ModCollector<'_, '_> {
|
||||||
.def_map
|
.def_map
|
||||||
.resolve_visibility(self.def_collector.db, self.module_id, vis)
|
.resolve_visibility(self.def_collector.db, self.module_id, vis)
|
||||||
.unwrap_or(Visibility::Public);
|
.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, has_constructor))],
|
||||||
|
vis,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) {
|
fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) {
|
||||||
|
|
|
@ -155,10 +155,17 @@ pub(super) struct DefData {
|
||||||
pub(super) visibility: RawVisibility,
|
pub(super) visibility: RawVisibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
pub(super) enum StructDefKind {
|
||||||
|
Record,
|
||||||
|
Tuple,
|
||||||
|
Unit,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub(super) enum DefKind {
|
pub(super) enum DefKind {
|
||||||
Function(FileAstId<ast::FnDef>),
|
Function(FileAstId<ast::FnDef>),
|
||||||
Struct(FileAstId<ast::StructDef>),
|
Struct(FileAstId<ast::StructDef>, StructDefKind),
|
||||||
Union(FileAstId<ast::UnionDef>),
|
Union(FileAstId<ast::UnionDef>),
|
||||||
Enum(FileAstId<ast::EnumDef>),
|
Enum(FileAstId<ast::EnumDef>),
|
||||||
Const(FileAstId<ast::ConstDef>),
|
Const(FileAstId<ast::ConstDef>),
|
||||||
|
@ -171,7 +178,7 @@ impl DefKind {
|
||||||
pub fn ast_id(&self) -> FileAstId<ast::ModuleItem> {
|
pub fn ast_id(&self) -> FileAstId<ast::ModuleItem> {
|
||||||
match self {
|
match self {
|
||||||
DefKind::Function(it) => it.upcast(),
|
DefKind::Function(it) => it.upcast(),
|
||||||
DefKind::Struct(it) => it.upcast(),
|
DefKind::Struct(it, _) => it.upcast(),
|
||||||
DefKind::Union(it) => it.upcast(),
|
DefKind::Union(it) => it.upcast(),
|
||||||
DefKind::Enum(it) => it.upcast(),
|
DefKind::Enum(it) => it.upcast(),
|
||||||
DefKind::Const(it) => it.upcast(),
|
DefKind::Const(it) => it.upcast(),
|
||||||
|
@ -236,9 +243,14 @@ impl RawItemsCollector {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ast::ModuleItem::StructDef(it) => {
|
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 id = self.source_ast_id_map.ast_id(&it);
|
||||||
let name = it.name();
|
let name = it.name();
|
||||||
(DefKind::Struct(id), name)
|
(DefKind::Struct(id, kind), name)
|
||||||
}
|
}
|
||||||
ast::ModuleItem::UnionDef(it) => {
|
ast::ModuleItem::UnionDef(it) => {
|
||||||
let id = self.source_ast_id_map.ast_id(&it);
|
let id = self.source_ast_id_map.ast_id(&it);
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn crate_def_map_smoke_test() {
|
||||||
⋮Baz: t v
|
⋮Baz: t v
|
||||||
⋮E: t
|
⋮E: t
|
||||||
⋮EXT: v
|
⋮EXT: v
|
||||||
⋮U: t v
|
⋮U: t
|
||||||
⋮ext: v
|
⋮ext: v
|
||||||
"###)
|
"###)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,12 @@ fn macro_rules_are_globally_visible() {
|
||||||
);
|
);
|
||||||
assert_snapshot!(map, @r###"
|
assert_snapshot!(map, @r###"
|
||||||
⋮crate
|
⋮crate
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮nested: t
|
⋮nested: t
|
||||||
⋮
|
⋮
|
||||||
⋮crate::nested
|
⋮crate::nested
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Baz: t v
|
⋮Baz: t
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,13 +91,13 @@ fn macro_rules_from_other_crates_are_visible() {
|
||||||
);
|
);
|
||||||
assert_snapshot!(map, @r###"
|
assert_snapshot!(map, @r###"
|
||||||
⋮crate
|
⋮crate
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: t
|
⋮bar: t
|
||||||
⋮
|
⋮
|
||||||
⋮crate::bar
|
⋮crate::bar
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: t
|
⋮bar: t
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
@ -124,13 +124,13 @@ fn macro_rules_export_with_local_inner_macros_are_visible() {
|
||||||
);
|
);
|
||||||
assert_snapshot!(map, @r###"
|
assert_snapshot!(map, @r###"
|
||||||
⋮crate
|
⋮crate
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: t
|
⋮bar: t
|
||||||
⋮
|
⋮
|
||||||
⋮crate::bar
|
⋮crate::bar
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: t
|
⋮bar: t
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
@ -161,13 +161,13 @@ fn local_inner_macros_makes_local_macros_usable() {
|
||||||
);
|
);
|
||||||
assert_snapshot!(map, @r###"
|
assert_snapshot!(map, @r###"
|
||||||
⋮crate
|
⋮crate
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: t
|
⋮bar: t
|
||||||
⋮
|
⋮
|
||||||
⋮crate::bar
|
⋮crate::bar
|
||||||
⋮Bar: t v
|
⋮Bar: t
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: t
|
⋮bar: t
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
|
||||||
);
|
);
|
||||||
assert_snapshot!(map, @r###"
|
assert_snapshot!(map, @r###"
|
||||||
⋮crate
|
⋮crate
|
||||||
⋮Foo: t v
|
⋮Foo: t
|
||||||
⋮bar: m
|
⋮bar: m
|
||||||
⋮foo: m
|
⋮foo: m
|
||||||
"###);
|
"###);
|
||||||
|
|
|
@ -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]
|
#[test]
|
||||||
fn issue_4053_diesel_where_clauses() {
|
fn issue_4053_diesel_where_clauses() {
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
|
|
Loading…
Reference in a new issue