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/parse | |
| 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/parse')
| -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 |
3 files changed, 47 insertions, 18 deletions
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) => { |
