diff options
| author | bors <bors@rust-lang.org> | 2014-01-30 10:41:47 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-01-30 10:41:47 -0800 |
| commit | 3427137f667e7def78f12a69af7d8beb2fcd5e65 (patch) | |
| tree | 29a48dde22730fb4e1a36e10915dcb772a3802d1 /src/libsyntax | |
| parent | 30e9bbaa2ce0042406c197cee142cbcbcbb7bc64 (diff) | |
| parent | 7d967741c388a4c2e8f1e45f350d5a0abb083961 (diff) | |
| download | rust-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.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/ty.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 30 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
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, ¶m.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); } |
