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:
bors[bot] 2020-05-05 15:06:41 +00:00 committed by GitHub
commit 756e91732b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 28 deletions

View File

@ -573,9 +573,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 has_constructor = match def {
ModuleDefId::AdtId(AdtId::StructId(s)) => {
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),
);
}
}
}

View File

@ -151,13 +151,20 @@ pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {
}
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 {
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::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::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),

View File

@ -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 has_constructor = 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) => {
has_constructor = 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, has_constructor))],
vis,
)
}
fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) {

View File

@ -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<ast::FnDef>),
Struct(FileAstId<ast::StructDef>),
Struct(FileAstId<ast::StructDef>, StructDefKind),
Union(FileAstId<ast::UnionDef>),
Enum(FileAstId<ast::EnumDef>),
Const(FileAstId<ast::ConstDef>),
@ -171,7 +178,7 @@ impl DefKind {
pub fn ast_id(&self) -> FileAstId<ast::ModuleItem> {
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<Idx<ModuleData>>, 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);

View File

@ -67,7 +67,7 @@ enum E { V }
Baz: t v
E: t
EXT: v
U: t v
U: t
ext: v
"###)
}

View File

@ -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
"###);

View File

@ -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!(