Skip to content

Commit 38517d0

Browse files
committed
auto merge of #17952 : jakub-/rust/remove-virtual-structs, r=eddyb
Closes #17861.
2 parents 86509d8 + 4442e6d commit 38517d0

25 files changed

+28
-584
lines changed

src/doc/reference.md

-17
Original file line numberDiff line numberDiff line change
@@ -1328,23 +1328,6 @@ let c = [Cookie, Cookie, Cookie, Cookie];
13281328
The precise memory layout of a structure is not specified. One can specify a
13291329
particular layout using the [`repr` attribute](#ffi-attributes).
13301330

1331-
By using the `struct_inherit` feature gate, structures may use single
1332-
inheritance. A Structure may only inherit from a single other structure, called
1333-
the _super-struct_. The inheriting structure (sub-struct) acts as if all fields
1334-
in the super-struct were present in the sub-struct. Fields declared in a
1335-
sub-struct must not have the same name as any field in any (transitive)
1336-
super-struct. All fields (both declared and inherited) must be specified in any
1337-
initializers. Inheritance between structures does not give subtyping or
1338-
coercion. The super-struct and sub-struct must be defined in the same crate.
1339-
The super-struct must be declared using the `virtual` keyword. For example:
1340-
1341-
```{.ignore}
1342-
virtual struct Sup { x: int }
1343-
struct Sub : Sup { y: int }
1344-
let s = Sub {x: 10, y: 11};
1345-
let sx = s.x;
1346-
```
1347-
13481331
### Enumerations
13491332

13501333
An _enumeration_ is a simultaneous definition of a nominal [enumerated

src/librustc/diagnostics.rs

-5
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ register_diagnostics!(
5656
E0038,
5757
E0039,
5858
E0040,
59-
E0041,
6059
E0044,
6160
E0045,
6261
E0046,
@@ -123,7 +122,6 @@ register_diagnostics!(
123122
E0121,
124123
E0122,
125124
E0124,
126-
E0126,
127125
E0127,
128126
E0128,
129127
E0129,
@@ -141,9 +139,6 @@ register_diagnostics!(
141139
E0141,
142140
E0152,
143141
E0153,
144-
E0154,
145-
E0155,
146-
E0156,
147142
E0157,
148143
E0158,
149144
E0159,

src/librustc/middle/resolve.rs

-39
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ use syntax::parse::token::special_idents;
5454
use syntax::parse::token;
5555
use syntax::codemap::{Span, DUMMY_SP, Pos};
5656
use syntax::owned_slice::OwnedSlice;
57-
use syntax::ptr::P;
5857
use syntax::visit;
5958
use syntax::visit::Visitor;
6059

@@ -4179,7 +4178,6 @@ impl<'a> Resolver<'a> {
41794178
ItemStruct(ref struct_def, ref generics) => {
41804179
self.resolve_struct(item.id,
41814180
generics,
4182-
&struct_def.super_struct,
41834181
struct_def.fields.as_slice());
41844182
}
41854183

@@ -4505,7 +4503,6 @@ impl<'a> Resolver<'a> {
45054503
fn resolve_struct(&mut self,
45064504
id: NodeId,
45074505
generics: &Generics,
4508-
super_struct: &Option<P<Ty>>,
45094506
fields: &[StructField]) {
45104507
// If applicable, create a rib for the type parameters.
45114508
self.with_type_parameter_rib(HasTypeParameters(generics,
@@ -4517,42 +4514,6 @@ impl<'a> Resolver<'a> {
45174514
this.resolve_type_parameters(&generics.ty_params);
45184515
this.resolve_where_clause(&generics.where_clause);
45194516

4520-
// Resolve the super struct.
4521-
match *super_struct {
4522-
Some(ref t) => match t.node {
4523-
TyPath(ref path, None, path_id) => {
4524-
match this.resolve_path(id, path, TypeNS, true) {
4525-
Some((DefTy(def_id, _), lp)) if this.structs.contains_key(&def_id) => {
4526-
let def = DefStruct(def_id);
4527-
debug!("(resolving struct) resolved `{}` to type {:?}",
4528-
token::get_ident(path.segments
4529-
.last().unwrap()
4530-
.identifier),
4531-
def);
4532-
debug!("(resolving struct) writing resolution for `{}` (id {})",
4533-
this.path_idents_to_string(path),
4534-
path_id);
4535-
this.record_def(path_id, (def, lp));
4536-
}
4537-
Some((DefStruct(_), _)) => {
4538-
span_err!(this.session, t.span, E0154,
4539-
"super-struct is defined in a different crate");
4540-
},
4541-
Some(_) => {
4542-
span_err!(this.session, t.span, E0155,
4543-
"super-struct is not a struct type");
4544-
}
4545-
None => {
4546-
span_err!(this.session, t.span, E0156,
4547-
"super-struct could not be resolved");
4548-
}
4549-
}
4550-
},
4551-
_ => this.session.span_bug(t.span, "path not mapped to a TyPath")
4552-
},
4553-
None => {}
4554-
}
4555-
45564517
// Resolve fields.
45574518
for field in fields.iter() {
45584519
this.resolve_type(&*field.node.ty);

src/librustc/middle/ty.rs

+13-57
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ use middle::mem_categorization as mc;
2424
use middle::resolve;
2525
use middle::resolve_lifetime;
2626
use middle::stability;
27-
use middle::subst::{Subst, Substs, VecPerParamSpace};
28-
use middle::subst;
27+
use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
2928
use middle::traits;
3029
use middle::ty;
3130
use middle::typeck;
32-
use middle::ty_fold;
33-
use middle::ty_fold::{TypeFoldable,TypeFolder};
31+
use middle::ty_fold::{mod, TypeFoldable,TypeFolder};
3432
use middle;
3533
use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
3634
use util::ppaux::{trait_store_to_string, ty_to_string};
@@ -40,10 +38,8 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet, FnvHashMap};
4038

4139
use std::cell::{Cell, RefCell};
4240
use std::cmp;
43-
use std::fmt::Show;
44-
use std::fmt;
41+
use std::fmt::{mod, Show};
4542
use std::hash::{Hash, sip, Writer};
46-
use std::iter::AdditiveIterator;
4743
use std::mem;
4844
use std::ops;
4945
use std::rc::Rc;
@@ -55,15 +51,11 @@ use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE};
5551
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
5652
use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField};
5753
use syntax::ast::{Visibility};
58-
use syntax::ast_util::{PostExpansionMethod, is_local, lit_is_str};
59-
use syntax::ast_util;
60-
use syntax::attr;
61-
use syntax::attr::AttrMetaMethods;
54+
use syntax::ast_util::{mod, PostExpansionMethod, is_local, lit_is_str};
55+
use syntax::attr::{mod, AttrMetaMethods};
6256
use syntax::codemap::Span;
63-
use syntax::parse::token;
64-
use syntax::parse::token::InternedString;
57+
use syntax::parse::token::{mod, InternedString};
6558
use syntax::{ast, ast_map};
66-
use syntax::util::small_vector::SmallVector;
6759
use std::collections::enum_set::{EnumSet, CLike};
6860

6961
pub type Disr = u64;
@@ -493,7 +485,6 @@ pub struct ctxt<'tcx> {
493485
pub lang_items: middle::lang_items::LanguageItems,
494486
/// A mapping of fake provided method def_ids to the default implementation
495487
pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
496-
pub superstructs: RefCell<DefIdMap<Option<ast::DefId>>>,
497488
pub struct_fields: RefCell<DefIdMap<Rc<Vec<field_ty>>>>,
498489

499490
/// Maps from def-id of a type or region parameter to its
@@ -1512,7 +1503,6 @@ pub fn mk_ctxt<'tcx>(s: Session,
15121503
normalized_cache: RefCell::new(HashMap::new()),
15131504
lang_items: lang_items,
15141505
provided_method_sources: RefCell::new(DefIdMap::new()),
1515-
superstructs: RefCell::new(DefIdMap::new()),
15161506
struct_fields: RefCell::new(DefIdMap::new()),
15171507
destructor_for_type: RefCell::new(DefIdMap::new()),
15181508
destructors: RefCell::new(DefIdSet::new()),
@@ -4539,53 +4529,19 @@ pub fn lookup_field_type(tcx: &ctxt,
45394529
t.subst(tcx, substs)
45404530
}
45414531

4542-
// Lookup all ancestor structs of a struct indicated by did. That is the reflexive,
4543-
// transitive closure of doing a single lookup in cx.superstructs.
4544-
fn each_super_struct(cx: &ctxt, mut did: ast::DefId, f: |ast::DefId|) {
4545-
let superstructs = cx.superstructs.borrow();
4546-
4547-
loop {
4548-
f(did);
4549-
match superstructs.find(&did) {
4550-
Some(&Some(def_id)) => {
4551-
did = def_id;
4552-
},
4553-
Some(&None) => break,
4554-
None => {
4555-
cx.sess.bug(
4556-
format!("ID not mapped to super-struct: {}",
4557-
cx.map.node_to_string(did.node)).as_slice());
4558-
}
4559-
}
4560-
}
4561-
}
4562-
45634532
// Look up the list of field names and IDs for a given struct.
45644533
// Fails if the id is not bound to a struct.
45654534
pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
45664535
if did.krate == ast::LOCAL_CRATE {
4567-
// We store the fields which are syntactically in each struct in cx. So
4568-
// we have to walk the inheritance chain of the struct to get all the
4569-
// fields (explicit and inherited) for a struct. If this is expensive
4570-
// we could cache the whole list of fields here.
45714536
let struct_fields = cx.struct_fields.borrow();
4572-
let mut results: SmallVector<&[field_ty]> = SmallVector::zero();
4573-
each_super_struct(cx, did, |s| {
4574-
match struct_fields.find(&s) {
4575-
Some(fields) => results.push(fields.as_slice()),
4576-
_ => {
4577-
cx.sess.bug(
4578-
format!("ID not mapped to struct fields: {}",
4579-
cx.map.node_to_string(did.node)).as_slice());
4580-
}
4537+
match struct_fields.find(&did) {
4538+
Some(fields) => (**fields).clone(),
4539+
_ => {
4540+
cx.sess.bug(
4541+
format!("ID not mapped to struct fields: {}",
4542+
cx.map.node_to_string(did.node)).as_slice());
45814543
}
4582-
});
4583-
4584-
let len = results.as_slice().iter().map(|x| x.len()).sum();
4585-
let mut result: Vec<field_ty> = Vec::with_capacity(len);
4586-
result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|f| f.clone())));
4587-
assert!(result.len() == len);
4588-
result
4544+
}
45894545
} else {
45904546
csearch::get_struct_fields(&cx.sess.cstore, did)
45914547
}

src/librustc/middle/typeck/check/mod.rs

-58
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ use std::rc::Rc;
127127
use syntax::abi;
128128
use syntax::ast::{ProvidedMethod, RequiredMethod, TypeTraitItem};
129129
use syntax::ast;
130-
use syntax::ast_map;
131130
use syntax::ast_util::{local_def, PostExpansionMethod};
132131
use syntax::ast_util;
133132
use syntax::attr;
@@ -602,69 +601,12 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
602601
fcx
603602
}
604603

605-
fn span_for_field(tcx: &ty::ctxt, field: &ty::field_ty, struct_id: ast::DefId) -> Span {
606-
assert!(field.id.krate == ast::LOCAL_CRATE);
607-
let item = match tcx.map.find(struct_id.node) {
608-
Some(ast_map::NodeItem(item)) => item,
609-
None => fail!("node not in ast map: {}", struct_id.node),
610-
_ => fail!("expected item, found {}", tcx.map.node_to_string(struct_id.node))
611-
};
612-
613-
match item.node {
614-
ast::ItemStruct(ref struct_def, _) => {
615-
match struct_def.fields.iter().find(|f| match f.node.kind {
616-
ast::NamedField(ident, _) => ident.name == field.name,
617-
_ => false,
618-
}) {
619-
Some(f) => f.span,
620-
None => {
621-
tcx.sess
622-
.bug(format!("Could not find field {}",
623-
token::get_name(field.name)).as_slice())
624-
}
625-
}
626-
},
627-
_ => tcx.sess.bug("Field found outside of a struct?"),
628-
}
629-
}
630-
631-
// Check struct fields are uniquely named wrt parents.
632-
fn check_for_field_shadowing(tcx: &ty::ctxt,
633-
id: ast::DefId) {
634-
let struct_fields = tcx.struct_fields.borrow();
635-
let fields = struct_fields.get(&id);
636-
637-
let superstructs = tcx.superstructs.borrow();
638-
let super_struct = superstructs.get(&id);
639-
match *super_struct {
640-
Some(parent_id) => {
641-
let super_fields = ty::lookup_struct_fields(tcx, parent_id);
642-
for f in fields.iter() {
643-
match super_fields.iter().find(|sf| f.name == sf.name) {
644-
Some(prev_field) => {
645-
span_err!(tcx.sess, span_for_field(tcx, f, id), E0041,
646-
"field `{}` hides field declared in super-struct",
647-
token::get_name(f.name));
648-
span_note!(tcx.sess, span_for_field(tcx, prev_field, parent_id),
649-
"previously declared here");
650-
},
651-
None => {}
652-
}
653-
}
654-
},
655-
None => {}
656-
}
657-
}
658-
659604
pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
660605
let tcx = ccx.tcx;
661606

662607
check_representable(tcx, span, id, "struct");
663608
check_instantiable(tcx, span, id);
664609

665-
// Check there are no overlapping fields in super-structs
666-
check_for_field_shadowing(tcx, local_def(id));
667-
668610
if ty::lookup_simd(tcx, local_def(id)) {
669611
check_simd(tcx, span, id);
670612
}

src/librustc/middle/typeck/collect.rs

-42
Original file line numberDiff line numberDiff line change
@@ -1235,15 +1235,6 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
12351235

12361236
tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
12371237

1238-
// Write the super-struct type, if it exists.
1239-
match struct_def.super_struct {
1240-
Some(ref ty) => {
1241-
let supserty = ccx.to_ty(&ExplicitRscope, &**ty);
1242-
write_ty_to_tcx(tcx, it.id, supserty);
1243-
},
1244-
_ => {},
1245-
}
1246-
12471238
convert_struct(ccx, &**struct_def, pty, it.id);
12481239
},
12491240
ast::ItemTy(_, ref generics) => {
@@ -1295,39 +1286,6 @@ pub fn convert_struct(ccx: &CrateCtxt,
12951286

12961287
tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys));
12971288

1298-
let super_struct = match struct_def.super_struct {
1299-
Some(ref t) => match t.node {
1300-
ast::TyPath(_, _, path_id) => {
1301-
let def_map = tcx.def_map.borrow();
1302-
match def_map.find(&path_id) {
1303-
Some(&def::DefStruct(def_id)) => {
1304-
// FIXME(#12511) Check for cycles in the inheritance hierarchy.
1305-
// Check super-struct is virtual.
1306-
match tcx.map.find(def_id.node) {
1307-
Some(ast_map::NodeItem(i)) => match i.node {
1308-
ast::ItemStruct(ref struct_def, _) => {
1309-
if !struct_def.is_virtual {
1310-
span_err!(tcx.sess, t.span, E0126,
1311-
"struct inheritance is only \
1312-
allowed from virtual structs");
1313-
}
1314-
},
1315-
_ => {},
1316-
},
1317-
_ => {},
1318-
}
1319-
1320-
Some(def_id)
1321-
},
1322-
_ => None,
1323-
}
1324-
}
1325-
_ => None,
1326-
},
1327-
None => None,
1328-
};
1329-
tcx.superstructs.borrow_mut().insert(local_def(id), super_struct);
1330-
13311289
let substs = mk_item_substs(ccx, &pty.generics);
13321290
let selfty = ty::mk_struct(tcx, local_def(id), substs);
13331291

src/libsyntax/ast.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1286,10 +1286,6 @@ pub struct StructDef {
12861286
/// ID of the constructor. This is only used for tuple- or enum-like
12871287
/// structs.
12881288
pub ctor_id: Option<NodeId>,
1289-
/// Super struct, if specified.
1290-
pub super_struct: Option<P<Ty>>,
1291-
/// True iff the struct may be inherited from.
1292-
pub is_virtual: bool,
12931289
}
12941290

12951291
/*

0 commit comments

Comments
 (0)