Skip to content

Commit 1e18676

Browse files
author
Ariel Ben-Yehuda
committed
it compiles!
1 parent f357392 commit 1e18676

File tree

13 files changed

+224
-279
lines changed

13 files changed

+224
-279
lines changed

src/librustc_lint/builtin.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ use std::collections::{HashSet, BitSet};
4545
use std::collections::hash_map::Entry::{Occupied, Vacant};
4646
use std::{cmp, slice};
4747
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
48-
use std::rc::Rc;
4948

5049
use syntax::{abi, ast};
5150
use syntax::ast_util::{self, is_shift_binop, local_def};
@@ -413,18 +412,21 @@ enum FfiResult {
413412
/// to function pointers and references, but could be
414413
/// expanded to cover NonZero raw pointers and newtypes.
415414
/// FIXME: This duplicates code in trans.
416-
fn is_repr_nullable_ptr<'tcx>(variants: &Vec<Rc<ty::VariantInfo<'tcx>>>) -> bool {
417-
if variants.len() == 2 {
415+
fn is_repr_nullable_ptr<'tcx>(tcx: &ty::ctxt<'tcx>,
416+
def: &ty::ADTDef<'tcx>,
417+
substs: &Substs<'tcx>)
418+
-> bool {
419+
if def.variants.len() == 2 {
418420
let mut data_idx = 0;
419421

420-
if variants[0].args.is_empty() {
422+
if def.variants[0].fields.is_empty() {
421423
data_idx = 1;
422-
} else if !variants[1].args.is_empty() {
424+
} else if !def.variants[1].fields.is_empty() {
423425
return false;
424426
}
425427

426-
if variants[data_idx].args.len() == 1 {
427-
match variants[data_idx].args[0].sty {
428+
if def.variants[data_idx].fields.len() == 1 {
429+
match def.variants[data_idx].fields[0].ty(tcx, substs).sty {
428430
ty::TyBareFn(None, _) => { return true; }
429431
ty::TyRef(..) => { return true; }
430432
_ => { }
@@ -474,16 +476,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
474476

475477
// We can't completely trust repr(C) markings; make sure the
476478
// fields are actually safe.
477-
let fields = cx.struct_fields(def.did, substs);
478-
479-
if fields.is_empty() {
479+
if def.struct_variant().fields.is_empty() {
480480
return FfiUnsafe(
481481
"found zero-size struct in foreign module, consider \
482482
adding a member to this struct");
483483
}
484484

485-
for field in fields {
486-
let field_ty = infer::normalize_associated_type(cx, &field.mt.ty);
485+
for field in &def.struct_variant().fields {
486+
let field_ty = infer::normalize_associated_type(cx, &field.ty(cx, substs));
487487
let r = self.check_type_for_ffi(cache, field_ty);
488488
match r {
489489
FfiSafe => {}
@@ -494,8 +494,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
494494
FfiSafe
495495
}
496496
ty::TyEnum(def, substs) => {
497-
let variants = cx.substd_enum_variants(def.did, substs);
498-
if variants.is_empty() {
497+
if def.variants.is_empty() {
499498
// Empty enums are okay... although sort of useless.
500499
return FfiSafe
501500
}
@@ -506,7 +505,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
506505
match &**repr_hints {
507506
[] => {
508507
// Special-case types like `Option<extern fn()>`.
509-
if !is_repr_nullable_ptr(&variants) {
508+
if !is_repr_nullable_ptr(cx, def, substs) {
510509
return FfiUnsafe(
511510
"found enum without foreign-function-safe \
512511
representation annotation in foreign module, \
@@ -537,9 +536,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
537536
}
538537

539538
// Check the contained variants.
540-
for variant in variants {
541-
for arg in &variant.args {
542-
let arg = infer::normalize_associated_type(cx, arg);
539+
for variant in &def.variants {
540+
for field in &variant.fields {
541+
let arg = infer::normalize_associated_type(cx, &field.ty(cx, substs));
543542
let r = self.check_type_for_ffi(cache, arg);
544543
match r {
545544
FfiSafe => {}

src/librustc_privacy/lib.rs

Lines changed: 49 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use self::FieldName::*;
3434
use std::mem::replace;
3535

3636
use rustc::ast_map;
37-
use rustc::metadata::csearch;
3837
use rustc::middle::def;
3938
use rustc::middle::privacy::ImportUse::*;
4039
use rustc::middle::privacy::LastPrivate::*;
@@ -688,29 +687,26 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
688687
// Checks that a field is in scope.
689688
fn check_field(&mut self,
690689
span: Span,
691-
id: ast::DefId,
690+
def: &'tcx ty::ADTDef<'tcx>,
691+
v: &'tcx ty::VariantDef<'tcx>,
692692
name: FieldName) {
693-
// TODO: refactor to variant API
694-
let fields = self.tcx.lookup_struct_fields(id);
695693
let field = match name {
696694
NamedField(f_name) => {
697-
debug!("privacy - check named field {} in struct {:?}", f_name, id);
698-
fields.iter().find(|f| f.name == f_name).unwrap()
695+
debug!("privacy - check named field {} in struct {:?}", f_name, def);
696+
v.field_named(f_name)
699697
}
700-
UnnamedField(idx) => &fields[idx]
698+
UnnamedField(idx) => &v.fields[idx]
701699
};
702700
if field.vis == ast::Public ||
703-
(is_local(field.id) && self.private_accessible(field.id.node)) {
701+
(is_local(field.did) && self.private_accessible(field.did.node)) {
704702
return
705703
}
706704

707-
let struct_type = self.tcx.lookup_item_type(id).ty;
708-
let struct_desc = match struct_type.sty {
709-
ty::TyStruct(_, _) =>
710-
format!("struct `{}`", self.tcx.item_path_str(id)),
705+
let struct_desc = match def.adt_kind() {
706+
ty::ADTKind::Struct =>
707+
format!("struct `{}`", self.tcx.item_path_str(def.did)),
711708
// struct variant fields have inherited visibility
712-
ty::TyEnum(..) => return,
713-
_ => self.tcx.sess.span_bug(span, "can't find struct for field")
709+
ty::ADTKind::Enum => return
714710
};
715711
let msg = match name {
716712
NamedField(name) => format!("field `{}` of {} is private",
@@ -885,12 +881,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
885881
match expr.node {
886882
ast::ExprField(ref base, ident) => {
887883
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(&**base).sty {
888-
self.check_field(expr.span, def.did, NamedField(ident.node.name));
884+
self.check_field(expr.span,
885+
def,
886+
def.struct_variant(),
887+
NamedField(ident.node.name));
889888
}
890889
}
891890
ast::ExprTupField(ref base, idx) => {
892891
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(&**base).sty {
893-
self.check_field(expr.span, def.did, UnnamedField(idx.node));
892+
self.check_field(expr.span,
893+
def,
894+
def.struct_variant(),
895+
UnnamedField(idx.node));
894896
}
895897
}
896898
ast::ExprMethodCall(ident, _, _) => {
@@ -899,67 +901,31 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
899901
debug!("(privacy checking) checking impl method");
900902
self.check_method(expr.span, method.def_id, ident.node.name);
901903
}
902-
ast::ExprStruct(_, ref fields, _) => {
903-
match self.tcx.expr_ty(expr).sty {
904-
ty::TyStruct(ctor_def, _) => {
905-
// RFC 736: ensure all unmentioned fields are visible.
906-
// Rather than computing the set of unmentioned fields
907-
// (i.e. `all_fields - fields`), just check them all.
908-
let all_fields = self.tcx.lookup_struct_fields(ctor_def.did);
909-
for field in all_fields {
910-
self.check_field(expr.span, ctor_def.did,
911-
NamedField(field.name));
912-
}
913-
}
914-
ty::TyEnum(_, _) => {
915-
match self.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() {
916-
def::DefVariant(_, variant_id, _) => {
917-
for field in fields {
918-
self.check_field(expr.span, variant_id,
919-
NamedField(field.ident.node.name));
920-
}
921-
}
922-
_ => self.tcx.sess.span_bug(expr.span,
923-
"resolve didn't \
924-
map enum struct \
925-
constructor to a \
926-
variant def"),
927-
}
928-
}
929-
_ => self.tcx.sess.span_bug(expr.span, "struct expr \
930-
didn't have \
931-
struct type?!"),
904+
ast::ExprStruct(..) => {
905+
let adt = self.tcx.expr_ty(expr).ty_adt_def().unwrap();
906+
let variant = adt.variant_of_def(self.tcx.resolve_expr(expr));
907+
// RFC 736: ensure all unmentioned fields are visible.
908+
// Rather than computing the set of unmentioned fields
909+
// (i.e. `all_fields - fields`), just check them all.
910+
for field in &variant.fields {
911+
self.check_field(expr.span, adt, variant, NamedField(field.name));
932912
}
933913
}
934914
ast::ExprPath(..) => {
935-
let guard = |did: ast::DefId| {
936-
let fields = self.tcx.lookup_struct_fields(did);
937-
let any_priv = fields.iter().any(|f| {
938-
f.vis != ast::Public && (
939-
!is_local(f.id) ||
940-
!self.private_accessible(f.id.node))
941-
});
942-
if any_priv {
943-
self.tcx.sess.span_err(expr.span,
944-
"cannot invoke tuple struct constructor \
945-
with private fields");
946-
}
947-
};
948-
match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
949-
Some(def::DefStruct(did)) => {
950-
guard(if is_local(did) {
951-
local_def(self.tcx.map.get_parent(did.node))
952-
} else {
953-
// "tuple structs" with zero fields (such as
954-
// `pub struct Foo;`) don't have a ctor_id, hence
955-
// the unwrap_or to the same struct id.
956-
let maybe_did =
957-
csearch::get_tuple_struct_definition_if_ctor(
958-
&self.tcx.sess.cstore, did);
959-
maybe_did.unwrap_or(did)
960-
})
915+
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) ||
921+
!self.private_accessible(f.did.node))
922+
});
923+
if any_priv {
924+
self.tcx.sess.span_err(expr.span,
925+
"cannot invoke tuple struct constructor \
926+
with private fields");
927+
}
961928
}
962-
_ => {}
963929
}
964930
}
965931
_ => {}
@@ -977,31 +943,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
977943

978944
match pattern.node {
979945
ast::PatStruct(_, ref fields, _) => {
980-
match self.tcx.pat_ty(pattern).sty {
981-
ty::TyStruct(def, _) => {
982-
for field in fields {
983-
self.check_field(pattern.span, def.did,
984-
NamedField(field.node.ident.name));
985-
}
986-
}
987-
ty::TyEnum(_, _) => {
988-
match self.tcx.def_map.borrow().get(&pattern.id).map(|d| d.full_def()) {
989-
Some(def::DefVariant(_, variant_id, _)) => {
990-
for field in fields {
991-
self.check_field(pattern.span, variant_id,
992-
NamedField(field.node.ident.name));
993-
}
994-
}
995-
_ => self.tcx.sess.span_bug(pattern.span,
996-
"resolve didn't \
997-
map enum struct \
998-
pattern to a \
999-
variant def"),
1000-
}
1001-
}
1002-
_ => self.tcx.sess.span_bug(pattern.span,
1003-
"struct pattern didn't have \
1004-
struct type?!"),
946+
let adt = self.tcx.pat_ty(pattern).ty_adt_def().unwrap();
947+
let def = self.tcx.def_map.borrow().get(&pattern.id).unwrap().full_def();
948+
let variant = adt.variant_of_def(def);
949+
for field in fields {
950+
self.check_field(pattern.span, adt, variant,
951+
NamedField(field.node.ident.name));
1005952
}
1006953
}
1007954

@@ -1014,7 +961,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
1014961
if let ast::PatWild(..) = field.node {
1015962
continue
1016963
}
1017-
self.check_field(field.span, def.did, UnnamedField(i));
964+
self.check_field(field.span,
965+
def,
966+
def.struct_variant(),
967+
UnnamedField(i));
1018968
}
1019969
}
1020970
ty::TyEnum(..) => {

src/librustc_trans/trans/_match.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,8 +1191,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
11911191
// since we can only ever match that field behind
11921192
// a reference we construct a fat ptr here.
11931193
let unsized_ty = def.struct_variant().fields.last().map(|field| {
1194-
let fty = field.ty(bcx.tcx(), substs);
1195-
monomorphize::normalize_associated_type(bcx.tcx(), &fty)
1194+
monomorphize::field_ty(bcx.tcx(), substs, field)
11961195
}).unwrap();
11971196
let llty = type_of::type_of(bcx.ccx(), unsized_ty);
11981197
let scratch = alloca_no_lifetime(bcx, llty, "__struct_field_fat_ptr");

src/librustc_trans/trans/adt.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
246246
Univariant(mk_struct(cx, &elems[..], false, t), 0)
247247
}
248248
ty::TyStruct(def, substs) => {
249-
let fields = cx.tcx().lookup_struct_fields(def.did);
250-
let mut ftys = fields.iter().map(|field| {
251-
let fty = cx.tcx().lookup_field_type(def.did, field.id, substs);
252-
monomorphize::normalize_associated_type(cx.tcx(), &fty)
249+
let mut ftys = def.struct_variant().fields.iter().map(|field| {
250+
monomorphize::field_ty(cx.tcx(), substs, field)
253251
}).collect::<Vec<_>>();
254252
let packed = cx.tcx().lookup_packed(def.did);
255253
let dtor = cx.tcx().ty_dtor(def.did).has_drop_flag();
@@ -263,7 +261,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
263261
Univariant(mk_struct(cx, &substs.upvar_tys, false, t), 0)
264262
}
265263
ty::TyEnum(def, substs) => {
266-
let cases = get_cases(cx.tcx(), def.did, substs);
264+
let cases = get_cases(cx.tcx(), def, substs);
267265
let hint = *cx.tcx().lookup_repr_hints(def.did).get(0)
268266
.unwrap_or(&attr::ReprAny);
269267

@@ -444,10 +442,10 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
444442

445443
// Is this the NonZero lang item wrapping a pointer or integer type?
446444
ty::TyStruct(def, substs) if Some(def.did) == tcx.lang_items.non_zero() => {
447-
let nonzero_fields = tcx.lookup_struct_fields(def.did);
445+
let nonzero_fields = &def.struct_variant().fields;
448446
assert_eq!(nonzero_fields.len(), 1);
449-
let nonzero_field = tcx.lookup_field_type(def.did, nonzero_fields[0].id, substs);
450-
match nonzero_field.sty {
447+
let field_ty = monomorphize::field_ty(tcx, substs, &nonzero_fields[0]);
448+
match field_ty.sty {
451449
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if !type_is_sized(tcx, ty) => {
452450
path.push_all(&[0, FAT_PTR_ADDR]);
453451
Some(path)
@@ -463,9 +461,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
463461
// Perhaps one of the fields of this struct is non-zero
464462
// let's recurse and find out
465463
ty::TyStruct(def, substs) => {
466-
let fields = tcx.lookup_struct_fields(def.did);
467-
for (j, field) in fields.iter().enumerate() {
468-
let field_ty = tcx.lookup_field_type(def.did, field.id, substs);
464+
for (j, field) in def.struct_variant().fields.iter().enumerate() {
465+
// TODO(#27532)
466+
let field_ty = field.ty(tcx, substs);
469467
if let Some(mut fpath) = find_discr_field_candidate(tcx, field_ty, path.clone()) {
470468
fpath.push(j);
471469
return Some(fpath);
@@ -530,14 +528,14 @@ impl<'tcx> Case<'tcx> {
530528
}
531529

532530
fn get_cases<'tcx>(tcx: &ty::ctxt<'tcx>,
533-
def_id: ast::DefId,
531+
adt: &ty::ADTDef<'tcx>,
534532
substs: &subst::Substs<'tcx>)
535533
-> Vec<Case<'tcx>> {
536-
tcx.enum_variants(def_id).iter().map(|vi| {
537-
let arg_tys = vi.args.iter().map(|&raw_ty| {
538-
monomorphize::apply_param_substs(tcx, substs, &raw_ty)
534+
adt.variants.iter().map(|vi| {
535+
let field_tys = vi.fields.iter().map(|field| {
536+
monomorphize::field_ty(tcx, substs, field)
539537
}).collect();
540-
Case { discr: vi.disr_val, tys: arg_tys }
538+
Case { discr: vi.disr_val, tys: field_tys }
541539
}).collect()
542540
}
543541

0 commit comments

Comments
 (0)