diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2014-07-08 14:26:02 +1200 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2014-07-08 22:44:31 +1200 |
| commit | a0cfda53c4b7367f6494e3d746b35cea644ee50d (patch) | |
| tree | a9a65cb86769ae39e01562cda9eda0dfdb860245 /src/libsyntax | |
| parent | 6959931498820b2b784168164b53a79dceafc4da (diff) | |
| download | rust-a0cfda53c4b7367f6494e3d746b35cea644ee50d.tar.gz rust-a0cfda53c4b7367f6494e3d746b35cea644ee50d.zip | |
Change DST syntax: type -> Sized?
closes #13367
[breaking-change] Use `Sized?` to indicate a dynamically sized type parameter or trait (used to be `type`). E.g.,
```
trait Tr for Sized? {}
fn foo<Sized? X: Share>(x: X) {}
```
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 8 | ||||
| -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/mod.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/ty.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/hash.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/rand.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 62 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 21 |
13 files changed, 89 insertions, 55 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ce1302c8db8..76dbae48839 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -184,8 +184,8 @@ pub enum TyParamBound { pub struct TyParam { pub ident: Ident, pub id: NodeId, - pub sized: Sized, pub bounds: OwnedSlice<TyParamBound>, + pub unbound: Option<TyParamBound>, pub default: Option<P<Ty>>, pub span: Span } @@ -1042,12 +1042,6 @@ impl Visibility { } #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] -pub enum Sized { - DynSize, - StaticSize, -} - -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] pub struct StructField_ { pub kind: StructFieldKind, pub id: NodeId, @@ -1115,7 +1109,11 @@ pub enum Item_ { ItemEnum(EnumDef, Generics), ItemStruct(Gc<StructDef>, Generics), /// Represents a Trait Declaration - ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ), + ItemTrait(Generics, + Option<TyParamBound>, // (optional) default bound not required for Self. + // Currently, only Sized makes sense here. + Vec<TraitRef> , + Vec<TraitMethod>), ItemImpl(Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 46bc4ec11ce..4d79ff3257a 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -66,8 +66,8 @@ pub trait AstBuilder { fn typaram(&self, span: Span, id: ast::Ident, - sized: ast::Sized, bounds: OwnedSlice<ast::TyParamBound>, + unbound: Option<ast::TyParamBound>, default: Option<P<ast::Ty>>) -> ast::TyParam; fn trait_ref(&self, path: ast::Path) -> ast::TraitRef; @@ -396,14 +396,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn typaram(&self, span: Span, id: ast::Ident, - sized: ast::Sized, bounds: OwnedSlice<ast::TyParamBound>, + unbound: Option<ast::TyParamBound>, default: Option<P<ast::Ty>>) -> ast::TyParam { ast::TyParam { ident: id, id: ast::DUMMY_NODE_ID, - sized: sized, bounds: bounds, + unbound: unbound, default: default, span: span } @@ -423,7 +423,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn strip_bounds(&self, generics: &Generics) -> Generics { let new_params = generics.ty_params.map(|ty_param| { - ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param } + ast::TyParam { bounds: OwnedSlice::empty(), unbound: None, ..*ty_param } }); Generics { ty_params: new_params, diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 0c23d65fde0..6da5f1e2700 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -13,7 +13,6 @@ 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; @@ -39,10 +38,10 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt, additional_bounds: Vec::new(), generics: LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__D", ast::StaticSize, vec!(Path::new_( + bounds: vec!(("__D", None, vec!(Path::new_( vec!("serialize", "Decoder"), None, vec!(box Literal(Path::new_local("__E"))), true))), - ("__E", ast::StaticSize, vec!())) + ("__E", None, vec!())) }, methods: vec!( MethodDef { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index f57670af199..652d593c004 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -82,7 +82,6 @@ would yield functions like: ``` */ -use ast; use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil}; use codemap::Span; use ext::base::ExtCtxt; @@ -107,10 +106,10 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt, additional_bounds: Vec::new(), generics: LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__S", ast::StaticSize, vec!(Path::new_( + bounds: vec!(("__S", None, vec!(Path::new_( vec!("serialize", "Encoder"), None, vec!(box Literal(Path::new_local("__E"))), true))), - ("__E", ast::StaticSize, vec!())) + ("__E", None, vec!())) }, methods: vec!( MethodDef { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 157b64fb47c..7ad11b186f5 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -406,8 +406,8 @@ impl<'a> TraitDef<'a> { cx.typaram(self.span, ty_param.ident, - ty_param.sized, OwnedSlice::from_vec(bounds), + ty_param.unbound.clone(), None) })); let trait_generics = Generics { diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs index 7501b950770..28f39a4cb8c 100644 --- a/src/libsyntax/ext/deriving/generic/ty.rs +++ b/src/libsyntax/ext/deriving/generic/ty.rs @@ -188,17 +188,18 @@ impl<'a> Ty<'a> { } -fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path], +fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, + bounds: &[Path], unbound: Option<ast::TyParamBound>, 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), sized, bounds, None) + cx.typaram(span, cx.ident_of(name), bounds, unbound, None) } -fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) -> Generics { +fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics { Generics { lifetimes: lifetimes, ty_params: OwnedSlice::from_vec(ty_params) @@ -208,7 +209,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, ast::Sized, Vec<Path<'a>>)>, + pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>, } impl<'a> LifetimeBounds<'a> { @@ -228,12 +229,12 @@ impl<'a> LifetimeBounds<'a> { }).collect(); let ty_params = self.bounds.iter().map(|t| { match t { - &(ref name, sized, ref bounds) => { + &(ref name, ref unbound, ref bounds) => { mk_ty_param(cx, span, *name, - sized, bounds.as_slice(), + unbound.clone(), self_ty, self_generics) } diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 77fb013b269..1b3ac47092a 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -8,7 +8,6 @@ // 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; @@ -30,7 +29,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, vec!(box Literal(Path::new_local("__S"))), true), LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__S", ast::StaticSize, + bounds: vec!(("__S", None, vec!(Path::new(vec!("std", "hash", "Writer"))))), }, Path::new_local("__S")) diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index f6a15ea917e..34b5f120d6a 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -35,7 +35,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt, generics: LifetimeBounds { lifetimes: Vec::new(), bounds: vec!(("R", - ast::StaticSize, + None, vec!( Path::new(vec!("std", "rand", "Rng")) ))) }, explicit_self: None, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 04e6612daf1..80dd4a83e48 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -491,8 +491,8 @@ 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)), + unbound: tp.unbound.as_ref().map(|x| fold_ty_param_bound(x, fld)), default: tp.default.map(|x| fld.fold_ty(x)), span: tp.span } @@ -666,7 +666,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 sized, ref traits, ref methods) => { + ItemTrait(ref generics, ref unbound, ref traits, ref methods) => { let methods = methods.iter().map(|method| { match *method { Required(ref m) => Required(folder.fold_type_method(m)), @@ -674,7 +674,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ } }).collect(); ItemTrait(fold_generics(generics, folder), - *sized, + unbound.clone(), traits.iter().map(|p| fold_trait_ref(p, folder)).collect(), methods) } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0f188fdf18a..1e72b2de20f 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -849,6 +849,7 @@ impl<'a> StringReader<'a> { '@' => { self.bump(); return token::AT; } '#' => { self.bump(); return token::POUND; } '~' => { self.bump(); return token::TILDE; } + '?' => { self.bump(); return token::QUESTION; } ':' => { self.bump(); if self.curr_is(':') { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6b6387b0127..3119d341281 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -42,7 +42,6 @@ use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, 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; @@ -3564,11 +3563,40 @@ impl<'a> Parser<'a> { return (ret_lifetime, OwnedSlice::from_vec(result)); } - // matches typaram = type? IDENT optbounds ( EQ ty )? + fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef { + let segment = ast::PathSegment { + identifier: ident, + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }; + let path = ast::Path { + span: span, + global: false, + segments: vec![segment], + }; + ast::TraitRef { + path: path, + ref_id: ast::DUMMY_NODE_ID, + } + } + + // matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )? fn parse_ty_param(&mut self) -> TyParam { - let sized = self.parse_sized(); - let span = self.span; - let ident = self.parse_ident(); + // This is a bit hacky. Currently we are only interested in a single + // unbound, and it may only be `Sized`. To avoid backtracking and other + // complications, we parse an ident, then check for `?`. If we find it, + // we use the ident as the unbound, otherwise, we use it as the name of + // type param. + let mut span = self.span; + let mut ident = self.parse_ident(); + let mut unbound = None; + if self.eat(&token::QUESTION) { + let tref = Parser::trait_ref_from_ident(ident, span); + unbound = Some(TraitTyParamBound(tref)); + span = self.span; + ident = self.parse_ident(); + } + let opt_bounds = { if self.eat(&token::COLON) { let (_, bounds) = self.parse_ty_param_bounds(false); @@ -3589,8 +3617,8 @@ impl<'a> Parser<'a> { TyParam { ident: ident, id: ast::DUMMY_NODE_ID, - sized: sized, bounds: bounds, + unbound: unbound, default: default, span: span, } @@ -4209,21 +4237,19 @@ 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 { + fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> { if self.eat_keyword(keywords::For) { - if !self.eat_keyword(keywords::Type) { - let last_span = self.last_span; - self.span_err(last_span, - "expected 'type' after for in trait item"); + let span = self.span; + let ident = self.parse_ident(); + if !self.eat(&token::QUESTION) { + self.span_err(span, + "expected 'Sized?' after `for` in trait item"); + return None; } - DynSize + let tref = Parser::trait_ref_from_ident(ident, span); + Some(TraitTyParamBound(tref)) } else { - StaticSize + None } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index dcf37e37ff0..367b18916ac 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -76,6 +76,7 @@ pub enum Token { RBRACE, POUND, DOLLAR, + QUESTION, /* Literals */ LIT_BYTE(u8), @@ -195,6 +196,7 @@ pub fn to_str(t: &Token) -> String { RBRACE => "}".to_string(), POUND => "#".to_string(), DOLLAR => "$".to_string(), + QUESTION => "?".to_string(), /* Literals */ LIT_BYTE(b) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bf210110829..cdaa9bbd8dd 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -740,14 +740,19 @@ impl<'a> State<'a> { } try!(self.bclose(item.span)); } - ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => { + ast::ItemTrait(ref generics, ref unbound, ref traits, ref methods) => { try!(self.head(visibility_qualified(item.vis, "trait").as_slice())); try!(self.print_ident(item.ident)); try!(self.print_generics(generics)); - if *sized == ast::DynSize { - try!(space(&mut self.s)); - try!(word(&mut self.s, "for type")); + match unbound { + &Some(TraitTyParamBound(ref tref)) => { + try!(space(&mut self.s)); + try!(self.word_space("for")); + try!(self.print_trait_ref(tref)); + try!(word(&mut self.s, "?")); + } + _ => {} } if traits.len() != 0u { try!(word(&mut self.s, ":")); @@ -2029,8 +2034,12 @@ 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")); + match param.unbound { + Some(TraitTyParamBound(ref tref)) => { + try!(s.print_trait_ref(tref)); + try!(s.word_space("?")); + } + _ => {} } try!(s.print_ident(param.ident)); try!(s.print_bounds(&None, |
