Unify structures and enum variants in HIR
This commit is contained in:
parent
ea47c2b6b3
commit
2314ab29c2
@ -138,22 +138,11 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
NodeVariant(&**v),
|
||||
DefPathData::EnumVariant(v.node.name));
|
||||
|
||||
match v.node.kind {
|
||||
TupleVariantKind(ref args) => {
|
||||
for arg in args {
|
||||
self.create_def_with_parent(Some(variant_def_index),
|
||||
arg.id,
|
||||
DefPathData::PositionalField);
|
||||
}
|
||||
}
|
||||
StructVariantKind(ref def) => {
|
||||
for field in &def.fields {
|
||||
self.create_def_with_parent(
|
||||
Some(variant_def_index),
|
||||
field.node.id,
|
||||
DefPathData::Field(field.node.kind));
|
||||
}
|
||||
}
|
||||
for field in &v.node.def.fields {
|
||||
self.create_def_with_parent(
|
||||
Some(variant_def_index),
|
||||
field.node.id,
|
||||
DefPathData::Field(field.node.kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,13 +475,13 @@ impl<'ast> Map<'ast> {
|
||||
match self.find(id) {
|
||||
Some(NodeItem(i)) => {
|
||||
match i.node {
|
||||
ItemStruct(ref struct_def, _) => &**struct_def,
|
||||
ItemStruct(ref struct_def, _) => struct_def,
|
||||
_ => panic!("struct ID bound to non-struct")
|
||||
}
|
||||
}
|
||||
Some(NodeVariant(variant)) => {
|
||||
match variant.node.kind {
|
||||
StructVariantKind(ref struct_def) => &**struct_def,
|
||||
match variant.node.def.ctor_id {
|
||||
None => &variant.node.def,
|
||||
_ => panic!("struct ID bound to enum variant that isn't struct-like"),
|
||||
}
|
||||
}
|
||||
|
@ -435,24 +435,15 @@ pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod { abi, items }: ForeignMod,
|
||||
}
|
||||
|
||||
pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
|
||||
v.map(|Spanned { node: Variant_ { id, name, attrs, kind, disr_expr }, span }| {
|
||||
Spanned {
|
||||
node: Variant_ {
|
||||
id: fld.new_id(id),
|
||||
name: name,
|
||||
attrs: fold_attrs(attrs, fld),
|
||||
kind: match kind {
|
||||
TupleVariantKind(variant_args) => {
|
||||
TupleVariantKind(variant_args.move_map(|x| fld.fold_variant_arg(x)))
|
||||
}
|
||||
StructVariantKind(struct_def) => {
|
||||
StructVariantKind(fld.fold_struct_def(struct_def))
|
||||
}
|
||||
},
|
||||
disr_expr: disr_expr.map(|e| fld.fold_expr(e)),
|
||||
},
|
||||
span: fld.new_span(span),
|
||||
}
|
||||
v.map(|Spanned {node: Variant_ {id, name, attrs, def, disr_expr}, span}| Spanned {
|
||||
node: Variant_ {
|
||||
id: fld.new_id(id),
|
||||
name: name,
|
||||
attrs: fold_attrs(attrs, fld),
|
||||
def: fld.fold_struct_def(def),
|
||||
disr_expr: disr_expr.map(|e| fld.fold_expr(e)),
|
||||
},
|
||||
span: fld.new_span(span),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ pub struct EnumDef {
|
||||
pub struct Variant_ {
|
||||
pub name: Name,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub kind: VariantKind,
|
||||
pub def: P<StructDef>,
|
||||
pub id: NodeId,
|
||||
/// Explicit discriminant, eg `Foo = 1`
|
||||
pub disr_expr: Option<P<Expr>>,
|
||||
|
@ -267,16 +267,8 @@ pub fn lower_variant(_lctx: &LoweringContext, v: &Variant) -> P<hir::Variant> {
|
||||
id: v.node.id,
|
||||
name: v.node.name.name,
|
||||
attrs: v.node.attrs.clone(),
|
||||
kind: {
|
||||
if v.node.def.ctor_id.is_none() {
|
||||
hir::StructVariantKind(lower_struct_def(_lctx, &v.node.def))
|
||||
} else {
|
||||
hir::TupleVariantKind(v.node.def.fields.iter().map(|ref field| {
|
||||
hir::VariantArg { id: field.node.id, ty: lower_ty(_lctx, &field.node.ty) }
|
||||
}).collect())
|
||||
}
|
||||
},
|
||||
disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(_lctx, e)),
|
||||
def: lower_struct_def(_lctx, &v.node.def),
|
||||
disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(e)),
|
||||
},
|
||||
span: v.span,
|
||||
})
|
||||
|
@ -734,7 +734,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
hir::ItemStruct(ref struct_def, ref generics) => {
|
||||
try!(self.head(&visibility_qualified(item.vis, "struct")));
|
||||
try!(self.print_struct(&**struct_def, generics, item.name, item.span));
|
||||
try!(self.print_struct(&**struct_def, generics, item.name, item.span, true));
|
||||
}
|
||||
|
||||
hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
|
||||
@ -891,7 +891,8 @@ impl<'a> State<'a> {
|
||||
struct_def: &hir::StructDef,
|
||||
generics: &hir::Generics,
|
||||
name: ast::Name,
|
||||
span: codemap::Span)
|
||||
span: codemap::Span,
|
||||
print_finalizer: bool)
|
||||
-> io::Result<()> {
|
||||
try!(self.print_name(name));
|
||||
try!(self.print_generics(generics));
|
||||
@ -913,7 +914,9 @@ impl<'a> State<'a> {
|
||||
try!(self.pclose());
|
||||
}
|
||||
try!(self.print_where_clause(&generics.where_clause));
|
||||
try!(word(&mut self.s, ";"));
|
||||
if print_finalizer {
|
||||
try!(word(&mut self.s, ";"));
|
||||
}
|
||||
try!(self.end());
|
||||
self.end() // close the outer-box
|
||||
} else {
|
||||
@ -943,21 +946,9 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> {
|
||||
match v.node.kind {
|
||||
hir::TupleVariantKind(ref args) => {
|
||||
try!(self.print_name(v.node.name));
|
||||
if !args.is_empty() {
|
||||
try!(self.popen());
|
||||
try!(self.commasep(Consistent, &args[..], |s, arg| s.print_type(&*arg.ty)));
|
||||
try!(self.pclose());
|
||||
}
|
||||
}
|
||||
hir::StructVariantKind(ref struct_def) => {
|
||||
try!(self.head(""));
|
||||
let generics = ::util::empty_generics();
|
||||
try!(self.print_struct(&**struct_def, &generics, v.node.name, v.span));
|
||||
}
|
||||
}
|
||||
try!(self.head(""));
|
||||
let generics = ::util::empty_generics();
|
||||
try!(self.print_struct(&v.node.def, &generics, v.node.name, v.span, false));
|
||||
match v.node.disr_expr {
|
||||
Some(ref d) => {
|
||||
try!(space(&mut self.s));
|
||||
|
@ -333,20 +333,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
variant: &'v Variant,
|
||||
generics: &'v Generics) {
|
||||
visitor.visit_name(variant.span, variant.node.name);
|
||||
|
||||
match variant.node.kind {
|
||||
TupleVariantKind(ref variant_arguments) => {
|
||||
for variant_argument in variant_arguments {
|
||||
visitor.visit_ty(&variant_argument.ty)
|
||||
}
|
||||
}
|
||||
StructVariantKind(ref struct_definition) => {
|
||||
visitor.visit_struct_def(struct_definition,
|
||||
variant.node.name,
|
||||
generics,
|
||||
variant.node.id)
|
||||
}
|
||||
}
|
||||
visitor.visit_struct_def(&variant.node.def, variant.node.name, generics, variant.node.id);
|
||||
walk_list!(visitor, visit_expr, &variant.node.disr_expr);
|
||||
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
||||
}
|
||||
|
@ -49,8 +49,6 @@ use rustc_front::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaul
|
||||
use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
|
||||
use rustc_front::hir::{NamedField, PathListIdent, PathListMod, Public};
|
||||
use rustc_front::hir::StmtDecl;
|
||||
use rustc_front::hir::StructVariantKind;
|
||||
use rustc_front::hir::TupleVariantKind;
|
||||
use rustc_front::hir::UnnamedField;
|
||||
use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use rustc_front::hir::Visibility;
|
||||
@ -589,9 +587,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
item_id: DefId,
|
||||
parent: &Rc<Module>) {
|
||||
let name = variant.node.name;
|
||||
let is_exported = match variant.node.kind {
|
||||
TupleVariantKind(_) => false,
|
||||
StructVariantKind(_) => {
|
||||
let is_exported = match variant.node.def.ctor_id {
|
||||
Some(_) => false,
|
||||
None => {
|
||||
// Not adding fields for variants as they are not accessed with a self receiver
|
||||
let variant_def_id = self.ast_map.local_def_id(variant.node.id);
|
||||
self.structs.insert(variant_def_id, Vec::new());
|
||||
|
@ -501,19 +501,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// `visit::walk_variant` without the discriminant expression.
|
||||
match variant.node.kind {
|
||||
hir::TupleVariantKind(ref variant_arguments) => {
|
||||
for variant_argument in variant_arguments {
|
||||
self.visit_ty(&*variant_argument.ty);
|
||||
}
|
||||
}
|
||||
hir::StructVariantKind(ref struct_definition) => {
|
||||
self.visit_struct_def(&**struct_definition,
|
||||
variant.node.name,
|
||||
generics,
|
||||
variant.node.id);
|
||||
}
|
||||
}
|
||||
self.visit_struct_def(&variant.node.def, variant.node.name, generics, variant.node.id);
|
||||
}
|
||||
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
|
||||
execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
|
||||
|
@ -2428,13 +2428,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
||||
|
||||
hir_map::NodeVariant(ref v) => {
|
||||
let llfn;
|
||||
let args = match v.node.kind {
|
||||
hir::TupleVariantKind(ref args) => args,
|
||||
hir::StructVariantKind(_) => {
|
||||
ccx.sess().bug("struct variant kind unexpected in get_item_val")
|
||||
}
|
||||
let fields = if v.node.def.ctor_id.is_none() {
|
||||
ccx.sess().bug("struct variant kind unexpected in get_item_val")
|
||||
} else {
|
||||
&v.node.def.fields
|
||||
};
|
||||
assert!(!args.is_empty());
|
||||
assert!(!fields.is_empty());
|
||||
let ty = ccx.tcx().node_id_to_type(id);
|
||||
let parent = ccx.tcx().map.get_parent(id);
|
||||
let enm = ccx.tcx().map.expect_item(parent);
|
||||
|
@ -417,10 +417,9 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
||||
|| "local item should be in ast map".to_string());
|
||||
|
||||
match map_node {
|
||||
hir_map::NodeVariant(v) => match v.node.kind {
|
||||
hir::TupleVariantKind(ref args) => !args.is_empty(),
|
||||
_ => false
|
||||
},
|
||||
hir_map::NodeVariant(v) => {
|
||||
v.node.def.ctor_id.is_some() && !v.node.def.fields.is_empty()
|
||||
}
|
||||
hir_map::NodeStructCtor(_) => true,
|
||||
_ => false
|
||||
}
|
||||
|
@ -647,41 +647,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
enum_def: &hir::EnumDef)
|
||||
-> Vec<AdtVariant<'tcx>> {
|
||||
enum_def.variants.iter()
|
||||
.map(|variant| {
|
||||
match variant.node.kind {
|
||||
hir::TupleVariantKind(ref args) if !args.is_empty() => {
|
||||
let ctor_ty = fcx.tcx().node_id_to_type(variant.node.id);
|
||||
|
||||
// the regions in the argument types come from the
|
||||
// enum def'n, and hence will all be early bound
|
||||
let arg_tys = fcx.tcx().no_late_bound_regions(&ctor_ty.fn_args()).unwrap();
|
||||
AdtVariant {
|
||||
fields: args.iter().enumerate().map(|(index, arg)| {
|
||||
let arg_ty = arg_tys[index];
|
||||
let arg_ty =
|
||||
fcx.instantiate_type_scheme(variant.span,
|
||||
&fcx.inh
|
||||
.infcx
|
||||
.parameter_environment
|
||||
.free_substs,
|
||||
&arg_ty);
|
||||
AdtField {
|
||||
ty: arg_ty,
|
||||
span: arg.ty.span
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
hir::TupleVariantKind(_) => {
|
||||
AdtVariant {
|
||||
fields: Vec::new()
|
||||
}
|
||||
}
|
||||
hir::StructVariantKind(ref struct_def) => {
|
||||
struct_variant(fcx, &**struct_def)
|
||||
}
|
||||
}
|
||||
})
|
||||
.map(|variant| struct_variant(fcx, &variant.node.def))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -544,41 +544,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
enum_def: &hir::EnumDef)
|
||||
-> Vec<AdtVariant<'tcx>> {
|
||||
enum_def.variants.iter()
|
||||
.map(|variant| {
|
||||
match variant.node.kind {
|
||||
hir::TupleVariantKind(ref args) if !args.is_empty() => {
|
||||
let ctor_ty = fcx.tcx().node_id_to_type(variant.node.id);
|
||||
|
||||
// the regions in the argument types come from the
|
||||
// enum def'n, and hence will all be early bound
|
||||
let arg_tys = fcx.tcx().no_late_bound_regions(&ctor_ty.fn_args()).unwrap();
|
||||
AdtVariant {
|
||||
fields: args.iter().enumerate().map(|(index, arg)| {
|
||||
let arg_ty = arg_tys[index];
|
||||
let arg_ty =
|
||||
fcx.instantiate_type_scheme(variant.span,
|
||||
&fcx.inh
|
||||
.infcx
|
||||
.parameter_environment
|
||||
.free_substs,
|
||||
&arg_ty);
|
||||
AdtField {
|
||||
ty: arg_ty,
|
||||
span: arg.ty.span
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
hir::TupleVariantKind(_) => {
|
||||
AdtVariant {
|
||||
fields: Vec::new()
|
||||
}
|
||||
}
|
||||
hir::StructVariantKind(ref struct_def) => {
|
||||
struct_variant(fcx, &**struct_def)
|
||||
}
|
||||
}
|
||||
})
|
||||
.map(|variant| struct_variant(fcx, &variant.node.def))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -1065,31 +1065,16 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
scheme: ty::TypeScheme<'tcx>,
|
||||
predicates: ty::GenericPredicates<'tcx>,
|
||||
variants: &[P<hir::Variant>]) {
|
||||
let tcx = ccx.tcx;
|
||||
let icx = ccx.icx(&predicates);
|
||||
|
||||
// fill the field types
|
||||
for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
|
||||
match variant.node.kind {
|
||||
hir::TupleVariantKind(ref args) => {
|
||||
let rs = ExplicitRscope;
|
||||
let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
|
||||
for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
|
||||
field.fulfill_ty(ty);
|
||||
}
|
||||
}
|
||||
|
||||
hir::StructVariantKind(ref struct_def) => {
|
||||
for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
|
||||
convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
|
||||
}
|
||||
}
|
||||
};
|
||||
for (f, ty_f) in variant.node.def.fields.iter().zip(ty_variant.fields.iter()) {
|
||||
convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
|
||||
}
|
||||
|
||||
// Convert the ctor, if any. This also registers the variant as
|
||||
// an item.
|
||||
convert_variant_ctor(
|
||||
tcx,
|
||||
ccx.tcx,
|
||||
variant.node.id,
|
||||
ty_variant,
|
||||
scheme.clone(),
|
||||
@ -1223,25 +1208,7 @@ fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
{
|
||||
let did = tcx.map.local_def_id(v.node.id);
|
||||
let name = v.node.name;
|
||||
match v.node.kind {
|
||||
hir::TupleVariantKind(ref va) => {
|
||||
ty::VariantDefData {
|
||||
did: did,
|
||||
name: name,
|
||||
disr_val: disr,
|
||||
fields: va.iter().map(|&hir::VariantArg { id, .. }| {
|
||||
ty::FieldDefData::new(
|
||||
tcx.map.local_def_id(id),
|
||||
special_idents::unnamed_field.name,
|
||||
hir::Visibility::Public
|
||||
)
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
hir::StructVariantKind(ref def) => {
|
||||
convert_struct_variant(tcx, did, name, disr, &def)
|
||||
}
|
||||
}
|
||||
convert_struct_variant(tcx, did, name, disr, &v.node.def)
|
||||
}
|
||||
let did = tcx.map.local_def_id(it.id);
|
||||
let repr_hints = tcx.lookup_repr_hints(did);
|
||||
|
@ -1855,7 +1855,7 @@ impl Clean<Item> for doctree::Variant {
|
||||
stability: self.stab.clean(cx),
|
||||
def_id: cx.map.local_def_id(self.id),
|
||||
inner: VariantItem(Variant {
|
||||
kind: self.kind.clean(cx),
|
||||
kind: struct_def_to_variant_kind(&self.def, cx),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -1932,6 +1932,16 @@ impl Clean<VariantKind> for hir::VariantKind {
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_def_to_variant_kind(struct_def: &hir::StructDef, cx: &DocContext) -> VariantKind {
|
||||
if struct_def.ctor_id.is_none() {
|
||||
StructVariant(struct_def.clean(cx))
|
||||
} else if struct_def.fields.is_empty() {
|
||||
CLikeVariant
|
||||
} else {
|
||||
TupleVariant(struct_def.fields.iter().map(|x| x.node.ty.clean(cx)).collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Span {
|
||||
pub filename: String,
|
||||
|
@ -119,7 +119,7 @@ pub struct Enum {
|
||||
pub struct Variant {
|
||||
pub name: Name,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub kind: hir::VariantKind,
|
||||
pub def: P<hir::StructDef>,
|
||||
pub id: ast::NodeId,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub whence: Span,
|
||||
|
@ -113,7 +113,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
attrs: v.node.attrs.clone(),
|
||||
stab: self.stability(v.node.id),
|
||||
id: v.node.id,
|
||||
kind: v.node.kind.clone(),
|
||||
def: v.node.def.clone(),
|
||||
whence: v.span,
|
||||
}).collect(),
|
||||
vis: it.vis,
|
||||
|
Loading…
x
Reference in New Issue
Block a user