Unreserve braced enum variants in value namespace

This commit is contained in:
Vadim Petrochenkov
2022-10-25 20:15:15 +04:00
parent 1cbc45942d
commit 7a5376d23c
71 changed files with 364 additions and 642 deletions

View File

@@ -747,7 +747,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// If this is a tuple or unit struct, define a name
// in the value namespace as well.
if let Some(ctor_node_id) = vdata.ctor_id() {
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(vdata) {
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
let mut ctor_vis = if vis.is_public()
@@ -773,10 +773,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
ret_fields.push(field_vis.to_def_id());
}
let ctor_def_id = self.r.local_def_id(ctor_node_id);
let ctor_res = Res::Def(
DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)),
ctor_def_id.to_def_id(),
);
let ctor_res =
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id());
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
self.r.visibilities.insert(ctor_def_id, ctor_vis);
@@ -999,8 +997,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
Res::Def(DefKind::Struct, def_id) => {
let field_names =
cstore.struct_field_names_untracked(def_id, self.r.session).collect();
let ctor = cstore.ctor_def_id_and_kind_untracked(def_id);
if let Some((ctor_def_id, ctor_kind)) = ctor {
if let Some((ctor_kind, ctor_def_id)) = cstore.ctor_untracked(def_id) {
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let ctor_vis = cstore.visibility_untracked(ctor_def_id);
let field_visibilities =
@@ -1517,20 +1514,20 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
};
// Define a constructor name in the value namespace.
// Braced variants, unlike structs, generate unusable names in
// value namespace, they are reserved for possible future use.
// It's ok to use the variant's id as a ctor id since an
// error will be reported on any use of such resolution anyway.
let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id);
let ctor_def_id = self.r.local_def_id(ctor_node_id);
let ctor_kind = CtorKind::from_ast(&variant.data);
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id());
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
if ctor_def_id != def_id {
let fields_id = if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) {
let ctor_def_id = self.r.local_def_id(ctor_node_id);
let ctor_res =
Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id());
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
self.r.visibilities.insert(ctor_def_id, ctor_vis);
}
ctor_def_id
} else {
def_id
};
// Record field names for error reporting.
self.insert_field_names_local(ctor_def_id.to_def_id(), &variant.data);
// FIXME: Always use non-ctor id as the key.
self.insert_field_names_local(fields_id.to_def_id(), &variant.data);
visit::walk_variant(self, variant);
}

View File

@@ -118,8 +118,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
match i.kind {
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
// If this is a unit or tuple-like struct, register the constructor.
if let Some(ctor_hir_id) = struct_def.ctor_id() {
this.create_def(ctor_hir_id, DefPathData::Ctor, i.span);
if let Some(ctor_node_id) = struct_def.ctor_node_id() {
this.create_def(ctor_node_id, DefPathData::Ctor, i.span);
}
}
_ => {}
@@ -196,8 +196,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
}
let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span);
self.with_parent(def, |this| {
if let Some(ctor_hir_id) = v.data.ctor_id() {
this.create_def(ctor_hir_id, DefPathData::Ctor, v.span);
if let Some(ctor_node_id) = v.data.ctor_node_id() {
this.create_def(ctor_node_id, DefPathData::Ctor, v.span);
}
visit::walk_variant(this, v)
});

View File

@@ -1442,13 +1442,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
err.span_label(span, "constructor is not visible here due to private fields");
}
(
Res::Def(
DefKind::Union | DefKind::Variant | DefKind::Ctor(_, CtorKind::Fictive),
def_id,
),
_,
) if ns == ValueNS => {
(Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => {
bad_struct_syntax_suggestion(def_id);
}
(Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => {
@@ -1963,7 +1957,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty());
match kind {
CtorKind::Const => false,
CtorKind::Fn | CtorKind::Fictive if has_no_fields => false,
CtorKind::Fn if has_no_fields => false,
_ => true,
}
};
@@ -1975,7 +1969,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.map(|(variant, kind)| match kind {
CtorKind::Const => variant,
CtorKind::Fn => format!("({}())", variant),
CtorKind::Fictive => format!("({} {{}})", variant),
})
.collect::<Vec<_>>();
let no_suggestable_variant = suggestable_variants.is_empty();
@@ -2001,7 +1994,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.map(|(variant, _, kind)| (path_names_to_string(variant), kind))
.filter_map(|(variant, kind)| match kind {
CtorKind::Fn => Some(format!("({}(/* fields */))", variant)),
CtorKind::Fictive => Some(format!("({} {{ /* fields */ }})", variant)),
_ => None,
})
.collect::<Vec<_>>();