E0038,
E0039,
E0040,
- E0041,
E0044,
E0045,
E0046,
E0121,
E0122,
E0124,
- E0126,
E0127,
E0128,
E0129,
E0141,
E0152,
E0153,
- E0154,
- E0155,
- E0156,
E0157,
E0158,
E0159,
use syntax::parse::token;
use syntax::codemap::{Span, DUMMY_SP, Pos};
use syntax::owned_slice::OwnedSlice;
-use syntax::ptr::P;
use syntax::visit;
use syntax::visit::Visitor;
ItemStruct(ref struct_def, ref generics) => {
self.resolve_struct(item.id,
generics,
- &struct_def.super_struct,
struct_def.fields.as_slice());
}
fn resolve_struct(&mut self,
id: NodeId,
generics: &Generics,
- super_struct: &Option<P<Ty>>,
fields: &[StructField]) {
// If applicable, create a rib for the type parameters.
self.with_type_parameter_rib(HasTypeParameters(generics,
this.resolve_type_parameters(&generics.ty_params);
this.resolve_where_clause(&generics.where_clause);
- // Resolve the super struct.
- match *super_struct {
- Some(ref t) => match t.node {
- TyPath(ref path, None, path_id) => {
- match this.resolve_path(id, path, TypeNS, true) {
- Some((DefTy(def_id, _), lp)) if this.structs.contains_key(&def_id) => {
- let def = DefStruct(def_id);
- debug!("(resolving struct) resolved `{}` to type {:?}",
- token::get_ident(path.segments
- .last().unwrap()
- .identifier),
- def);
- debug!("(resolving struct) writing resolution for `{}` (id {})",
- this.path_idents_to_string(path),
- path_id);
- this.record_def(path_id, (def, lp));
- }
- Some((DefStruct(_), _)) => {
- span_err!(this.session, t.span, E0154,
- "super-struct is defined in a different crate");
- },
- Some(_) => {
- span_err!(this.session, t.span, E0155,
- "super-struct is not a struct type");
- }
- None => {
- span_err!(this.session, t.span, E0156,
- "super-struct could not be resolved");
- }
- }
- },
- _ => this.session.span_bug(t.span, "path not mapped to a TyPath")
- },
- None => {}
- }
-
// Resolve fields.
for field in fields.iter() {
this.resolve_type(&*field.node.ty);
use middle::resolve;
use middle::resolve_lifetime;
use middle::stability;
-use middle::subst::{Subst, Substs, VecPerParamSpace};
-use middle::subst;
+use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
use middle::traits;
use middle::ty;
use middle::typeck;
-use middle::ty_fold;
-use middle::ty_fold::{TypeFoldable,TypeFolder};
+use middle::ty_fold::{mod, TypeFoldable,TypeFolder};
use middle;
use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
use util::ppaux::{trait_store_to_string, ty_to_string};
use std::cell::{Cell, RefCell};
use std::cmp;
-use std::fmt::Show;
-use std::fmt;
+use std::fmt::{mod, Show};
use std::hash::{Hash, sip, Writer};
-use std::iter::AdditiveIterator;
use std::mem;
use std::ops;
use std::rc::Rc;
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField};
use syntax::ast::{Visibility};
-use syntax::ast_util::{PostExpansionMethod, is_local, lit_is_str};
-use syntax::ast_util;
-use syntax::attr;
-use syntax::attr::AttrMetaMethods;
+use syntax::ast_util::{mod, PostExpansionMethod, is_local, lit_is_str};
+use syntax::attr::{mod, AttrMetaMethods};
use syntax::codemap::Span;
-use syntax::parse::token;
-use syntax::parse::token::InternedString;
+use syntax::parse::token::{mod, InternedString};
use syntax::{ast, ast_map};
-use syntax::util::small_vector::SmallVector;
use std::collections::enum_set::{EnumSet, CLike};
pub type Disr = u64;
pub lang_items: middle::lang_items::LanguageItems,
/// A mapping of fake provided method def_ids to the default implementation
pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
- pub superstructs: RefCell<DefIdMap<Option<ast::DefId>>>,
pub struct_fields: RefCell<DefIdMap<Rc<Vec<field_ty>>>>,
/// Maps from def-id of a type or region parameter to its
normalized_cache: RefCell::new(HashMap::new()),
lang_items: lang_items,
provided_method_sources: RefCell::new(DefIdMap::new()),
- superstructs: RefCell::new(DefIdMap::new()),
struct_fields: RefCell::new(DefIdMap::new()),
destructor_for_type: RefCell::new(DefIdMap::new()),
destructors: RefCell::new(DefIdSet::new()),
t.subst(tcx, substs)
}
-// Lookup all ancestor structs of a struct indicated by did. That is the reflexive,
-// transitive closure of doing a single lookup in cx.superstructs.
-fn each_super_struct(cx: &ctxt, mut did: ast::DefId, f: |ast::DefId|) {
- let superstructs = cx.superstructs.borrow();
-
- loop {
- f(did);
- match superstructs.find(&did) {
- Some(&Some(def_id)) => {
- did = def_id;
- },
- Some(&None) => break,
- None => {
- cx.sess.bug(
- format!("ID not mapped to super-struct: {}",
- cx.map.node_to_string(did.node)).as_slice());
- }
- }
- }
-}
-
// Look up the list of field names and IDs for a given struct.
// Fails if the id is not bound to a struct.
pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
if did.krate == ast::LOCAL_CRATE {
- // We store the fields which are syntactically in each struct in cx. So
- // we have to walk the inheritance chain of the struct to get all the
- // fields (explicit and inherited) for a struct. If this is expensive
- // we could cache the whole list of fields here.
let struct_fields = cx.struct_fields.borrow();
- let mut results: SmallVector<&[field_ty]> = SmallVector::zero();
- each_super_struct(cx, did, |s| {
- match struct_fields.find(&s) {
- Some(fields) => results.push(fields.as_slice()),
- _ => {
- cx.sess.bug(
- format!("ID not mapped to struct fields: {}",
- cx.map.node_to_string(did.node)).as_slice());
- }
+ match struct_fields.find(&did) {
+ Some(fields) => (**fields).clone(),
+ _ => {
+ cx.sess.bug(
+ format!("ID not mapped to struct fields: {}",
+ cx.map.node_to_string(did.node)).as_slice());
}
- });
-
- let len = results.as_slice().iter().map(|x| x.len()).sum();
- let mut result: Vec<field_ty> = Vec::with_capacity(len);
- result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|f| f.clone())));
- assert!(result.len() == len);
- result
+ }
} else {
csearch::get_struct_fields(&cx.sess.cstore, did)
}
use syntax::abi;
use syntax::ast::{ProvidedMethod, RequiredMethod, TypeTraitItem};
use syntax::ast;
-use syntax::ast_map;
use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util;
use syntax::attr;
fcx
}
-fn span_for_field(tcx: &ty::ctxt, field: &ty::field_ty, struct_id: ast::DefId) -> Span {
- assert!(field.id.krate == ast::LOCAL_CRATE);
- let item = match tcx.map.find(struct_id.node) {
- Some(ast_map::NodeItem(item)) => item,
- None => fail!("node not in ast map: {}", struct_id.node),
- _ => fail!("expected item, found {}", tcx.map.node_to_string(struct_id.node))
- };
-
- match item.node {
- ast::ItemStruct(ref struct_def, _) => {
- match struct_def.fields.iter().find(|f| match f.node.kind {
- ast::NamedField(ident, _) => ident.name == field.name,
- _ => false,
- }) {
- Some(f) => f.span,
- None => {
- tcx.sess
- .bug(format!("Could not find field {}",
- token::get_name(field.name)).as_slice())
- }
- }
- },
- _ => tcx.sess.bug("Field found outside of a struct?"),
- }
-}
-
-// Check struct fields are uniquely named wrt parents.
-fn check_for_field_shadowing(tcx: &ty::ctxt,
- id: ast::DefId) {
- let struct_fields = tcx.struct_fields.borrow();
- let fields = struct_fields.get(&id);
-
- let superstructs = tcx.superstructs.borrow();
- let super_struct = superstructs.get(&id);
- match *super_struct {
- Some(parent_id) => {
- let super_fields = ty::lookup_struct_fields(tcx, parent_id);
- for f in fields.iter() {
- match super_fields.iter().find(|sf| f.name == sf.name) {
- Some(prev_field) => {
- span_err!(tcx.sess, span_for_field(tcx, f, id), E0041,
- "field `{}` hides field declared in super-struct",
- token::get_name(f.name));
- span_note!(tcx.sess, span_for_field(tcx, prev_field, parent_id),
- "previously declared here");
- },
- None => {}
- }
- }
- },
- None => {}
- }
-}
-
pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
let tcx = ccx.tcx;
check_representable(tcx, span, id, "struct");
check_instantiable(tcx, span, id);
- // Check there are no overlapping fields in super-structs
- check_for_field_shadowing(tcx, local_def(id));
-
if ty::lookup_simd(tcx, local_def(id)) {
check_simd(tcx, span, id);
}
tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
- // Write the super-struct type, if it exists.
- match struct_def.super_struct {
- Some(ref ty) => {
- let supserty = ccx.to_ty(&ExplicitRscope, &**ty);
- write_ty_to_tcx(tcx, it.id, supserty);
- },
- _ => {},
- }
-
convert_struct(ccx, &**struct_def, pty, it.id);
},
ast::ItemTy(_, ref generics) => {
tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys));
- let super_struct = match struct_def.super_struct {
- Some(ref t) => match t.node {
- ast::TyPath(_, _, path_id) => {
- let def_map = tcx.def_map.borrow();
- match def_map.find(&path_id) {
- Some(&def::DefStruct(def_id)) => {
- // FIXME(#12511) Check for cycles in the inheritance hierarchy.
- // Check super-struct is virtual.
- match tcx.map.find(def_id.node) {
- Some(ast_map::NodeItem(i)) => match i.node {
- ast::ItemStruct(ref struct_def, _) => {
- if !struct_def.is_virtual {
- span_err!(tcx.sess, t.span, E0126,
- "struct inheritance is only \
- allowed from virtual structs");
- }
- },
- _ => {},
- },
- _ => {},
- }
-
- Some(def_id)
- },
- _ => None,
- }
- }
- _ => None,
- },
- None => None,
- };
- tcx.superstructs.borrow_mut().insert(local_def(id), super_struct);
-
let substs = mk_item_substs(ccx, &pty.generics);
let selfty = ty::mk_struct(tcx, local_def(id), substs);
/// ID of the constructor. This is only used for tuple- or enum-like
/// structs.
pub ctor_id: Option<NodeId>,
- /// Super struct, if specified.
- pub super_struct: Option<P<Ty>>,
- /// True iff the struct may be inherited from.
- pub is_virtual: bool,
}
/*
}
fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> {
- def.map(|ast::StructDef {fields, ctor_id, super_struct, is_virtual}| {
+ def.map(|ast::StructDef { fields, ctor_id }| {
ast::StructDef {
fields: fields.into_iter().filter(|m| {
(cx.in_cfg)(m.node.attrs.as_slice())
}).collect(),
ctor_id: ctor_id,
- super_struct: super_struct,
- is_virtual: is_virtual,
}
})
}
}
}
- ast::ItemStruct(ref struct_definition, _) => {
+ ast::ItemStruct(..) => {
if attr::contains_name(i.attrs.as_slice(), "simd") {
self.gate_feature("simd", i.span,
"SIMD types are experimental and possibly buggy");
}
- match struct_definition.super_struct {
- Some(ref path) => self.gate_feature("struct_inherit", path.span,
- "struct inheritance is experimental \
- and possibly buggy"),
- None => {}
- }
- if struct_definition.is_virtual {
- self.gate_feature("struct_inherit", i.span,
- "struct inheritance (`virtual` keyword) is \
- experimental and possibly buggy");
- }
}
ast::ItemImpl(_, _, _, ref items) => {
}
pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> {
- struct_def.map(|StructDef {fields, ctor_id, super_struct, is_virtual}| StructDef {
+ struct_def.map(|StructDef { fields, ctor_id }| StructDef {
fields: fields.move_map(|f| fld.fold_struct_field(f)),
ctor_id: ctor_id.map(|cid| fld.new_id(cid)),
- super_struct: super_struct.map(|t| fld.fold_ty(t)),
- is_virtual: is_virtual
})
}
}
/// Parse struct Foo { ... }
- fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
+ fn parse_item_struct(&mut self) -> ItemInfo {
let class_name = self.parse_ident();
let mut generics = self.parse_generics();
- let super_struct = if self.eat(&token::COLON) {
+ if self.eat(&token::COLON) {
let ty = self.parse_ty(true);
- match ty.node {
- TyPath(_, None, _) => {
- Some(ty)
- }
- _ => {
- self.span_err(ty.span, "not a struct");
- None
- }
- }
- } else {
- None
- };
+ self.span_err(ty.span, "`virtual` structs have been removed from the language");
+ }
self.parse_where_clause(&mut generics);
ItemStruct(P(ast::StructDef {
fields: fields,
ctor_id: if is_tuple_like { Some(new_id) } else { None },
- super_struct: super_struct,
- is_virtual: is_virtual,
}), generics),
None)
}
P(StructDef {
fields: fields,
ctor_id: None,
- super_struct: None,
- is_virtual: false,
})
}
token_str).as_slice());
}
- let is_virtual = self.eat_keyword(keywords::Virtual);
- if is_virtual && !self.is_keyword(keywords::Struct) {
+ if self.eat_keyword(keywords::Virtual) {
let span = self.span;
- self.span_err(span,
- "`virtual` keyword may only be used with `struct`");
+ self.span_err(span, "`virtual` structs have been removed from the language");
}
// the rest are all guaranteed to be items:
}
if self.eat_keyword(keywords::Struct) {
// STRUCT ITEM
- let (ident, item_, extra_attrs) = self.parse_item_struct(is_virtual);
+ let (ident, item_, extra_attrs) = self.parse_item_struct();
let last_span = self.last_span;
let item = self.mk_item(lo,
last_span.hi,
));
}
ast::ItemStruct(ref struct_def, ref generics) => {
- if struct_def.is_virtual {
- try!(self.word_space("virtual"));
- }
try!(self.head(visibility_qualified(item.vis,"struct").as_slice()));
try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
}
span: codemap::Span) -> IoResult<()> {
try!(self.print_ident(ident));
try!(self.print_generics(generics));
- match struct_def.super_struct {
- Some(ref t) => {
- try!(self.word_space(":"));
- try!(self.print_type(&**t));
- },
- None => {},
- }
if ast_util::struct_def_is_tuple_like(struct_def) {
if !struct_def.fields.is_empty() {
try!(self.popen());
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
struct_definition: &'v StructDef) {
- match struct_definition.super_struct {
- Some(ref t) => visitor.visit_ty(&**t),
- None => {},
- }
for field in struct_definition.fields.iter() {
visitor.visit_struct_field(field)
}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test diagnostics for the removed struct inheritance feature.
+#![feature(struct_inherit)]
+
+virtual struct SuperStruct { //~ ERROR `virtual` structs have been removed from the language
+ f1: int,
+}
+
+struct Struct : SuperStruct; //~ ERROR `virtual` structs have been removed from the language
+
+pub fn main() {}