create VariantDef-s (but don't actually use them)
This commit is contained in:
parent
213b6d71f5
commit
4816e60667
7 changed files with 504 additions and 183 deletions
|
@ -222,10 +222,10 @@ pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDe
|
|||
decoder::get_trait_def(&*cdata, def.node, tcx)
|
||||
}
|
||||
|
||||
pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> &'tcx ty::ADTDef<'tcx> {
|
||||
pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> &'tcx ty::ADTDef_<'tcx, 'tcx> {
|
||||
let cstore = &tcx.sess.cstore;
|
||||
let cdata = cstore.get_crate_data(def.krate);
|
||||
decoder::get_adt_def(&*cdata, def.node, tcx)
|
||||
decoder::get_adt_def(&cstore.intr, &*cdata, def.node, tcx)
|
||||
}
|
||||
|
||||
pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
|
||||
|
|
|
@ -108,7 +108,7 @@ fn lookup_item<'a>(item_id: ast::NodeId, data: &'a [u8]) -> rbml::Doc<'a> {
|
|||
find_item(item_id, items)
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Family {
|
||||
ImmStatic, // c
|
||||
MutStatic, // b
|
||||
|
@ -390,12 +390,111 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_adt_def<'tcx>(cdata: Cmd,
|
||||
pub fn get_adt_def<'tcx>(intr: &IdentInterner,
|
||||
cdata: Cmd,
|
||||
item_id: ast::NodeId,
|
||||
tcx: &ty::ctxt<'tcx>) -> &'tcx ty::ADTDef<'tcx>
|
||||
tcx: &ty::ctxt<'tcx>) -> &'tcx ty::ADTDef_<'tcx, 'tcx>
|
||||
{
|
||||
tcx.intern_adt_def(ast::DefId { krate: cdata.cnum, node: item_id },
|
||||
ty::ADTKind::Enum)
|
||||
fn get_enum_variants<'tcx>(intr: &IdentInterner,
|
||||
cdata: Cmd,
|
||||
doc: rbml::Doc,
|
||||
tcx: &ty::ctxt<'tcx>) -> Vec<ty::VariantDef_<'tcx, 'tcx>> {
|
||||
let mut disr_val = 0;
|
||||
reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
|
||||
let did = translated_def_id(cdata, p);
|
||||
let item = lookup_item(did.node, cdata.data());
|
||||
|
||||
if let Some(disr) = variant_disr_val(item) {
|
||||
disr_val = disr;
|
||||
}
|
||||
let disr = disr_val;
|
||||
disr_val = disr_val.wrapping_add(1);
|
||||
|
||||
ty::VariantDef_ {
|
||||
did: did,
|
||||
name: item_name(intr, item),
|
||||
fields: get_variant_fields(intr, cdata, item, tcx),
|
||||
disr_val: disr
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
fn get_variant_fields<'tcx>(intr: &IdentInterner,
|
||||
cdata: Cmd,
|
||||
doc: rbml::Doc,
|
||||
tcx: &ty::ctxt<'tcx>) -> Vec<ty::FieldDef_<'tcx, 'tcx>> {
|
||||
reader::tagged_docs(doc, tag_item_field).map(|f| {
|
||||
let ff = item_family(f);
|
||||
match ff {
|
||||
PublicField | InheritedField => {},
|
||||
_ => tcx.sess.bug(&format!("expected field, found {:?}", ff))
|
||||
};
|
||||
ty::FieldDef_::new(item_def_id(f, cdata),
|
||||
item_name(intr, f),
|
||||
struct_field_family_to_visibility(ff))
|
||||
}).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| {
|
||||
let ff = item_family(f);
|
||||
ty::FieldDef_::new(item_def_id(f, cdata),
|
||||
special_idents::unnamed_field.name,
|
||||
struct_field_family_to_visibility(ff))
|
||||
})).collect()
|
||||
}
|
||||
fn get_struct_variant<'tcx>(intr: &IdentInterner,
|
||||
cdata: Cmd,
|
||||
doc: rbml::Doc,
|
||||
did: ast::DefId,
|
||||
tcx: &ty::ctxt<'tcx>) -> ty::VariantDef_<'tcx, 'tcx> {
|
||||
ty::VariantDef_ {
|
||||
did: did,
|
||||
name: item_name(intr, doc),
|
||||
fields: get_variant_fields(intr, cdata, doc, tcx),
|
||||
disr_val: 0
|
||||
}
|
||||
}
|
||||
|
||||
let doc = lookup_item(item_id, cdata.data());
|
||||
let did = ast::DefId { krate: cdata.cnum, node: item_id };
|
||||
let (kind, variants) = match item_family(doc) {
|
||||
Enum => (ty::ADTKind::Enum,
|
||||
get_enum_variants(intr, cdata, doc, tcx)),
|
||||
Struct => (ty::ADTKind::Struct,
|
||||
vec![get_struct_variant(intr, cdata, doc, did, tcx)]),
|
||||
_ => tcx.sess.bug("get_adt_def called on a non-ADT")
|
||||
};
|
||||
|
||||
let adt = tcx.intern_adt_def(did, kind, variants);
|
||||
|
||||
// this needs to be done *after* the variant is interned,
|
||||
// to support recursive structures
|
||||
for variant in &adt.variants {
|
||||
if variant.kind() == ty::VariantKind::Tuple &&
|
||||
adt.adt_kind() == ty::ADTKind::Enum {
|
||||
// tuple-like enum variant fields aren't real items - get the types
|
||||
// from the ctor.
|
||||
debug!("evaluating the ctor-type of {:?}",
|
||||
variant.name);
|
||||
let ctor_ty = get_type(cdata, variant.did.node, tcx).ty;
|
||||
debug!("evaluating the ctor-type of {:?}.. {:?}",
|
||||
variant.name,
|
||||
ctor_ty);
|
||||
let field_tys = match ctor_ty.sty {
|
||||
ty::TyBareFn(_, ref f) => &f.sig.skip_binder().inputs,
|
||||
_ => tcx.sess.bug("tuple-variant ctor is not an ADT")
|
||||
};
|
||||
for (field, &ty) in variant.fields.iter().zip(field_tys.iter()) {
|
||||
field.fulfill_ty(ty);
|
||||
}
|
||||
} else {
|
||||
for field in &variant.fields {
|
||||
debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
|
||||
let ty = get_type(cdata, field.did.node, tcx).ty;
|
||||
field.fulfill_ty(ty);
|
||||
debug!("evaluating the type of {:?}::{:?}: {:?}",
|
||||
variant.name, field.name, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adt
|
||||
}
|
||||
|
||||
pub fn get_predicates<'tcx>(cdata: Cmd,
|
||||
|
|
|
@ -41,7 +41,6 @@ use syntax::attr::AttrMetaMethods;
|
|||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
use syntax;
|
||||
|
@ -266,7 +265,7 @@ fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
|
|||
}
|
||||
|
||||
fn encode_struct_fields(rbml_w: &mut Encoder,
|
||||
fields: &[ty::FieldTy],
|
||||
fields: &[ty::FieldDef],
|
||||
origin: DefId) {
|
||||
for f in fields {
|
||||
if f.name == special_idents::unnamed_field.name {
|
||||
|
@ -276,7 +275,7 @@ fn encode_struct_fields(rbml_w: &mut Encoder,
|
|||
encode_name(rbml_w, f.name);
|
||||
}
|
||||
encode_struct_field_family(rbml_w, f.vis);
|
||||
encode_def_id(rbml_w, f.id);
|
||||
encode_def_id(rbml_w, f.did);
|
||||
rbml_w.wr_tagged_u64(tag_item_field_origin, def_to_u64(origin));
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
|
@ -285,57 +284,56 @@ fn encode_struct_fields(rbml_w: &mut Encoder,
|
|||
fn encode_enum_variant_info(ecx: &EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
id: NodeId,
|
||||
variants: &[P<ast::Variant>],
|
||||
vis: ast::Visibility,
|
||||
index: &mut Vec<entry<i64>>) {
|
||||
debug!("encode_enum_variant_info(id={})", id);
|
||||
|
||||
let mut disr_val = 0;
|
||||
let mut i = 0;
|
||||
let vi = ecx.tcx.enum_variants(local_def(id));
|
||||
for variant in variants {
|
||||
let def_id = local_def(variant.node.id);
|
||||
let def = ecx.tcx.lookup_adt_def(local_def(id));
|
||||
for variant in &def.variants {
|
||||
let vid = variant.did;
|
||||
assert!(is_local(vid));
|
||||
index.push(entry {
|
||||
val: variant.node.id as i64,
|
||||
val: vid.node as i64,
|
||||
pos: rbml_w.mark_stable_position(),
|
||||
});
|
||||
rbml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(rbml_w, def_id);
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(_) => encode_family(rbml_w, 'v'),
|
||||
ast::StructVariantKind(_) => encode_family(rbml_w, 'V')
|
||||
}
|
||||
encode_name(rbml_w, variant.node.name.name);
|
||||
encode_def_id(rbml_w, vid);
|
||||
encode_family(rbml_w, match variant.kind() {
|
||||
ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v',
|
||||
ty::VariantKind::Dict => 'V'
|
||||
});
|
||||
encode_name(rbml_w, variant.name);
|
||||
encode_parent_item(rbml_w, local_def(id));
|
||||
encode_visibility(rbml_w, variant.node.vis);
|
||||
encode_attributes(rbml_w, &variant.node.attrs);
|
||||
encode_repr_attrs(rbml_w, ecx, &variant.node.attrs);
|
||||
encode_visibility(rbml_w, vis);
|
||||
|
||||
let stab = stability::lookup(ecx.tcx, ast_util::local_def(variant.node.id));
|
||||
let attrs = ecx.tcx.get_attrs(vid);
|
||||
encode_attributes(rbml_w, &attrs);
|
||||
encode_repr_attrs(rbml_w, ecx, &attrs);
|
||||
|
||||
let stab = stability::lookup(ecx.tcx, vid);
|
||||
encode_stability(rbml_w, stab);
|
||||
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(_) => {},
|
||||
ast::StructVariantKind(_) => {
|
||||
let fields = ecx.tcx.lookup_struct_fields(def_id);
|
||||
let idx = encode_info_for_struct(ecx,
|
||||
rbml_w,
|
||||
&fields[..],
|
||||
index);
|
||||
encode_struct_fields(rbml_w, &fields[..], def_id);
|
||||
encode_index(rbml_w, idx, write_i64);
|
||||
}
|
||||
if let ty::VariantKind::Dict = variant.kind() {
|
||||
let idx = encode_info_for_struct(ecx,
|
||||
rbml_w,
|
||||
&variant.fields,
|
||||
index);
|
||||
encode_index(rbml_w, idx, write_i64);
|
||||
}
|
||||
let specified_disr_val = vi[i].disr_val;
|
||||
|
||||
encode_struct_fields(rbml_w, &variant.fields, vid);
|
||||
|
||||
let specified_disr_val = variant.disr_val;
|
||||
if specified_disr_val != disr_val {
|
||||
encode_disr_val(ecx, rbml_w, specified_disr_val);
|
||||
disr_val = specified_disr_val;
|
||||
}
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, def_id.local_id());
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, vid.node);
|
||||
|
||||
ecx.tcx.map.with_path(variant.node.id, |path| encode_path(rbml_w, path));
|
||||
ecx.tcx.map.with_path(vid.node, |path| encode_path(rbml_w, path));
|
||||
rbml_w.end_tag();
|
||||
disr_val = disr_val.wrapping_add(1);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,11 +628,11 @@ fn encode_provided_source(rbml_w: &mut Encoder,
|
|||
}
|
||||
|
||||
/* Returns an index of items in this class */
|
||||
fn encode_info_for_struct(ecx: &EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
fields: &[ty::FieldTy],
|
||||
global_index: &mut Vec<entry<i64>>)
|
||||
-> Vec<entry<i64>> {
|
||||
fn encode_info_for_struct<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
||||
rbml_w: &mut Encoder,
|
||||
fields: &[ty::FieldDef<'tcx>],
|
||||
global_index: &mut Vec<entry<i64>>)
|
||||
-> Vec<entry<i64>> {
|
||||
/* Each class has its own index, since different classes
|
||||
may have fields with the same name */
|
||||
let mut index = Vec::new();
|
||||
|
@ -642,7 +640,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
|
|||
private fields to get the offsets right */
|
||||
for field in fields {
|
||||
let nm = field.name;
|
||||
let id = field.id.node;
|
||||
let id = field.did.node;
|
||||
|
||||
let pos = rbml_w.mark_stable_position();
|
||||
index.push(entry {val: id as i64, pos: pos});
|
||||
|
@ -658,7 +656,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
|
|||
encode_bounds_and_type_for_item(rbml_w, ecx, id);
|
||||
encode_def_id(rbml_w, local_def(id));
|
||||
|
||||
let stab = stability::lookup(ecx.tcx, field.id);
|
||||
let stab = stability::lookup(ecx.tcx, field.did);
|
||||
encode_stability(rbml_w, stab);
|
||||
|
||||
rbml_w.end_tag();
|
||||
|
@ -1150,20 +1148,18 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_enum_variant_info(ecx,
|
||||
rbml_w,
|
||||
item.id,
|
||||
&(*enum_definition).variants,
|
||||
vis,
|
||||
index);
|
||||
}
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
let fields = tcx.lookup_struct_fields(def_id);
|
||||
let def = ecx.tcx.lookup_adt_def(def_id);
|
||||
let fields = &def.struct_variant().fields;
|
||||
|
||||
/* First, encode the fields
|
||||
These come first because we need to write them to make
|
||||
the index, and the index needs to be in the item for the
|
||||
class itself */
|
||||
let idx = encode_info_for_struct(ecx,
|
||||
rbml_w,
|
||||
&fields[..],
|
||||
index);
|
||||
let idx = encode_info_for_struct(ecx, rbml_w, &fields, index);
|
||||
|
||||
/* Index the class*/
|
||||
add_to_index(item, rbml_w, index);
|
||||
|
@ -1185,7 +1181,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
/* Encode def_ids for each field and method
|
||||
for methods, write all the stuff get_trait_method
|
||||
needs to know*/
|
||||
encode_struct_fields(rbml_w, &fields[..], def_id);
|
||||
encode_struct_fields(rbml_w, &fields, def_id);
|
||||
|
||||
encode_inlined_item(ecx, rbml_w, IIItemRef(item));
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
|
|||
&Variant(vid) =>
|
||||
(vid, cx.tcx.enum_variant_with_id(cid.did, vid).arg_names.is_some()),
|
||||
_ =>
|
||||
(cid.did, !cid.is_tuple_struct(cx.tcx))
|
||||
(cid.did, !cid.struct_variant().is_tuple_struct())
|
||||
};
|
||||
if is_structure {
|
||||
let fields = cx.tcx.lookup_struct_fields(vid);
|
||||
|
|
|
@ -74,10 +74,12 @@ use std::cell::{Cell, RefCell, Ref};
|
|||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, SipHasher, Hasher};
|
||||
use std::iter;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops;
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
use std::vec::IntoIter;
|
||||
use collections::enum_set::{self, EnumSet, CLike};
|
||||
use core::nonzero::NonZero;
|
||||
|
@ -90,7 +92,7 @@ use syntax::ast::{StructField, UnnamedField, Visibility};
|
|||
use syntax::ast_util::{self, is_local, local_def};
|
||||
use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::{self, InternedString, special_idents};
|
||||
use syntax::parse::token::{InternedString, special_idents};
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::ast;
|
||||
|
@ -211,7 +213,7 @@ impl DtorKind {
|
|||
}
|
||||
}
|
||||
|
||||
trait IntTypeExt {
|
||||
pub trait IntTypeExt {
|
||||
fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
|
||||
fn i64_to_disr(&self, val: i64) -> Option<Disr>;
|
||||
fn u64_to_disr(&self, val: u64) -> Option<Disr>;
|
||||
|
@ -852,7 +854,7 @@ pub struct ctxt<'tcx> {
|
|||
|
||||
pub impl_trait_refs: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
|
||||
pub trait_defs: RefCell<DefIdMap<&'tcx TraitDef<'tcx>>>,
|
||||
pub adt_defs: RefCell<DefIdMap<&'tcx ADTDef<'tcx>>>,
|
||||
pub adt_defs: RefCell<DefIdMap<&'tcx ADTDef_<'tcx, 'tcx>>>,
|
||||
|
||||
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
|
||||
/// associated predicates.
|
||||
|
@ -1023,8 +1025,12 @@ impl<'tcx> ctxt<'tcx> {
|
|||
interned
|
||||
}
|
||||
|
||||
pub fn intern_adt_def(&self, did: DefId, kind: ADTKind) -> &'tcx ADTDef_<'tcx, 'tcx> {
|
||||
let def = ADTDef_::new(self, did, kind);
|
||||
pub fn intern_adt_def(&self,
|
||||
did: DefId,
|
||||
kind: ADTKind,
|
||||
variants: Vec<VariantDef_<'tcx, 'tcx>>)
|
||||
-> &'tcx ADTDef_<'tcx, 'tcx> {
|
||||
let def = ADTDef_::new(self, did, kind, variants);
|
||||
let interned = self.arenas.adt_defs.alloc(def);
|
||||
// this will need a transmute when reverse-variance is removed
|
||||
self.adt_defs.borrow_mut().insert(did, interned);
|
||||
|
@ -2190,7 +2196,7 @@ pub struct ExistentialBounds<'tcx> {
|
|||
pub struct BuiltinBounds(EnumSet<BuiltinBound>);
|
||||
|
||||
impl BuiltinBounds {
|
||||
pub fn empty() -> BuiltinBounds {
|
||||
pub fn empty() -> BuiltinBounds {
|
||||
BuiltinBounds(EnumSet::new())
|
||||
}
|
||||
|
||||
|
@ -3274,17 +3280,21 @@ bitflags! {
|
|||
}
|
||||
|
||||
pub type ADTDef<'tcx> = ADTDef_<'tcx, 'static>;
|
||||
pub type VariantDef<'tcx> = VariantDef_<'tcx, 'static>;
|
||||
pub type FieldDef<'tcx> = FieldDef_<'tcx, 'static>;
|
||||
|
||||
pub struct VariantDef<'tcx, 'lt: 'tcx> {
|
||||
pub struct VariantDef_<'tcx, 'lt: 'tcx> {
|
||||
pub did: DefId,
|
||||
pub name: Name, // struct's name if this is a struct
|
||||
pub disr_val: Disr,
|
||||
pub fields: Vec<FieldDef<'tcx, 'lt>>
|
||||
pub fields: Vec<FieldDef_<'tcx, 'lt>>
|
||||
}
|
||||
|
||||
pub struct FieldDef<'tcx, 'lt: 'tcx> {
|
||||
pub struct FieldDef_<'tcx, 'lt: 'tcx> {
|
||||
pub did: DefId,
|
||||
pub name: Name, // XXX if tuple-like
|
||||
// special_idents::unnamed_field.name
|
||||
// if this is a tuple-like field
|
||||
pub name: Name,
|
||||
pub vis: ast::Visibility,
|
||||
// TyIVar is used here to allow for
|
||||
ty: TyIVar<'tcx, 'lt>
|
||||
|
@ -3294,7 +3304,7 @@ pub struct FieldDef<'tcx, 'lt: 'tcx> {
|
|||
/// is here so 'tcx can be variant.
|
||||
pub struct ADTDef_<'tcx, 'lt: 'tcx> {
|
||||
pub did: DefId,
|
||||
pub variants: Vec<VariantDef<'tcx, 'lt>>,
|
||||
pub variants: Vec<VariantDef_<'tcx, 'lt>>,
|
||||
flags: Cell<ADTFlags>,
|
||||
}
|
||||
|
||||
|
@ -3313,11 +3323,18 @@ impl<'tcx, 'lt> Hash for ADTDef_<'tcx, 'lt> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum ADTKind { Struct, Enum }
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum VariantKind { Dict, Tuple, Unit }
|
||||
|
||||
impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
|
||||
fn new(tcx: &ctxt<'tcx>, did: DefId, kind: ADTKind) -> Self {
|
||||
fn new(tcx: &ctxt<'tcx>,
|
||||
did: DefId,
|
||||
kind: ADTKind,
|
||||
variants: Vec<VariantDef_<'tcx, 'lt>>) -> Self {
|
||||
let mut flags = ADTFlags::NO_ADT_FLAGS;
|
||||
if tcx.has_attr(did, "fundamental") {
|
||||
flags = flags | ADTFlags::IS_FUNDAMENTAL;
|
||||
|
@ -3330,7 +3347,7 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
|
|||
}
|
||||
ADTDef {
|
||||
did: did,
|
||||
variants: vec![],
|
||||
variants: variants,
|
||||
flags: Cell::new(flags),
|
||||
}
|
||||
}
|
||||
|
@ -3374,9 +3391,9 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
|
|||
tcx.destructor_for_type.borrow().contains_key(&self.did)
|
||||
}
|
||||
|
||||
pub fn is_tuple_struct(&self, tcx: &ctxt<'tcx>) -> bool {
|
||||
let fields = tcx.lookup_struct_fields(self.did);
|
||||
!fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
|
||||
pub fn struct_variant(&self) -> &ty::VariantDef_<'tcx, 'lt> {
|
||||
assert!(self.adt_kind() == ADTKind::Struct);
|
||||
&self.variants[0]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -3388,6 +3405,104 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
|
|||
pub fn predicates(&self, tcx: &ctxt<'tcx>) -> GenericPredicates<'tcx> {
|
||||
tcx.lookup_predicates(self.did)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn all_fields(&self) ->
|
||||
iter::FlatMap<
|
||||
slice::Iter<VariantDef_<'tcx, 'lt>>,
|
||||
slice::Iter<FieldDef_<'tcx, 'lt>>,
|
||||
for<'s> fn(&'s VariantDef_<'tcx, 'lt>)
|
||||
-> slice::Iter<'s, FieldDef_<'tcx, 'lt>>
|
||||
> {
|
||||
self.variants.iter().flat_map(VariantDef_::fields_iter)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
// FIXME(#TODO(wxyz)): be smarter here
|
||||
self.variants.is_empty()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_univariant(&self) -> bool {
|
||||
self.variants.len() == 1
|
||||
}
|
||||
|
||||
pub fn is_payloadfree(&self) -> bool {
|
||||
!self.variants.is_empty() &&
|
||||
self.variants.iter().all(|v| v.fields.is_empty())
|
||||
}
|
||||
|
||||
pub fn variant_with_id(&self, vid: DefId) -> &VariantDef_<'tcx, 'lt> {
|
||||
self.variants
|
||||
.iter()
|
||||
.find(|v| v.did == vid)
|
||||
.expect("variant_with_id: unknown variant")
|
||||
}
|
||||
|
||||
pub fn variant_of_def(&self, def: def::Def) -> &VariantDef_<'tcx, 'lt> {
|
||||
match def {
|
||||
def::DefVariant(_, vid, _) => self.variant_with_id(vid),
|
||||
def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
|
||||
_ => panic!("unexpected def {:?} in variant_of_def", def)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'lt> VariantDef_<'tcx, 'lt> {
|
||||
#[inline]
|
||||
fn fields_iter(&self) -> slice::Iter<FieldDef_<'tcx, 'lt>> {
|
||||
self.fields.iter()
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> VariantKind {
|
||||
match self.fields.get(0) {
|
||||
None => VariantKind::Unit,
|
||||
Some(&FieldDef_ { name, .. }) if name == special_idents::unnamed_field.name => {
|
||||
VariantKind::Tuple
|
||||
}
|
||||
Some(_) => VariantKind::Dict
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_tuple_struct(&self) -> bool {
|
||||
self.kind() == VariantKind::Tuple
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn find_field_named(&self, name: ast::Name) -> Option<&FieldDef_<'tcx, 'lt>> {
|
||||
self.fields.iter().find(|f| f.name == name)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn field_named(&self, name: ast::Name) -> &FieldDef_<'tcx, 'lt> {
|
||||
self.find_field_named(name).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'lt> FieldDef_<'tcx, 'lt> {
|
||||
pub fn new(did: DefId,
|
||||
name: Name,
|
||||
vis: ast::Visibility) -> Self {
|
||||
FieldDef_ {
|
||||
did: did,
|
||||
name: name,
|
||||
vis: vis,
|
||||
ty: TyIVar::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ty(&self, tcx: &ctxt<'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
|
||||
self.unsubst_ty().subst(tcx, subst)
|
||||
}
|
||||
|
||||
pub fn unsubst_ty(&self) -> Ty<'tcx> {
|
||||
self.ty.unwrap()
|
||||
}
|
||||
|
||||
pub fn fulfill_ty(&self, ty: Ty<'lt>) {
|
||||
self.ty.fulfill(ty);
|
||||
}
|
||||
}
|
||||
|
||||
/// Records the substitutions used to translate the polytype for an
|
||||
|
@ -6132,7 +6247,7 @@ impl<'tcx> ctxt<'tcx> {
|
|||
}
|
||||
|
||||
/// Given the did of a trait, returns its canonical trait ref.
|
||||
pub fn lookup_adt_def(&self, did: ast::DefId) -> &'tcx ADTDef<'tcx> {
|
||||
pub fn lookup_adt_def(&self, did: ast::DefId) -> &'tcx ADTDef_<'tcx, 'tcx> {
|
||||
lookup_locally_or_in_crate_store(
|
||||
"adt_defs", did, &self.adt_defs,
|
||||
|| csearch::get_adt_def(self, did)
|
||||
|
|
|
@ -2980,7 +2980,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
|base_t, _| {
|
||||
match base_t.sty {
|
||||
ty::TyStruct(base_def, substs) => {
|
||||
tuple_like = base_def.is_tuple_struct(tcx);
|
||||
tuple_like = base_def.struct_variant().is_tuple_struct();
|
||||
if tuple_like {
|
||||
debug!("tuple struct named {:?}", base_t);
|
||||
let fields = tcx.lookup_struct_fields(base_def.did);
|
||||
|
|
|
@ -71,9 +71,12 @@ use middle::lang_items::SizedTraitLangItem;
|
|||
use middle::free_region::FreeRegionMap;
|
||||
use middle::region;
|
||||
use middle::resolve_lifetime;
|
||||
use middle::const_eval::{self, ConstVal};
|
||||
use middle::const_eval::EvalHint::UncheckedExprHint;
|
||||
use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
|
||||
use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
||||
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme};
|
||||
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme, IntTypeExt};
|
||||
use middle::ty::{VariantKind};
|
||||
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
|
||||
use middle::infer;
|
||||
use rscope::*;
|
||||
|
@ -89,8 +92,10 @@ use std::rc::Rc;
|
|||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::local_def;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit;
|
||||
|
||||
|
@ -563,48 +568,6 @@ fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
enum_scheme: ty::TypeScheme<'tcx>,
|
||||
enum_predicates: ty::GenericPredicates<'tcx>,
|
||||
variants: &[P<ast::Variant>]) {
|
||||
let tcx = ccx.tcx;
|
||||
let icx = ccx.icx(&enum_predicates);
|
||||
|
||||
// Create a set of parameter types shared among all the variants.
|
||||
for variant in variants {
|
||||
let variant_def_id = local_def(variant.node.id);
|
||||
|
||||
// Nullary enum constructors get turned into constants; n-ary enum
|
||||
// constructors get turned into functions.
|
||||
let result_ty = match variant.node.kind {
|
||||
ast::TupleVariantKind(ref args) if !args.is_empty() => {
|
||||
let rs = ExplicitRscope;
|
||||
let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
|
||||
tcx.mk_ctor_fn(variant_def_id, &input_tys, enum_scheme.ty)
|
||||
}
|
||||
|
||||
ast::TupleVariantKind(_) => {
|
||||
enum_scheme.ty
|
||||
}
|
||||
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
convert_struct(ccx, &**struct_def, enum_scheme.clone(),
|
||||
enum_predicates.clone(), variant.node.id);
|
||||
enum_scheme.ty
|
||||
}
|
||||
};
|
||||
|
||||
let variant_scheme = TypeScheme {
|
||||
generics: enum_scheme.generics.clone(),
|
||||
ty: result_ty
|
||||
};
|
||||
|
||||
tcx.register_item_type(variant_def_id, variant_scheme.clone());
|
||||
tcx.predicates.borrow_mut().insert(variant_def_id, enum_predicates.clone());
|
||||
write_ty_to_tcx(tcx, variant.node.id, result_ty);
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
container: ImplOrTraitItemContainer,
|
||||
sig: &ast::MethodSig,
|
||||
|
@ -657,10 +620,12 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
struct_generics: &ty::Generics<'tcx>,
|
||||
struct_predicates: &ty::GenericPredicates<'tcx>,
|
||||
v: &ast::StructField,
|
||||
ty_f: &'tcx ty::FieldDef_<'tcx, 'tcx>,
|
||||
origin: ast::DefId)
|
||||
-> ty::FieldTy
|
||||
{
|
||||
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
|
||||
ty_f.fulfill_ty(tt);
|
||||
write_ty_to_tcx(ccx.tcx, v.node.id, tt);
|
||||
|
||||
/* add the field to the tcache */
|
||||
|
@ -803,10 +768,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
ast::ItemEnum(ref enum_definition, _) => {
|
||||
let (scheme, predicates) = convert_typed_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, scheme.ty);
|
||||
get_enum_variant_types(ccx,
|
||||
scheme,
|
||||
predicates,
|
||||
&enum_definition.variants);
|
||||
convert_enum_variant_types(ccx,
|
||||
tcx.lookup_adt_def(local_def(it.id)),
|
||||
scheme,
|
||||
predicates,
|
||||
&enum_definition.variants);
|
||||
},
|
||||
ast::ItemDefaultImpl(_, ref ast_trait_ref) => {
|
||||
let trait_ref =
|
||||
|
@ -1048,10 +1014,14 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
}
|
||||
},
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
// Write the class type.
|
||||
let (scheme, predicates) = convert_typed_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, scheme.ty);
|
||||
convert_struct(ccx, &**struct_def, scheme, predicates, it.id);
|
||||
|
||||
let variant = tcx.lookup_adt_def(local_def(it.id)).struct_variant();
|
||||
convert_struct_variant_types(ccx, &struct_def, variant, &scheme, &predicates);
|
||||
if let Some(ctor_id) = struct_def.ctor_id {
|
||||
convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
|
||||
}
|
||||
},
|
||||
ast::ItemTy(_, ref generics) => {
|
||||
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
|
||||
|
@ -1068,74 +1038,216 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
struct_def: &ast::StructDef,
|
||||
scheme: ty::TypeScheme<'tcx>,
|
||||
predicates: ty::GenericPredicates<'tcx>,
|
||||
id: ast::NodeId) {
|
||||
fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
ctor_id: ast::NodeId,
|
||||
variant: &'tcx ty::VariantDef<'tcx>,
|
||||
scheme: ty::TypeScheme<'tcx>,
|
||||
predicates: ty::GenericPredicates<'tcx>) {
|
||||
let ctor_ty = match variant.kind() {
|
||||
VariantKind::Unit | VariantKind::Dict => scheme.ty,
|
||||
VariantKind::Tuple => {
|
||||
let inputs: Vec<_> =
|
||||
variant.fields
|
||||
.iter()
|
||||
.map(|field| field.unsubst_ty())
|
||||
.collect();
|
||||
tcx.mk_ctor_fn(local_def(ctor_id),
|
||||
&inputs[..],
|
||||
scheme.ty)
|
||||
}
|
||||
};
|
||||
write_ty_to_tcx(tcx, ctor_id, ctor_ty);
|
||||
tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates);
|
||||
tcx.register_item_type(local_def(ctor_id),
|
||||
TypeScheme {
|
||||
generics: scheme.generics,
|
||||
ty: ctor_ty
|
||||
});
|
||||
}
|
||||
|
||||
fn convert_struct_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
def: &ast::StructDef,
|
||||
variant: &'tcx ty::VariantDef_<'tcx, 'tcx>,
|
||||
scheme: &ty::TypeScheme<'tcx>,
|
||||
predicates: &ty::GenericPredicates<'tcx>) {
|
||||
let field_tys = def.fields.iter().zip(variant.fields.iter()).map(|(f, ty_f)| {
|
||||
convert_field(ccx, &scheme.generics, &predicates, f, ty_f, variant.did)
|
||||
}).collect();
|
||||
ccx.tcx.struct_fields.borrow_mut().insert(variant.did, Rc::new(field_tys));
|
||||
}
|
||||
|
||||
fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
def: &'tcx ty::ADTDef_<'tcx, 'tcx>,
|
||||
scheme: ty::TypeScheme<'tcx>,
|
||||
predicates: ty::GenericPredicates<'tcx>,
|
||||
variants: &[P<ast::Variant>]) {
|
||||
let tcx = ccx.tcx;
|
||||
let icx = ccx.icx(&predicates);
|
||||
|
||||
// Write the type of each of the members and check for duplicate fields.
|
||||
// Create a set of parameter types shared among all the variants.
|
||||
for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
|
||||
match variant.node.kind {
|
||||
ast::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);
|
||||
}
|
||||
}
|
||||
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
convert_struct_variant_types(ccx, &struct_def, ty_variant, &scheme, &predicates);
|
||||
}
|
||||
};
|
||||
|
||||
convert_variant_ctor(
|
||||
tcx,
|
||||
variant.node.id,
|
||||
ty_variant,
|
||||
scheme.clone(),
|
||||
predicates.clone()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
did: ast::DefId,
|
||||
name: ast::Name,
|
||||
disr_val: ty::Disr,
|
||||
def: &ast::StructDef) -> ty::VariantDef_<'tcx, 'tcx> {
|
||||
let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
|
||||
let field_tys = struct_def.fields.iter().map(|f| {
|
||||
let result = convert_field(ccx, &scheme.generics, &predicates, f, local_def(id));
|
||||
|
||||
if result.name != special_idents::unnamed_field.name {
|
||||
let dup = match seen_fields.get(&result.name) {
|
||||
Some(prev_span) => {
|
||||
let fields = def.fields.iter().map(|f| {
|
||||
let fid = local_def(f.node.id);
|
||||
match f.node.kind {
|
||||
ast::NamedField(ident, vis) => {
|
||||
let dup_span = seen_fields.get(&ident.name).cloned();
|
||||
if let Some(prev_span) = dup_span {
|
||||
span_err!(tcx.sess, f.span, E0124,
|
||||
"field `{}` is already declared",
|
||||
result.name);
|
||||
span_note!(tcx.sess, *prev_span, "previously declared here");
|
||||
true
|
||||
},
|
||||
None => false,
|
||||
};
|
||||
// FIXME(#6393) this whole dup thing is just to satisfy
|
||||
// the borrow checker :-(
|
||||
if !dup {
|
||||
seen_fields.insert(result.name, f.span);
|
||||
ident.name);
|
||||
span_note!(tcx.sess, prev_span, "previously declared here");
|
||||
} else {
|
||||
seen_fields.insert(ident.name, f.span);
|
||||
}
|
||||
|
||||
ty::FieldDef_::new(fid, ident.name, vis)
|
||||
},
|
||||
ast::UnnamedField(vis) => {
|
||||
ty::FieldDef_::new(fid, special_idents::unnamed_field.name, vis)
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}).collect();
|
||||
ty::VariantDef_ {
|
||||
did: did,
|
||||
name: name,
|
||||
disr_val: disr_val,
|
||||
fields: fields
|
||||
}
|
||||
}
|
||||
|
||||
tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys));
|
||||
fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
it: &ast::Item,
|
||||
def: &ast::StructDef)
|
||||
-> &'tcx ty::ADTDef_<'tcx, 'tcx>
|
||||
{
|
||||
|
||||
let did = local_def(it.id);
|
||||
tcx.intern_adt_def(
|
||||
did,
|
||||
ty::ADTKind::Struct,
|
||||
vec![convert_struct_variant(tcx, did, it.ident.name, 0, def)]
|
||||
)
|
||||
}
|
||||
|
||||
// If this struct is enum-like or tuple-like, create the type of its
|
||||
// constructor.
|
||||
if let Some(ctor_id) = struct_def.ctor_id {
|
||||
let substs = mk_item_substs(ccx, &scheme.generics);
|
||||
let selfty = tcx.mk_struct(tcx.lookup_adt_def(local_def(id)),
|
||||
tcx.mk_substs(substs));
|
||||
if struct_def.fields.is_empty() {
|
||||
// Enum-like.
|
||||
write_ty_to_tcx(tcx, ctor_id, selfty);
|
||||
fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
it: &ast::Item,
|
||||
def: &ast::EnumDef)
|
||||
-> &'tcx ty::ADTDef_<'tcx, 'tcx>
|
||||
{
|
||||
fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
repr_ty: Ty<'tcx>,
|
||||
e: &ast::Expr) -> Option<ty::Disr> {
|
||||
debug!("disr expr, checking {}", pprust::expr_to_string(e));
|
||||
|
||||
tcx.register_item_type(local_def(ctor_id), scheme);
|
||||
tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates);
|
||||
} else if struct_def.fields[0].node.kind.is_unnamed() {
|
||||
// Tuple-like.
|
||||
let inputs: Vec<_> =
|
||||
struct_def.fields
|
||||
.iter()
|
||||
.map(|field| tcx.lookup_item_type(
|
||||
local_def(field.node.id)).ty)
|
||||
.collect();
|
||||
let ctor_fn_ty = tcx.mk_ctor_fn(local_def(ctor_id),
|
||||
&inputs[..],
|
||||
selfty);
|
||||
write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
|
||||
tcx.register_item_type(local_def(ctor_id),
|
||||
TypeScheme {
|
||||
generics: scheme.generics,
|
||||
ty: ctor_fn_ty
|
||||
});
|
||||
tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates);
|
||||
let hint = UncheckedExprHint(repr_ty);
|
||||
match const_eval::eval_const_expr_partial(tcx, e, hint) {
|
||||
Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
|
||||
Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
|
||||
Ok(_) => {
|
||||
// let sign_desc = if repr_type.is_signed() {
|
||||
// "signed"
|
||||
// } else {
|
||||
// "unsigned"
|
||||
// };
|
||||
// span_err!(self.sess, e.span, E0079,
|
||||
// "expected {} integer constant",
|
||||
// sign_desc);
|
||||
None
|
||||
},
|
||||
Err(_) => {
|
||||
// span_err!(self.sess, err.span, E0080,
|
||||
// "constant evaluation error: {}",
|
||||
// err.description());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next_disr(repr_type: attr::IntType,
|
||||
prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
|
||||
if let Some(prev_disr_val) = prev_disr_val {
|
||||
let result = repr_type.disr_incr(prev_disr_val);
|
||||
// if let None = result {
|
||||
// self.report_discrim_overflow(v.span, &v.node.name.name.as_str(),
|
||||
// repr_type, prev_disr_val);
|
||||
// }
|
||||
result
|
||||
} else {
|
||||
Some(ty::INITIAL_DISCRIMINANT_VALUE)
|
||||
}
|
||||
}
|
||||
fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
v: &ast::Variant,
|
||||
disr: ty::Disr)
|
||||
-> ty::VariantDef_<'tcx, 'tcx>
|
||||
{
|
||||
let did = local_def(v.node.id);
|
||||
let name = v.node.name.name;
|
||||
match v.node.kind {
|
||||
ast::TupleVariantKind(ref va) => {
|
||||
ty::VariantDef_ {
|
||||
did: did,
|
||||
name: name,
|
||||
disr_val: disr,
|
||||
fields: va.iter().map(|&ast::VariantArg { id, .. }| {
|
||||
ty::FieldDef_::new(
|
||||
local_def(id),
|
||||
special_idents::unnamed_field.name,
|
||||
ast::Visibility::Public
|
||||
)
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
ast::StructVariantKind(ref def) => {
|
||||
convert_struct_variant(tcx, did, name, disr, &def)
|
||||
}
|
||||
}
|
||||
}
|
||||
let did = local_def(it.id);
|
||||
let repr_hints = tcx.lookup_repr_hints(did);
|
||||
let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
|
||||
let mut prev_disr = None;
|
||||
let variants = def.variants.iter().map(|v| {
|
||||
let disr = match v.node.disr_expr {
|
||||
Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
|
||||
None => next_disr(repr_type, prev_disr)
|
||||
}.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
|
||||
|
||||
let v = convert_enum_variant(tcx, v, disr);
|
||||
prev_disr = Some(disr);
|
||||
v
|
||||
}).collect();
|
||||
tcx.intern_adt_def(local_def(it.id), ty::ADTKind::Enum, variants)
|
||||
}
|
||||
|
||||
/// Ensures that the super-predicates of the trait with def-id
|
||||
|
@ -1469,18 +1581,17 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||
let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
|
||||
ty::TypeScheme { ty: ty, generics: ty_generics }
|
||||
}
|
||||
ast::ItemEnum(_, ref generics) => {
|
||||
// Create a new generic polytype.
|
||||
ast::ItemEnum(ref ei, ref generics) => {
|
||||
let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
|
||||
let substs = mk_item_substs(ccx, &ty_generics);
|
||||
let def = tcx.intern_adt_def(local_def(it.id), ty::ADTKind::Enum);
|
||||
let def = convert_enum_def(tcx, it, ei);
|
||||
let t = tcx.mk_enum(def, tcx.mk_substs(substs));
|
||||
ty::TypeScheme { ty: t, generics: ty_generics }
|
||||
}
|
||||
ast::ItemStruct(_, ref generics) => {
|
||||
ast::ItemStruct(ref si, ref generics) => {
|
||||
let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
|
||||
let substs = mk_item_substs(ccx, &ty_generics);
|
||||
let def = tcx.intern_adt_def(local_def(it.id), ty::ADTKind::Struct);
|
||||
let def = convert_struct_def(tcx, it, si);
|
||||
let t = tcx.mk_struct(def, tcx.mk_substs(substs));
|
||||
ty::TypeScheme { ty: t, generics: ty_generics }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue