about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-01-30 10:41:47 -0800
committerbors <bors@rust-lang.org>2014-01-30 10:41:47 -0800
commit3427137f667e7def78f12a69af7d8beb2fcd5e65 (patch)
tree29a48dde22730fb4e1a36e10915dcb772a3802d1 /src/libsyntax
parent30e9bbaa2ce0042406c197cee142cbcbcbb7bc64 (diff)
parent7d967741c388a4c2e8f1e45f350d5a0abb083961 (diff)
downloadrust-3427137f667e7def78f12a69af7d8beb2fcd5e65.tar.gz
rust-3427137f667e7def78f12a69af7d8beb2fcd5e65.zip
auto merge of #11217 : eddyb/rust/generic-default-type-params, r=cmr
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/ext/build.rs17
-rw-r--r--src/libsyntax/ext/deriving/generic.rs2
-rw-r--r--src/libsyntax/ext/deriving/ty.rs2
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs30
-rw-r--r--src/libsyntax/print/pprust.rs8
-rw-r--r--src/libsyntax/visit.rs6
8 files changed, 57 insertions, 12 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 3070ecde71e..40ae98791ef 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -206,7 +206,8 @@ pub enum TyParamBound {
 pub struct TyParam {
     ident: Ident,
     id: NodeId,
-    bounds: OptVec<TyParamBound>
+    bounds: OptVec<TyParamBound>,
+    default: Option<P<Ty>>
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 3b43c96a184..9ad4f4f7fac 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -66,7 +66,10 @@ pub trait AstBuilder {
     fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField;
     fn strip_bounds(&self, bounds: &Generics) -> Generics;
 
-    fn typaram(&self, id: ast::Ident, bounds: OptVec<ast::TyParamBound>) -> ast::TyParam;
+    fn typaram(&self,
+               id: ast::Ident,
+               bounds: OptVec<ast::TyParamBound>,
+               default: Option<P<ast::Ty>>) -> ast::TyParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound;
@@ -354,8 +357,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         })
     }
 
-    fn typaram(&self, id: ast::Ident, bounds: OptVec<ast::TyParamBound>) -> ast::TyParam {
-        ast::TyParam { ident: id, id: ast::DUMMY_NODE_ID, bounds: bounds }
+    fn typaram(&self,
+               id: ast::Ident,
+               bounds: OptVec<ast::TyParamBound>,
+               default: Option<P<ast::Ty>>) -> ast::TyParam {
+        ast::TyParam {
+            ident: id,
+            id: ast::DUMMY_NODE_ID,
+            bounds: bounds,
+            default: default
+        }
     }
 
     // these are strange, and probably shouldn't be used outside of
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index 3c9401b109f..9ebb771f5da 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -375,7 +375,7 @@ impl<'a> TraitDef<'a> {
             // require the current trait
             bounds.push(cx.typarambound(trait_path.clone()));
 
-            trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds));
+            trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds, None));
         }
 
         // Create the reference to the trait.
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index b22dcfe0da2..893a1c68426 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -196,7 +196,7 @@ fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, bounds: &[Path],
             let path = b.to_path(cx, span, self_ident, self_generics);
             cx.typarambound(path)
         }));
-    cx.typaram(cx.ident_of(name), bounds)
+    cx.typaram(cx.ident_of(name), bounds, None)
 }
 
 fn mk_generics(lifetimes: ~[ast::Lifetime],  ty_params: ~[ast::TyParam]) -> Generics {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index d02f6384990..8dac13f1e31 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -406,6 +406,7 @@ pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
         ident: tp.ident,
         id: fld.new_id(tp.id),
         bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+        default: tp.default.map(|x| fld.fold_ty(x))
     }
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 0c81e87c7b8..04a984ba95d 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3452,13 +3452,25 @@ impl Parser {
         return Some(result);
     }
 
-    // matches typaram = IDENT optbounds
+    // matches typaram = IDENT optbounds ( EQ ty )?
     fn parse_ty_param(&mut self) -> TyParam {
         let ident = self.parse_ident();
         let opt_bounds = self.parse_optional_ty_param_bounds();
         // For typarams we don't care about the difference b/w "<T>" and "<T:>".
         let bounds = opt_bounds.unwrap_or_default();
-        ast::TyParam { ident: ident, id: ast::DUMMY_NODE_ID, bounds: bounds }
+
+        let default = if self.token == token::EQ {
+            self.bump();
+            Some(self.parse_ty(false))
+        }
+        else { None };
+
+        TyParam {
+            ident: ident,
+            id: ast::DUMMY_NODE_ID,
+            bounds: bounds,
+            default: default
+        }
     }
 
     // parse a set of optional generic type parameter declarations
@@ -3468,9 +3480,17 @@ impl Parser {
     pub fn parse_generics(&mut self) -> ast::Generics {
         if self.eat(&token::LT) {
             let lifetimes = self.parse_lifetimes();
-            let ty_params = self.parse_seq_to_gt(
-                Some(token::COMMA),
-                |p| p.parse_ty_param());
+            let mut seen_default = false;
+            let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
+                let ty_param = p.parse_ty_param();
+                if ty_param.default.is_some() {
+                    seen_default = true;
+                } else if seen_default {
+                    p.span_err(p.last_span,
+                               "type parameters with a default must be trailing");
+                }
+                ty_param
+            });
             ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
         } else {
             ast_util::empty_generics()
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 019f86b342d..2783284ea8b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1905,6 +1905,14 @@ pub fn print_generics(s: &mut State, generics: &ast::Generics) {
                 let param = generics.ty_params.get(idx);
                 print_ident(s, param.ident);
                 print_bounds(s, &param.bounds, false);
+                match param.default {
+                    Some(default) => {
+                        space(&mut s.s);
+                        word_space(s, "=");
+                        print_type(s, default);
+                    }
+                    _ => {}
+                }
             }
         }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 7201fc3a380..2a6c14f0eae 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -470,7 +470,11 @@ pub fn walk_generics<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                               generics: &Generics,
                                               env: E) {
     for type_parameter in generics.ty_params.iter() {
-        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
+        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone());
+        match type_parameter.default {
+            Some(ty) => visitor.visit_ty(ty, env.clone()),
+            None => {}
+        }
     }
     walk_lifetime_decls(visitor, &generics.lifetimes, env);
 }