diff options
| author | bors <bors@rust-lang.org> | 2014-12-30 08:02:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-12-30 08:02:39 +0000 |
| commit | d2368c3c11ddab9d812c4ddec2e44579326ad347 (patch) | |
| tree | b976bc0eb040da67646a9d99bb9b901cb9f55abd /src/libsyntax | |
| parent | fea5aa656ff4349f4d3e1fea1447d26986762ae1 (diff) | |
| parent | 470ae101d6e26a6ce07292b7fca6eaed527451c7 (diff) | |
| download | rust-d2368c3c11ddab9d812c4ddec2e44579326ad347.tar.gz rust-d2368c3c11ddab9d812c4ddec2e44579326ad347.zip | |
auto merge of #20320 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/config.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/decodable.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/ty.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/hash.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/rand.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 102 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 13 |
15 files changed, 137 insertions, 76 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index debcbcd2154..f253943943d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -371,10 +371,18 @@ pub const DUMMY_NODE_ID: NodeId = -1; /// detects Copy, Send and Sync. #[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] pub enum TyParamBound { - TraitTyParamBound(PolyTraitRef), + TraitTyParamBound(PolyTraitRef, TraitBoundModifier), RegionTyParamBound(Lifetime) } +/// A modifier on a bound, currently this is only used for `?Sized`, where the +/// modifier is `Maybe`. Negative bounds should also be handled here. +#[deriving(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] +pub enum TraitBoundModifier { + None, + Maybe, +} + pub type TyParamBounds = OwnedSlice<TyParamBound>; #[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] @@ -382,7 +390,6 @@ pub struct TyParam { pub ident: Ident, pub id: NodeId, pub bounds: TyParamBounds, - pub unbound: Option<TraitRef>, pub default: Option<P<Ty>>, pub span: Span } @@ -1488,7 +1495,7 @@ pub struct PolyTraitRef { pub bound_lifetimes: Vec<LifetimeDef>, /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` - pub trait_ref: TraitRef + pub trait_ref: TraitRef, } #[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)] @@ -1577,8 +1584,6 @@ pub enum Item_ { /// Represents a Trait Declaration ItemTrait(Unsafety, Generics, - Option<TraitRef>, // (optional) default bound not required for Self. - // Currently, only Sized makes sense here. TyParamBounds, Vec<TraitItem>), ItemImpl(Unsafety, diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 9b42a8f7540..5a4f5731be5 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -780,9 +780,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { None => {} } } - ItemTrait(_, _, _, ref bounds, ref trait_items) => { + ItemTrait(_, _, ref bounds, ref trait_items) => { for b in bounds.iter() { - if let TraitTyParamBound(ref t) = *b { + if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { self.insert(t.trait_ref.ref_id, NodeItem(i)); } } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index d2185a00876..94a3784291d 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -139,11 +139,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ .collect(); ast::ItemImpl(u, a, b, c, impl_items) } - ast::ItemTrait(u, a, b, c, methods) => { + ast::ItemTrait(u, a, b, methods) => { let methods = methods.into_iter() .filter(|m| trait_method_in_cfg(cx, m)) .collect(); - ast::ItemTrait(u, a, b, c, methods) + ast::ItemTrait(u, a, b, methods) } ast::ItemStruct(def, generics) => { ast::ItemStruct(fold_struct(cx, def), generics) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 77165168746..239af188909 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -68,7 +68,6 @@ pub trait AstBuilder { span: Span, id: ast::Ident, bounds: OwnedSlice<ast::TyParamBound>, - unbound: Option<ast::TraitRef>, default: Option<P<ast::Ty>>) -> ast::TyParam; fn trait_ref(&self, path: ast::Path) -> ast::TraitRef; @@ -414,13 +413,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { span: Span, id: ast::Ident, bounds: OwnedSlice<ast::TyParamBound>, - unbound: Option<ast::TraitRef>, default: Option<P<ast::Ty>>) -> ast::TyParam { ast::TyParam { ident: id, id: ast::DUMMY_NODE_ID, bounds: bounds, - unbound: unbound, default: default, span: span } @@ -455,7 +452,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn typarambound(&self, path: ast::Path) -> ast::TyParamBound { - ast::TraitTyParamBound(self.poly_trait_ref(path)) + ast::TraitTyParamBound(self.poly_trait_ref(path), ast::TraitBoundModifier::None) } fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime { diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 57dfbc0c6e8..3c8d74c14ee 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -58,10 +58,10 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt, additional_bounds: Vec::new(), generics: LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__D", None, vec!(Path::new_( + bounds: vec!(("__D", vec!(Path::new_( vec!(krate, "Decoder"), None, vec!(box Literal(Path::new_local("__E"))), true))), - ("__E", None, vec!())) + ("__E", vec!())) }, methods: vec!( MethodDef { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 8bd3df6232c..5829f34bccc 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -134,10 +134,10 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt, additional_bounds: Vec::new(), generics: LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__S", None, vec!(Path::new_( + bounds: vec!(("__S", vec!(Path::new_( vec!(krate, "Encoder"), None, vec!(box Literal(Path::new_local("__E"))), true))), - ("__E", None, vec!())) + ("__E", vec!())) }, methods: vec!( MethodDef { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index cf0201294ae..e4e31139d82 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -417,7 +417,6 @@ impl<'a> TraitDef<'a> { cx.typaram(self.span, ty_param.ident, OwnedSlice::from_vec(bounds), - ty_param.unbound.clone(), None) })); diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs index 56d11c2377f..95bdd8b9ffd 100644 --- a/src/libsyntax/ext/deriving/generic/ty.rs +++ b/src/libsyntax/ext/deriving/generic/ty.rs @@ -189,15 +189,19 @@ impl<'a> Ty<'a> { } -fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, - bounds: &[Path], unbound: Option<ast::TraitRef>, - self_ident: Ident, self_generics: &Generics) -> ast::TyParam { +fn mk_ty_param(cx: &ExtCtxt, + span: Span, + name: &str, + bounds: &[Path], + 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), bounds, unbound, None) + cx.typaram(span, cx.ident_of(name), bounds, None) } fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>) @@ -216,7 +220,7 @@ fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>) #[deriving(Clone)] pub struct LifetimeBounds<'a> { pub lifetimes: Vec<(&'a str, Vec<&'a str>)>, - pub bounds: Vec<(&'a str, Option<ast::TraitRef>, Vec<Path<'a>>)>, + pub bounds: Vec<(&'a str, Vec<Path<'a>>)>, } impl<'a> LifetimeBounds<'a> { @@ -239,12 +243,11 @@ impl<'a> LifetimeBounds<'a> { }).collect(); let ty_params = self.bounds.iter().map(|t| { match t { - &(ref name, ref unbound, ref bounds) => { + &(ref name, ref bounds) => { mk_ty_param(cx, span, *name, 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 4e59124a129..72e3b45dc91 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -30,7 +30,7 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt, vec!(box Literal(Path::new_local("__S"))), true), LifetimeBounds { lifetimes: Vec::new(), - bounds: vec!(("__S", None, + bounds: vec!(("__S", 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 4f6e4d1fb3c..1ddf5b2a5c3 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -36,7 +36,6 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt, generics: LifetimeBounds { lifetimes: Vec::new(), bounds: vec!(("R", - None, vec!( Path::new(vec!("std", "rand", "Rng")) ))) }, explicit_self: None, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 11a9fdee0b9..4f0169e31f2 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -736,18 +736,17 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) -> TyParamBound where T: Folder { match tpb { - TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_poly_trait_ref(ty)), + TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier), RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), } } pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam { - let TyParam {id, ident, bounds, unbound, default, span} = tp; + let TyParam {id, ident, bounds, default, span} = tp; TyParam { id: fld.new_id(id), ident: ident, bounds: fld.fold_bounds(bounds), - unbound: unbound.map(|x| fld.fold_trait_ref(x)), default: default.map(|x| fld.fold_ty(x)), span: span } @@ -1043,7 +1042,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ { folder.fold_ty(ty), new_impl_items) } - ItemTrait(unsafety, generics, unbound, bounds, methods) => { + ItemTrait(unsafety, generics, bounds, methods) => { let bounds = folder.fold_bounds(bounds); let methods = methods.into_iter().flat_map(|method| { let r = match method { @@ -1073,7 +1072,6 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ { }).collect(); ItemTrait(unsafety, folder.fold_generics(generics), - unbound, bounds, methods) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2f43661eebe..e88aabb044c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -15,7 +15,7 @@ use self::ItemOrViewItem::*; use abi; use ast::{AssociatedType, BareFnTy, ClosureTy}; -use ast::{RegionTyParamBound, TraitTyParamBound}; +use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::{ProvidedMethod, Public, Unsafety}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, Block}; @@ -117,6 +117,13 @@ pub enum PathParsingMode { LifetimeAndTypesWithColons, } +/// How to parse a bound, whether to allow bound modifiers such as `?`. +#[deriving(Copy, PartialEq)] +pub enum BoundParsingMode { + Bare, + Modified, +} + enum ItemOrViewItem { /// Indicates a failure to parse any kind of item. The attributes are /// returned. @@ -1087,12 +1094,12 @@ impl<'a> Parser<'a> { let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs, trait_ref: trait_ref }; let other_bounds = if self.eat(&token::BinOp(token::Plus)) { - self.parse_ty_param_bounds() + self.parse_ty_param_bounds(BoundParsingMode::Bare) } else { OwnedSlice::empty() }; let all_bounds = - Some(TraitTyParamBound(poly_trait_ref)).into_iter() + Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter() .chain(other_bounds.into_vec().into_iter()) .collect(); ast::TyPolyTraitRef(all_bounds) @@ -1165,7 +1172,7 @@ impl<'a> Parser<'a> { // To be helpful, parse the proc as ever let _ = self.parse_legacy_lifetime_defs(lifetime_defs); let _ = self.parse_fn_args(false, false); - let _ = self.parse_colon_then_ty_param_bounds(); + let _ = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare); let _ = self.parse_ret_ty(); self.obsolete(proc_span, ObsoleteProcType); @@ -1255,7 +1262,7 @@ impl<'a> Parser<'a> { inputs }; - let bounds = self.parse_colon_then_ty_param_bounds(); + let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare); let output = self.parse_ret_ty(); let decl = P(FnDecl { @@ -1481,7 +1488,7 @@ impl<'a> Parser<'a> { return lhs; } - let bounds = self.parse_ty_param_bounds(); + let bounds = self.parse_ty_param_bounds(BoundParsingMode::Bare); // In type grammar, `+` is treated like a binary operator, // and hence both L and R side are required. @@ -4029,13 +4036,14 @@ impl<'a> Parser<'a> { // Parses a sequence of bounds if a `:` is found, // otherwise returns empty list. - fn parse_colon_then_ty_param_bounds(&mut self) + fn parse_colon_then_ty_param_bounds(&mut self, + mode: BoundParsingMode) -> OwnedSlice<TyParamBound> { if !self.eat(&token::Colon) { OwnedSlice::empty() } else { - self.parse_ty_param_bounds() + self.parse_ty_param_bounds(mode) } } @@ -4043,14 +4051,20 @@ impl<'a> Parser<'a> { // where boundseq = ( polybound + boundseq ) | polybound // and polybound = ( 'for' '<' 'region '>' )? bound // and bound = 'region | trait_ref - // NB: The None/Some distinction is important for issue #7264. - fn parse_ty_param_bounds(&mut self) + fn parse_ty_param_bounds(&mut self, + mode: BoundParsingMode) -> OwnedSlice<TyParamBound> { let mut result = vec!(); loop { + let question_span = self.span; + let ate_question = self.eat(&token::Question); match self.token { token::Lifetime(lifetime) => { + if ate_question { + self.span_err(question_span, + "`?` may only modify trait bounds, not lifetime bounds"); + } result.push(RegionTyParamBound(ast::Lifetime { id: ast::DUMMY_NODE_ID, span: self.span, @@ -4060,7 +4074,18 @@ impl<'a> Parser<'a> { } token::ModSep | token::Ident(..) => { let poly_trait_ref = self.parse_poly_trait_ref(); - result.push(TraitTyParamBound(poly_trait_ref)) + let modifier = if ate_question { + if mode == BoundParsingMode::Modified { + TraitBoundModifier::Maybe + } else { + self.span_err(question_span, + "unexpected `?`"); + TraitBoundModifier::None + } + } else { + TraitBoundModifier::None + }; + result.push(TraitTyParamBound(poly_trait_ref, modifier)) } _ => break, } @@ -4089,13 +4114,14 @@ impl<'a> Parser<'a> { } } - /// Matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )? + /// Matches typaram = (unbound `?`)? IDENT (`?` unbound)? optbounds ( EQ ty )? fn parse_ty_param(&mut self) -> TyParam { // 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. + // type param. Even worse, for now, we need to check for `?` before or + // after the bound. let mut span = self.span; let mut ident = self.parse_ident(); let mut unbound = None; @@ -4106,7 +4132,14 @@ impl<'a> Parser<'a> { ident = self.parse_ident(); } - let bounds = self.parse_colon_then_ty_param_bounds(); + let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Modified); + if let Some(unbound) = unbound { + let mut bounds_as_vec = bounds.into_vec(); + bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![], + trait_ref: unbound }, + TraitBoundModifier::Maybe)); + bounds = OwnedSlice::from_vec(bounds_as_vec); + }; let default = if self.check(&token::Eq) { self.bump(); @@ -4118,7 +4151,6 @@ impl<'a> Parser<'a> { ident: ident, id: ast::DUMMY_NODE_ID, bounds: bounds, - unbound: unbound, default: default, span: span, } @@ -4260,7 +4292,7 @@ impl<'a> Parser<'a> { let bounded_ty = self.parse_ty(); if self.eat(&token::Colon) { - let bounds = self.parse_ty_param_bounds(); + let bounds = self.parse_ty_param_bounds(BoundParsingMode::Bare); let hi = self.span.hi; let span = mk_sp(lo, hi); @@ -4747,15 +4779,23 @@ impl<'a> Parser<'a> { fn parse_item_trait(&mut self, unsafety: Unsafety) -> ItemInfo { let ident = self.parse_ident(); let mut tps = self.parse_generics(); - let sized = self.parse_for_sized(); + let unbound = self.parse_for_sized(); // Parse supertrait bounds. - let bounds = self.parse_colon_then_ty_param_bounds(); + let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare); + + if let Some(unbound) = unbound { + let mut bounds_as_vec = bounds.into_vec(); + bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![], + trait_ref: unbound }, + TraitBoundModifier::Maybe)); + bounds = OwnedSlice::from_vec(bounds_as_vec); + }; self.parse_where_clause(&mut tps); let meths = self.parse_trait_items(); - (ident, ItemTrait(unsafety, tps, sized, bounds, meths), None) + (ident, ItemTrait(unsafety, tps, bounds, meths), None) } fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) { @@ -4974,12 +5014,25 @@ impl<'a> Parser<'a> { } fn parse_for_sized(&mut self) -> Option<ast::TraitRef> { + // FIXME, this should really use TraitBoundModifier, but it will get + // re-jigged shortly in any case, so leaving the hacky version for now. if self.eat_keyword(keywords::For) { let span = self.span; + let mut ate_question = false; + if self.eat(&token::Question) { + ate_question = true; + } let ident = self.parse_ident(); - if !self.eat(&token::Question) { + if self.eat(&token::Question) { + if ate_question { + self.span_err(span, + "unexpected `?`"); + } + ate_question = true; + } + if !ate_question { self.span_err(span, - "expected 'Sized?' after `for` in trait item"); + "expected `?Sized` after `for` in trait item"); return None; } let tref = Parser::trait_ref_from_ident(ident, span); @@ -5924,7 +5977,7 @@ impl<'a> Parser<'a> { } - /// Matches view_path : MOD? IDENT EQ non_global_path + /// Matches view_path : MOD? non_global_path as IDENT /// | MOD? non_global_path MOD_SEP LBRACE RBRACE /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE /// | MOD? non_global_path MOD_SEP STAR @@ -6036,7 +6089,7 @@ impl<'a> Parser<'a> { } let mut rename_to = path[path.len() - 1u]; let path = ast::Path { - span: mk_sp(lo, self.span.hi), + span: mk_sp(lo, self.last_span.hi), global: false, segments: path.into_iter().map(|identifier| { ast::PathSegment { @@ -6048,7 +6101,8 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::As) { rename_to = self.parse_ident() } - P(spanned(lo, self.last_span.hi, + P(spanned(lo, + self.last_span.hi, ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID))) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index f575d3d6c67..f22a4b5c6ed 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -724,7 +724,7 @@ pub fn fresh_name(src: &ast::Ident) -> ast::Name { // following: debug version. Could work in final except that it's incompatible with // good error messages and uses of struct names in ambiguous could-be-binding // locations. Also definitely destroys the guarantee given above about ptr_eq. - /*let num = rand::task_rng().gen_uint_range(0,0xffff); + /*let num = rand::thread_rng().gen_uint_range(0,0xffff); gensym(format!("{}_{}",ident_to_string(src),num))*/ } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index accffbc35ba..02a03285d3b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -13,7 +13,7 @@ pub use self::AnnNode::*; use abi; use ast::{mod, FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; -use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound}; +use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; use ast::{UnboxedClosureKind}; use ast_util; @@ -958,20 +958,25 @@ impl<'a> State<'a> { } try!(self.bclose(item.span)); } - ast::ItemTrait(unsafety, ref generics, ref unbound, ref bounds, ref methods) => { + ast::ItemTrait(unsafety, ref generics, ref bounds, ref methods) => { try!(self.head("")); try!(self.print_visibility(item.vis)); try!(self.print_unsafety(unsafety)); try!(self.word_nbsp("trait")); try!(self.print_ident(item.ident)); try!(self.print_generics(generics)); - if let &Some(ref tref) = unbound { - try!(space(&mut self.s)); - try!(self.word_space("for")); - try!(self.print_trait_ref(tref)); - try!(word(&mut self.s, "?")); + let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect(); + let mut real_bounds = Vec::with_capacity(bounds.len()); + for b in bounds.into_iter() { + if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b { + try!(space(&mut self.s)); + try!(self.word_space("for ?")); + try!(self.print_trait_ref(&ptr.trait_ref)); + } else { + real_bounds.push(b); + } } - try!(self.print_bounds(":", bounds[])); + try!(self.print_bounds(":", real_bounds[])); try!(self.print_where_clause(generics)); try!(word(&mut self.s, " ")); try!(self.bopen()); @@ -2345,7 +2350,11 @@ impl<'a> State<'a> { } try!(match *bound { - TraitTyParamBound(ref tref) => { + TraitTyParamBound(ref tref, TraitBoundModifier::None) => { + self.print_poly_trait_ref(tref) + } + TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => { + try!(word(&mut self.s, "?")); self.print_poly_trait_ref(tref) } RegionTyParamBound(ref lt) => { @@ -2412,10 +2421,6 @@ impl<'a> State<'a> { } pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> { - if let Some(ref tref) = param.unbound { - try!(self.print_trait_ref(tref)); - try!(self.word_space("?")); - } try!(self.print_ident(param.ident)); try!(self.print_bounds(":", param.bounds[])); match param.default { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 22cfea86251..1cd21ccac7a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -85,8 +85,8 @@ pub trait Visitor<'v> { fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) { walk_ty_param_bound(self, bounds) } - fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef) { - walk_poly_trait_ref(self, t) + fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) { + walk_poly_trait_ref(self, t, m) } fn visit_struct_def(&mut self, s: &'v StructDef, _: Ident, _: &'v Generics, _: NodeId) { walk_struct_def(self, s) @@ -244,7 +244,8 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, /// Like with walk_method_helper this doesn't correspond to a method /// in Visitor, and so it gets a _helper suffix. pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, - trait_ref: &'v PolyTraitRef) + trait_ref: &'v PolyTraitRef, + _modifier: &'v TraitBoundModifier) where V: Visitor<'v> { walk_lifetime_decls_helper(visitor, &trait_ref.bound_lifetimes); @@ -324,7 +325,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { generics, item.id) } - ItemTrait(_, ref generics, _, ref bounds, ref methods) => { + ItemTrait(_, ref generics, ref bounds, ref methods) => { visitor.visit_generics(generics); walk_ty_param_bounds_helper(visitor, bounds); for method in methods.iter() { @@ -558,8 +559,8 @@ pub fn walk_ty_param_bounds_helper<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) { match *bound { - TraitTyParamBound(ref typ) => { - visitor.visit_poly_trait_ref(typ); + TraitTyParamBound(ref typ, ref modifier) => { + visitor.visit_poly_trait_ref(typ, modifier); } RegionTyParamBound(ref lifetime) => { visitor.visit_lifetime_bound(lifetime); |
