Remove CtorOf from Node::Ctor.

This commit removes `CtorOf` from `Node::Ctor` as the parent of the
constructor can be determined by looking at the node's parent in the few
places where knowing this is necessary.
This commit is contained in:
David Wood 2019-03-24 18:21:59 +01:00
parent 782a6debe4
commit db4770f699
No known key found for this signature in database
GPG Key ID: 01760B4F9F53F154
9 changed files with 63 additions and 50 deletions

View File

@ -362,9 +362,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
if let ItemKind::Struct(ref struct_def, _) = i.node {
// If this is a tuple or unit-like struct, register the constructor.
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
this.insert(i.span,
ctor_hir_id,
Node::Ctor(hir::CtorOf::Struct, struct_def));
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
}
}
intravisit::walk_item(this, i);
@ -521,7 +519,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
self.with_parent(v.node.id, |this| {
// Register the constructor of this variant.
if let Some(ctor_hir_id) = v.node.data.ctor_hir_id() {
this.insert(v.span, ctor_hir_id, Node::Ctor(hir::CtorOf::Variant, &v.node.data));
this.insert(v.span, ctor_hir_id, Node::Ctor(&v.node.data));
}
intravisit::walk_variant(this, v, g, item_id);
});

View File

@ -369,12 +369,15 @@ impl<'hir> Map<'hir> {
let def_id = self.local_def_id_from_hir_id(variant.node.id);
Some(Def::Variant(def_id))
}
Node::Ctor(ctor_of, variant_data) => {
Node::Ctor(variant_data) => {
let ctor_of = match self.find(self.get_parent_node(node_id)) {
Some(Node::Item(..)) => CtorOf::Struct,
Some(Node::Variant(..)) => CtorOf::Variant,
_ => unreachable!(),
};
variant_data.ctor_hir_id()
.map(|hir_id| self.local_def_id_from_hir_id(hir_id))
.map(|def_id| Def::Ctor(
ctor_of, def_id, def::CtorKind::from_hir(variant_data),
))
.map(|def_id| Def::Ctor(ctor_of, def_id, def::CtorKind::from_hir(variant_data)))
}
Node::AnonConst(_) |
Node::Field(_) |
@ -951,7 +954,7 @@ impl<'hir> Map<'hir> {
}
}
Some(Node::Variant(variant)) => &variant.node.data,
Some(Node::Ctor(_, data)) => data,
Some(Node::Ctor(data)) => data,
_ => bug!("expected struct or variant, found {}", self.hir_to_string(id))
}
}
@ -1070,10 +1073,11 @@ impl<'hir> Map<'hir> {
Some(Node::Binding(pat)) => pat.span,
Some(Node::Pat(pat)) => pat.span,
Some(Node::Block(block)) => block.span,
Some(Node::Ctor(CtorOf::Struct, _)) =>
self.expect_item(self.get_parent(id)).span,
Some(Node::Ctor(CtorOf::Variant, _)) =>
self.expect_variant(self.node_to_hir_id(self.get_parent_node(id))).span,
Some(Node::Ctor(..)) => match self.find(self.get_parent_node(id)) {
Some(Node::Item(item)) => item.span,
Some(Node::Variant(variant)) => variant.span,
_ => unreachable!(),
}
Some(Node::Lifetime(lifetime)) => lifetime.span,
Some(Node::GenericParam(param)) => param.span,
Some(Node::Visibility(&Spanned {

View File

@ -2590,7 +2590,7 @@ pub enum Node<'hir> {
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
/// with synthesized constructors.
Ctor(CtorOf, &'hir VariantData),
Ctor(&'hir VariantData),
Lifetime(&'hir Lifetime),
GenericParam(&'hir GenericParam),

View File

@ -1077,7 +1077,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
_ => ArgKind::empty()
}).collect::<Vec<ArgKind>>())
}
Node::Ctor(_, ref variant_data) => {
Node::Ctor(ref variant_data) => {
let span = variant_data.ctor_hir_id()
.map(|hir_id| self.tcx.hir().span_by_hir_id(hir_id))
.unwrap_or(DUMMY_SP);

View File

@ -85,7 +85,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
let owner_id = tcx.hir().as_local_hir_id(owner_def_id).unwrap();
match tcx.hir().get_by_hir_id(owner_id) {
Node::Ctor(_, _) => {
Node::Ctor(..) => {
// We get invoked with anything that has MIR, but some of
// those things (notably the synthesized constructors from
// tuple structs/variants) do not have an associated body

View File

@ -31,7 +31,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
// Figure out what primary body this item has.
let (body_id, return_ty_span) = match tcx.hir().get_by_hir_id(id) {
Node::Ctor(_, ctor) => return create_constructor_shim(tcx, id, ctor),
Node::Ctor(ctor) => return create_constructor_shim(tcx, id, ctor),
Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, decl, body_id, _, _), .. })
| Node::Item(hir::Item { node: hir::ItemKind::Fn(decl, _, _, body_id), .. })

View File

@ -225,7 +225,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
let vis = match tcx.hir().get_by_hir_id(hir_id) {
Node::Item(item) => &item.vis,
Node::ForeignItem(foreign_item) => &foreign_item.vis,
Node::TraitItem(..) | Node::Variant(..) | Node::Ctor(hir::CtorOf::Variant, ..) => {
Node::TraitItem(..) | Node::Variant(..) => {
return def_id_visibility(tcx, tcx.hir().get_parent_did_by_hir_id(hir_id));
}
Node::ImplItem(impl_item) => {
@ -239,36 +239,48 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
node => bug!("unexpected node kind: {:?}", node),
}
}
Node::Ctor(hir::CtorOf::Struct, vdata) => {
let struct_hir_id = tcx.hir().get_parent_item(hir_id);
let item = match tcx.hir().get_by_hir_id(struct_hir_id) {
Node::Item(item) => item,
Node::Ctor(vdata) => {
let parent_hir_id = tcx.hir().get_parent_node_by_hir_id(hir_id);
match tcx.hir().get_by_hir_id(parent_hir_id) {
Node::Variant(..) => {
let parent_did = tcx.hir().local_def_id_from_hir_id(parent_hir_id);
return def_id_visibility(tcx, parent_did);
}
Node::Item(..) => {
let item = match tcx.hir().get_by_hir_id(parent_hir_id) {
Node::Item(item) => item,
node => bug!("unexpected node kind: {:?}", node),
};
let (mut ctor_vis, mut span, mut descr) =
(ty::Visibility::from_hir(&item.vis, parent_hir_id, tcx),
item.vis.span, item.vis.node.descr());
for field in vdata.fields() {
let field_vis = ty::Visibility::from_hir(&field.vis, hir_id, tcx);
if ctor_vis.is_at_least(field_vis, tcx) {
ctor_vis = field_vis;
span = field.vis.span;
descr = field.vis.node.descr();
}
}
// If the structure is marked as non_exhaustive then lower the
// visibility to within the crate.
if ctor_vis == ty::Visibility::Public {
let adt_def =
tcx.adt_def(tcx.hir().get_parent_did_by_hir_id(hir_id));
if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
ctor_vis =
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
span = attr::find_by_name(&item.attrs, "non_exhaustive")
.unwrap().span;
descr = "crate-visible";
}
}
return (ctor_vis, span, descr);
}
node => bug!("unexpected node kind: {:?}", node),
};
let (mut ctor_vis, mut span, mut descr) =
(ty::Visibility::from_hir(&item.vis, struct_hir_id, tcx),
item.vis.span, item.vis.node.descr());
for field in vdata.fields() {
let field_vis = ty::Visibility::from_hir(&field.vis, hir_id, tcx);
if ctor_vis.is_at_least(field_vis, tcx) {
ctor_vis = field_vis;
span = field.vis.span;
descr = field.vis.node.descr();
}
}
// If the structure is marked as non_exhaustive then lower the
// visibility to within the crate.
if ctor_vis == ty::Visibility::Public {
let adt_def = tcx.adt_def(tcx.hir().get_parent_did_by_hir_id(hir_id));
if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
span = attr::find_by_name(&item.attrs, "non_exhaustive").unwrap().span;
descr = "crate-visible";
}
}
return (ctor_vis, span, descr);
}
Node::Expr(expr) => {
return (ty::Visibility::Restricted(

View File

@ -2,8 +2,7 @@ use std::cmp::Reverse;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use log::debug;
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def::Namespace::*;
use rustc::hir::def::{Def, CtorKind, Namespace::*};
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::session::config::nightly_options;
use syntax::ast::{ExprKind};

View File

@ -1247,7 +1247,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
ForeignItemKind::Type => tcx.mk_foreign(def_id),
},
Node::Ctor(_, &ref def) | Node::Variant(&Spanned {
Node::Ctor(&ref def) | Node::Variant(&Spanned {
node: hir::VariantKind { data: ref def, .. },
..
}) => match *def {
@ -1625,7 +1625,7 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
}
Ctor(_, data) | Variant(Spanned {
Ctor(data) | Variant(Spanned {
node: hir::VariantKind { data, .. },
..
}) if data.ctor_hir_id().is_some() => {