diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2014-04-03 13:38:45 +1300 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2014-04-23 12:30:58 +1200 |
| commit | f78add10cde772b9d743a84a604dc584b63a06fc (patch) | |
| tree | bc159ccd2a18de0a71e4163e48b64cc31ae9dbcb /src/libsyntax | |
| parent | c3b2f2b0c6f074fb98add56a1977d407e294c9ed (diff) | |
| download | rust-f78add10cde772b9d743a84a604dc584b63a06fc.tar.gz rust-f78add10cde772b9d743a84a604dc584b63a06fc.zip | |
Support unsized types with the `type` keyword
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ast_map.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/decodable.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/hash.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/rand.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/ty.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 27 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
13 files changed, 85 insertions, 19 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5d0b24fdb3e..97ddff78789 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -180,6 +180,7 @@ pub enum TyParamBound { pub struct TyParam { pub ident: Ident, pub id: NodeId, + pub sized: Sized, pub bounds: OwnedSlice<TyParamBound>, pub default: Option<P<Ty>>, pub span: Span @@ -1052,6 +1053,12 @@ impl Visibility { } #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] +pub enum Sized { + DynSize, + StaticSize, +} + +#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] pub struct StructField_ { pub kind: StructFieldKind, pub id: NodeId, @@ -1109,7 +1116,7 @@ pub enum Item_ { ItemTy(P<Ty>, Generics), ItemEnum(EnumDef, Generics), ItemStruct(@StructDef, Generics), - ItemTrait(Generics, Vec<TraitRef> , Vec<TraitMethod> ), + ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ), ItemImpl(Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 45954800e7e..d0e3ff4ae54 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -265,6 +265,24 @@ impl Map { } } + pub fn expect_struct(&self, id: NodeId) -> @StructDef { + match self.find(id) { + Some(NodeItem(i)) => { + match i.node { + ItemStruct(struct_def, _) => struct_def, + _ => fail!("struct ID bound to non-struct") + } + } + Some(NodeVariant(ref variant)) => { + match (*variant).node.kind { + StructVariantKind(struct_def) => struct_def, + _ => fail!("struct ID bound to enum variant that isn't struct-like"), + } + } + _ => fail!(format!("expected struct, found {}", self.node_to_str(id))), + } + } + pub fn expect_foreign_item(&self, id: NodeId) -> @ForeignItem { match self.find(id) { Some(NodeForeignItem(item)) => item, @@ -453,7 +471,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> { None => {} } } - ItemTrait(_, ref traits, ref methods) => { + ItemTrait(_, _, ref traits, ref methods) => { for t in traits.iter() { self.insert(t.ref_id, EntryItem(self.parent, i)); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index c1289ef9858..e1174ea6cc4 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -68,6 +68,7 @@ pub trait AstBuilder { fn typaram(&self, span: Span, id: ast::Ident, + sized: ast::Sized, bounds: OwnedSlice<ast::TyParamBound>, default: Option<P<ast::Ty>>) -> ast::TyParam; @@ -371,11 +372,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn typaram(&self, span: Span, id: ast::Ident, + sized: ast::Sized, bounds: OwnedSlice<ast::TyParamBound>, default: Option<P<ast::Ty>>) -> ast::TyParam { ast::TyParam { ident: id, id: ast::DUMMY_NODE_ID, + sized: sized, bounds: bounds, default: default, span: span diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 579de82c8db..35a1eb0bb83 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -13,6 +13,7 @@ The compiler code necessary for `#[deriving(Decodable)]`. See encodable.rs for more. */ +use ast; use ast::{MetaItem, Item, Expr, MutMutable, Ident}; use codemap::Span; use ext::base::ExtCtxt; @@ -35,10 +36,10 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt, additional_bounds: Vec::new(), generics: LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__D", vec!(Path::new_( + bounds: vec!(("__D", ast::StaticSize, vec!(Path::new_( vec!("serialize", "Decoder"), None, vec!(~Literal(Path::new_local("__E"))), true))), - ("__E", vec!())) + ("__E", ast::StaticSize, vec!())) }, methods: vec!( MethodDef { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 1c3edce96fb..806560f6826 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -82,6 +82,7 @@ would yield functions like: ``` */ +use ast; use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil}; use codemap::Span; use ext::base::ExtCtxt; @@ -103,10 +104,10 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt, additional_bounds: Vec::new(), generics: LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__S", vec!(Path::new_( + bounds: vec!(("__S", ast::StaticSize, vec!(Path::new_( vec!("serialize", "Encoder"), None, vec!(~Literal(Path::new_local("__E"))), true))), - ("__E", vec!())) + ("__E", ast::StaticSize, vec!())) }, methods: vec!( MethodDef { diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index c040361a8eb..914451fb402 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -380,7 +380,11 @@ impl<'a> TraitDef<'a> { // require the current trait bounds.push(cx.typarambound(trait_path.clone())); - cx.typaram(self.span, ty_param.ident, OwnedSlice::from_vec(bounds), None) + cx.typaram(self.span, + ty_param.ident, + ty_param.sized, + OwnedSlice::from_vec(bounds), + None) })); let trait_generics = Generics { lifetimes: lifetimes, diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 23331dc03cb..d22027d203f 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use ast; use ast::{MetaItem, Item, Expr, MutMutable}; use codemap::Span; use ext::base::ExtCtxt; @@ -25,7 +26,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, vec!(~Literal(Path::new_local("__S"))), true), LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__S", vec!(Path::new(vec!("std", "io", "Writer"))))), + bounds: vec!(("__S", ast::StaticSize, vec!(Path::new(vec!("std", "io", "Writer"))))), }, Path::new_local("__S")) } else { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 6b824e52bb3..e81aa55d10d 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -32,7 +32,8 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt, generics: LifetimeBounds { lifetimes: Vec::new(), bounds: vec!(("R", - vec!( Path::new(vec!("rand", "Rng")) ))) + ast::StaticSize, + vec!( Path::new(vec!("rand", "Rng")) ))) }, explicit_self: None, args: vec!( diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index a6bbad62b8e..6e3327b4039 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -186,14 +186,14 @@ impl<'a> Ty<'a> { } -fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, bounds: &[Path], +fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path], self_ident: Ident, self_generics: &Generics) -> ast::TyParam { let bounds = bounds.iter().map(|b| { let path = b.to_path(cx, span, self_ident, self_generics); cx.typarambound(path) }).collect(); - cx.typaram(span, cx.ident_of(name), bounds, None) + cx.typaram(span, cx.ident_of(name), sized, bounds, None) } fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) -> Generics { @@ -206,7 +206,7 @@ fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) - /// Lifetimes and bounds on type parameters pub struct LifetimeBounds<'a> { pub lifetimes: Vec<&'a str>, - pub bounds: Vec<(&'a str, Vec<Path<'a>>)>, + pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>, } impl<'a> LifetimeBounds<'a> { @@ -226,10 +226,11 @@ impl<'a> LifetimeBounds<'a> { }).collect(); let ty_params = self.bounds.iter().map(|t| { match t { - &(ref name, ref bounds) => { + &(ref name, sized, ref bounds) => { mk_ty_param(cx, span, *name, + sized, bounds.as_slice(), self_ty, self_generics) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 72be633d456..04b289b9fca 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -447,6 +447,7 @@ pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam { TyParam { ident: tp.ident, id: id, + sized: tp.sized, bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)), default: tp.default.map(|x| fld.fold_ty(x)), span: tp.span @@ -620,7 +621,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ methods.iter().map(|x| folder.fold_method(*x)).collect() ) } - ItemTrait(ref generics, ref traits, ref methods) => { + ItemTrait(ref generics, ref sized, ref traits, ref methods) => { let methods = methods.iter().map(|method| { match *method { Required(ref m) => Required(folder.fold_type_method(m)), @@ -628,6 +629,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ } }).collect(); ItemTrait(fold_generics(generics, folder), + *sized, traits.iter().map(|p| fold_trait_ref(p, folder)).collect(), methods) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 85480bebc90..8808312bed7 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -42,6 +42,7 @@ use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatUniq, PatWild, PatWildMulti}; use ast::{BiRem, Required}; use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl}; +use ast::{Sized, DynSize, StaticSize}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub}; use ast::StrStyle; @@ -3390,10 +3391,11 @@ impl<'a> Parser<'a> { return (ret_lifetime, Some(OwnedSlice::from_vec(result))); } - // matches typaram = IDENT optbounds ( EQ ty )? + // matches typaram = type? IDENT optbounds ( EQ ty )? fn parse_ty_param(&mut self) -> TyParam { - let ident = self.parse_ident(); + let sized = self.parse_sized(); let span = self.span; + let ident = self.parse_ident(); let (_, opt_bounds) = self.parse_optional_ty_param_bounds(false); // For typarams we don't care about the difference b/w "<T>" and "<T:>". let bounds = opt_bounds.unwrap_or_default(); @@ -3407,6 +3409,7 @@ impl<'a> Parser<'a> { TyParam { ident: ident, id: ast::DUMMY_NODE_ID, + sized: sized, bounds: bounds, default: default, span: span, @@ -3797,6 +3800,7 @@ impl<'a> Parser<'a> { fn parse_item_trait(&mut self) -> ItemInfo { let ident = self.parse_ident(); let tps = self.parse_generics(); + let sized = self.parse_for_sized(); // Parse traits, if necessary. let traits; @@ -3808,7 +3812,7 @@ impl<'a> Parser<'a> { } let meths = self.parse_trait_methods(); - (ident, ItemTrait(tps, traits, meths), None) + (ident, ItemTrait(tps, sized, traits, meths), None) } // Parses two variants (with the region/type params always optional): @@ -3999,6 +4003,23 @@ impl<'a> Parser<'a> { else { Inherited } } + fn parse_sized(&mut self) -> Sized { + if self.eat_keyword(keywords::Type) { DynSize } + else { StaticSize } + } + + fn parse_for_sized(&mut self) -> Sized { + if self.eat_keyword(keywords::For) { + if !self.eat_keyword(keywords::Type) { + self.span_err(self.last_span, + "expected 'type' after for in trait item"); + } + DynSize + } else { + StaticSize + } + } + // given a termination token and a vector of already-parsed // attributes (of length 0 or 1), parse all of the items in a module fn parse_mod_items(&mut self, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f4e337e2048..57438169d6d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -673,10 +673,13 @@ impl<'a> State<'a> { } try!(self.bclose(item.span)); } - ast::ItemTrait(ref generics, ref traits, ref methods) => { + ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => { try!(self.head(visibility_qualified(item.vis, "trait"))); try!(self.print_ident(item.ident)); try!(self.print_generics(generics)); + if *sized == ast::DynSize { + try!(self.word_space("for type")); + } if traits.len() != 0u { try!(word(&mut self.s, ":")); for (i, trait_) in traits.iter().enumerate() { @@ -1910,6 +1913,9 @@ impl<'a> State<'a> { } else { let idx = idx - generics.lifetimes.len(); let param = generics.ty_params.get(idx); + if param.sized == ast::DynSize { + try!(s.word_space("type")); + } try!(s.print_ident(param.ident)); try!(s.print_bounds(&None, ¶m.bounds, false)); match param.default { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1f75c2e062f..e830daf8ede 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -257,7 +257,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E) item.id, env) } - ItemTrait(ref generics, ref trait_paths, ref methods) => { + ItemTrait(ref generics, _, ref trait_paths, ref methods) => { visitor.visit_generics(generics, env.clone()); for trait_path in trait_paths.iter() { visitor.visit_path(&trait_path.path, |
