about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2014-07-08 14:26:02 +1200
committerNick Cameron <ncameron@mozilla.com>2014-07-08 22:44:31 +1200
commita0cfda53c4b7367f6494e3d746b35cea644ee50d (patch)
treea9a65cb86769ae39e01562cda9eda0dfdb860245 /src/libsyntax/parse
parent6959931498820b2b784168164b53a79dceafc4da (diff)
downloadrust-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.rs1
-rw-r--r--src/libsyntax/parse/parser.rs62
-rw-r--r--src/libsyntax/parse/token.rs2
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) => {