Skip to content

Commit 63be9d7

Browse files
author
Ariel Ben-Yehuda
committed
it works!
1 parent 1e18676 commit 63be9d7

File tree

15 files changed

+85
-55
lines changed

15 files changed

+85
-55
lines changed

src/librustc/metadata/decoder.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -466,12 +466,31 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
466466
// this needs to be done *after* the variant is interned,
467467
// to support recursive structures
468468
for variant in &adt.variants {
469-
for field in &variant.fields {
470-
debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
471-
let ty = get_type(cdata, field.did.node, tcx).ty;
472-
field.fulfill_ty(ty);
473-
debug!("evaluating the type of {:?}::{:?}: {:?}",
474-
variant.name, field.name, ty);
469+
if variant.kind() == ty::VariantKind::Tuple &&
470+
adt.adt_kind() == ty::ADTKind::Enum {
471+
// tuple-like enum variant fields aren't real items - get the types
472+
// from the ctor.
473+
debug!("evaluating the ctor-type of {:?}",
474+
variant.name);
475+
let ctor_ty = get_type(cdata, variant.did.node, tcx).ty;
476+
debug!("evaluating the ctor-type of {:?}.. {:?}",
477+
variant.name,
478+
ctor_ty);
479+
let field_tys = match ctor_ty.sty {
480+
ty::TyBareFn(_, ref f) => &f.sig.skip_binder().inputs,
481+
_ => tcx.sess.bug("tuple-variant ctor is not an ADT")
482+
};
483+
for (field, &ty) in variant.fields.iter().zip(field_tys.iter()) {
484+
field.fulfill_ty(ty);
485+
}
486+
} else {
487+
for field in &variant.fields {
488+
debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
489+
let ty = get_type(cdata, field.did.node, tcx).ty;
490+
field.fulfill_ty(ty);
491+
debug!("evaluating the type of {:?}::{:?}: {:?}",
492+
variant.name, field.name, ty);
493+
}
475494
}
476495
}
477496

src/librustc/metadata/encoder.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,11 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
319319
rbml_w,
320320
&variant.fields,
321321
index);
322-
encode_struct_fields(rbml_w, &variant.fields, vid);
323322
encode_index(rbml_w, idx, write_i64);
324323
}
324+
325+
encode_struct_fields(rbml_w, &variant.fields, vid);
326+
325327
let specified_disr_val = variant.disr_val;
326328
if specified_disr_val != disr_val {
327329
encode_disr_val(ecx, rbml_w, specified_disr_val);

src/librustc/middle/cast.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ pub enum CastKind {
5858
}
5959

6060
impl<'tcx> CastTy<'tcx> {
61-
pub fn from_ty(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>)
62-
-> Option<CastTy<'tcx>> {
61+
pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
6362
match t.sty {
6463
ty::TyBool => Some(CastTy::Int(IntTy::Bool)),
6564
ty::TyChar => Some(CastTy::Int(IntTy::Char)),

src/librustc/middle/check_match.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,8 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
898898
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
899899
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
900900
let variant = adt.variant_of_ctor(constructor);
901-
if variant.did == def.def_id() {
901+
let def_variant = adt.variant_of_def(def);
902+
if variant.did == def_variant.did {
902903
Some(variant.fields.iter().map(|sf| {
903904
match pattern_fields.iter().find(|f| f.node.ident.name == sf.name) {
904905
Some(ref f) => &*f.node.pat,

src/librustc/middle/dead.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
110110
fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) {
111111
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
112112
self.live_symbols.insert(def.struct_variant().fields[idx].did.node);
113-
} else {
114-
self.tcx.sess.span_bug(lhs.span, "indexed field access on non-struct")
115113
}
116114
}
117115

src/librustc/middle/ty.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3287,6 +3287,8 @@ pub struct VariantDef_<'tcx, 'lt: 'tcx> {
32873287
}
32883288

32893289
pub struct FieldDef_<'tcx, 'lt: 'tcx> {
3290+
/// The field's def-id. Be aware that tuple-like enum fields
3291+
/// are currently not real items (you can't e.g. lookup_item_type them).
32903292
pub did: DefId,
32913293
// special_idents::unnamed_field.name
32923294
// if this is a tuple-like field
@@ -3424,7 +3426,8 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
34243426
}
34253427

34263428
pub fn is_payloadfree(&self) -> bool {
3427-
self.variants.iter().all(|v| v.fields.is_empty())
3429+
!self.variants.is_empty() &&
3430+
self.variants.iter().all(|v| v.fields.is_empty())
34283431
}
34293432

34303433
pub fn variant_with_id(&self, vid: DefId) -> &VariantDef_<'tcx, 'lt> {
@@ -3437,11 +3440,8 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
34373440
pub fn variant_of_def(&self, def: def::Def) -> &VariantDef_<'tcx, 'lt> {
34383441
match def {
34393442
def::DefVariant(_, vid, _) => self.variant_with_id(vid),
3440-
def::DefStruct(..) => self.struct_variant(),
3441-
_ => {
3442-
debug!("unexpected def {:?} in variant_of_def", def);
3443-
unreachable!()
3444-
}
3443+
def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
3444+
_ => panic!("unexpected def {:?} in variant_of_def", def)
34453445
}
34463446
}
34473447
}

src/librustc_lint/builtin.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,13 @@ fn is_repr_nullable_ptr<'tcx>(tcx: &ty::ctxt<'tcx>,
417417
substs: &Substs<'tcx>)
418418
-> bool {
419419
if def.variants.len() == 2 {
420-
let mut data_idx = 0;
420+
let data_idx;
421421

422422
if def.variants[0].fields.is_empty() {
423423
data_idx = 1;
424-
} else if !def.variants[1].fields.is_empty() {
424+
} else if def.variants[1].fields.is_empty() {
425+
data_idx = 0;
426+
} else {
425427
return false;
426428
}
427429

src/librustc_privacy/lib.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -913,18 +913,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
913913
}
914914
ast::ExprPath(..) => {
915915
if let def::DefStruct(_) = self.tcx.resolve_expr(expr) {
916-
if let ty::TyStruct(def, _) = self.tcx.expr_ty(expr).sty {
917-
let fields = &def.struct_variant().fields;
918-
let any_priv = fields.iter().any(|f| {
919-
f.vis != ast::Public && (
920-
!is_local(f.did) ||
916+
let expr_ty = self.tcx.expr_ty(expr);
917+
let def = match expr_ty.sty {
918+
ty::TyBareFn(_, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
919+
output: ty::FnConverging(ty), ..
920+
}), ..}) => ty,
921+
_ => expr_ty
922+
}.ty_adt_def().unwrap();
923+
let any_priv = def.struct_variant().fields.iter().any(|f| {
924+
f.vis != ast::Public && (
925+
!is_local(f.did) ||
921926
!self.private_accessible(f.did.node))
922927
});
923-
if any_priv {
924-
self.tcx.sess.span_err(expr.span,
925-
"cannot invoke tuple struct constructor \
926-
with private fields");
927-
}
928+
if any_priv {
929+
self.tcx.sess.span_err(expr.span,
930+
"cannot invoke tuple struct construcor \
931+
with private fields");
928932
}
929933
}
930934
}

src/librustc_trans/trans/common.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use std::cell::{Cell, RefCell};
4949
use std::result::Result as StdResult;
5050
use std::vec::Vec;
5151
use syntax::ast;
52+
use syntax::ast_util::local_def;
5253
use syntax::codemap::{DUMMY_SP, Span};
5354
use syntax::parse::token::InternedString;
5455
use syntax::parse::token;
@@ -282,14 +283,14 @@ pub struct VariantInfo<'tcx> {
282283
impl<'tcx> VariantInfo<'tcx> {
283284
pub fn from_ty(tcx: &ty::ctxt<'tcx>,
284285
ty: Ty<'tcx>,
285-
opt_vid: Option<ast::DefId>)
286+
opt_def: Option<def::Def>)
286287
-> Self
287288
{
288289
match ty.sty {
289290
ty::TyStruct(adt, substs) | ty::TyEnum(adt, substs) => {
290-
let variant = match opt_vid {
291+
let variant = match opt_def {
291292
None => adt.struct_variant(),
292-
Some(vid) => adt.variant_with_id(vid)
293+
Some(def) => adt.variant_of_def(def)
293294
};
294295

295296
VariantInfo {
@@ -319,8 +320,8 @@ impl<'tcx> VariantInfo<'tcx> {
319320

320321
/// Return the variant corresponding to a given node (e.g. expr)
321322
pub fn of_node(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, id: ast::NodeId) -> Self {
322-
let vid = tcx.def_map.borrow().get(&id).unwrap().full_def().def_id();
323-
Self::from_ty(tcx, ty, Some(vid))
323+
let node_def = tcx.def_map.borrow().get(&id).map(|v| v.full_def());
324+
Self::from_ty(tcx, ty, node_def)
324325
}
325326

326327
pub fn field_index(&self, name: ast::Name) -> usize {
@@ -1243,9 +1244,18 @@ pub fn inlined_variant_def<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
12431244
inlined_vid: ast::NodeId)
12441245
-> &'tcx ty::VariantDef<'tcx>
12451246
{
1246-
let adt_def = ccx.tcx().node_id_to_type(inlined_vid).ty_adt_def().unwrap();
1247+
let ctor_ty = ccx.tcx().node_id_to_type(inlined_vid);
1248+
debug!("inlined_variant_def: ctor_ty={:?} inlined_vid={:?}", ctor_ty,
1249+
inlined_vid);
1250+
let adt_def = match ctor_ty.sty {
1251+
ty::TyBareFn(_, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
1252+
output: ty::FnConverging(ty), ..
1253+
}), ..}) => ty,
1254+
_ => ctor_ty
1255+
}.ty_adt_def().unwrap();
12471256
adt_def.variants.iter().find(|v| {
1248-
ccx.external().borrow().get(&v.did) == Some(&Some(inlined_vid))
1257+
local_def(inlined_vid) == v.did ||
1258+
ccx.external().borrow().get(&v.did) == Some(&Some(inlined_vid))
12491259
}).unwrap_or_else(|| {
12501260
ccx.sess().bug(&format!("no variant for {:?}::{}", adt_def, inlined_vid))
12511261
})

src/librustc_trans/trans/consts.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
662662
}
663663
}
664664
unsafe { match (
665-
CastTy::from_ty(cx.tcx(), t_expr).expect("bad input type for cast"),
666-
CastTy::from_ty(cx.tcx(), t_cast).expect("bad output type for cast"),
665+
CastTy::from_ty(t_expr).expect("bad input type for cast"),
666+
CastTy::from_ty(t_cast).expect("bad output type for cast"),
667667
) {
668668
(CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
669669
let repr = adt::represent_type(cx, t_expr);
@@ -747,8 +747,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
747747
};
748748

749749
let VariantInfo { discr, fields } = VariantInfo::of_node(cx.tcx(), ety, e.id);
750-
751-
let cs = fields.iter().enumerate().map(|(ix, &Field(f_name, f_ty))| {
750+
let cs = fields.iter().enumerate().map(|(ix, &Field(f_name, _))| {
752751
match (fs.iter().find(|f| f_name == f.ident.node.name), base_val) {
753752
(Some(ref f), _) => const_expr(cx, &*f.expr, param_substs, fn_args).0,
754753
(_, Some((bv, _))) => adt::const_get_field(cx, &*repr, bv, discr, ix),

0 commit comments

Comments
 (0)