diff options
| author | bors <bors@rust-lang.org> | 2016-05-26 22:46:08 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-05-26 22:46:08 -0700 |
| commit | 36d5dc7c9bcfd287b5c4e4ac3e2f0ab93bdaa0c9 (patch) | |
| tree | 7e1af7784abe1ebab1c219d13e1a57439eb91996 /src/libsyntax | |
| parent | 97e3a2401e4b2f659d69ed0c0822cae04e3495b7 (diff) | |
| parent | 63dfbdbc1bc1ace106a525682f77b3d08af9ad71 (diff) | |
| download | rust-36d5dc7c9bcfd287b5c4e4ac3e2f0ab93bdaa0c9.tar.gz rust-36d5dc7c9bcfd287b5c4e4ac3e2f0ab93bdaa0c9.zip | |
Auto merge of #33864 - Manishearth:breaking-batch, r=Manishearth
Batch up libsyntax breaking changes cc https://github.com/rust-lang/rust/issues/31645
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 112 | ||||
| -rw-r--r-- | src/libsyntax/codemap.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 53 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 199 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 133 | ||||
| -rw-r--r-- | src/libsyntax/util/node_count.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 66 |
10 files changed, 275 insertions, 341 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d9409d3bbd9..9ecaa5b346a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -567,7 +567,7 @@ impl Pat { PatKind::Struct(_, ref fields, _) => { fields.iter().all(|field| field.node.pat.walk(it)) } - PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => { + PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => { s.iter().all(|p| p.walk(it)) } PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { @@ -582,7 +582,6 @@ impl Pat { PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::Ident(_, _, _) | - PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(_, _) | PatKind::Mac(_) => { @@ -631,9 +630,10 @@ pub enum PatKind { /// The `bool` is `true` in the presence of a `..`. Struct(Path, Vec<Spanned<FieldPat>>, bool), - /// A tuple struct/variant pattern `Variant(x, y, z)`. - /// "None" means a `Variant(..)` pattern where we don't bind the fields to names. - TupleStruct(Path, Option<Vec<P<Pat>>>), + /// A tuple struct/variant pattern `Variant(x, y, .., z)`. + /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position. + /// 0 <= position <= subpats.len() + TupleStruct(Path, Vec<P<Pat>>, Option<usize>), /// A path pattern. /// Such pattern can be resolved to a unit struct/variant or a constant. @@ -645,8 +645,10 @@ pub enum PatKind { /// PatKind::Path, and the resolver will have to sort that out. QPath(QSelf, Path), - /// A tuple pattern `(a, b)` - Tup(Vec<P<Pat>>), + /// A tuple pattern `(a, b)`. + /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position. + /// 0 <= position <= subpats.len() + Tuple(Vec<P<Pat>>, Option<usize>), /// A `box` pattern Box(P<Pat>), /// A reference pattern, e.g. `&mut (a, b)` @@ -1007,23 +1009,23 @@ pub enum ExprKind { /// A while loop, with an optional label /// /// `'label: while expr { block }` - While(P<Expr>, P<Block>, Option<Ident>), + While(P<Expr>, P<Block>, Option<SpannedIdent>), /// A while-let loop, with an optional label /// /// `'label: while let pat = expr { block }` /// /// This is desugared to a combination of `loop` and `match` expressions. - WhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>), + WhileLet(P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>), /// A for loop, with an optional label /// /// `'label: for pat in expr { block }` /// /// This is desugared to a combination of `loop` and `match` expressions. - ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>), + ForLoop(P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>), /// Conditionless loop (can be exited with break, continue, or return) /// /// `'label: loop { block }` - Loop(P<Block>, Option<Ident>), + Loop(P<Block>, Option<SpannedIdent>), /// A `match` block. Match(P<Expr>, Vec<Arm>), /// A closure (for example, `move |a, b, c| {a + b + c}`) @@ -1387,7 +1389,6 @@ pub struct MethodSig { pub abi: Abi, pub decl: P<FnDecl>, pub generics: Generics, - pub explicit_self: ExplicitSelf, } /// Represents an item declaration within a trait declaration, @@ -1638,6 +1639,8 @@ pub enum TyKind { /// TyKind::Infer means the type should be inferred instead of it having been /// specified. This can appear anywhere in a type. Infer, + /// Inferred type of a `self` or `&self` argument in a method. + ImplicitSelf, // A macro in the type position. Mac(Mac), } @@ -1677,81 +1680,65 @@ pub struct Arg { pub id: NodeId, } -/// Represents the kind of 'self' associated with a method. -/// String representation of `Ident` here is always "self", but hygiene contexts may differ. +/// Alternative representation for `Arg`s describing `self` parameter of methods. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum SelfKind { - /// No self - Static, /// `self`, `mut self` - Value(Ident), + Value(Mutability), /// `&'lt self`, `&'lt mut self` - Region(Option<Lifetime>, Mutability, Ident), + Region(Option<Lifetime>, Mutability), /// `self: TYPE`, `mut self: TYPE` - Explicit(P<Ty>, Ident), + Explicit(P<Ty>, Mutability), } pub type ExplicitSelf = Spanned<SelfKind>; impl Arg { - #[unstable(feature = "rustc_private", issue = "27812")] - #[rustc_deprecated(since = "1.10.0", reason = "use `from_self` instead")] - pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { - let path = Spanned{span:span,node:self_ident}; - Arg { - // HACK(eddyb) fake type for the self argument. - ty: P(Ty { - id: DUMMY_NODE_ID, - node: TyKind::Infer, - span: DUMMY_SP, - }), - pat: P(Pat { - id: DUMMY_NODE_ID, - node: PatKind::Ident(BindingMode::ByValue(mutability), path, None), - span: span - }), - id: DUMMY_NODE_ID - } - } - pub fn to_self(&self) -> Option<ExplicitSelf> { - if let PatKind::Ident(_, ident, _) = self.pat.node { + if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node { if ident.node.name == keywords::SelfValue.name() { return match self.ty.node { - TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(ident.node))), - TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::Infer => { - Some(respan(self.pat.span, SelfKind::Region(lt, mutbl, ident.node))) + TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), + TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::ImplicitSelf => { + Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) } _ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi), - SelfKind::Explicit(self.ty.clone(), ident.node))), + SelfKind::Explicit(self.ty.clone(), mutbl))), } } } None } - pub fn from_self(eself: ExplicitSelf, ident_sp: Span, mutbl: Mutability) -> Arg { - let pat = |ident, span| P(Pat { - id: DUMMY_NODE_ID, - node: PatKind::Ident(BindingMode::ByValue(mutbl), respan(ident_sp, ident), None), - span: span, - }); + pub fn is_self(&self) -> bool { + if let PatKind::Ident(_, ident, _) = self.pat.node { + ident.node.name == keywords::SelfValue.name() + } else { + false + } + } + + pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg { let infer_ty = P(Ty { id: DUMMY_NODE_ID, - node: TyKind::Infer, + node: TyKind::ImplicitSelf, span: DUMMY_SP, }); - let arg = |ident, ty, span| Arg { - pat: pat(ident, span), + let arg = |mutbl, ty, span| Arg { + pat: P(Pat { + id: DUMMY_NODE_ID, + node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None), + span: span, + }), ty: ty, id: DUMMY_NODE_ID, }; match eself.node { - SelfKind::Static => panic!("bug: `Arg::from_self` is called \ - with `SelfKind::Static` argument"), - SelfKind::Explicit(ty, ident) => arg(ident, ty, mk_sp(eself.span.lo, ident_sp.hi)), - SelfKind::Value(ident) => arg(ident, infer_ty, eself.span), - SelfKind::Region(lt, mutbl, ident) => arg(ident, P(Ty { + SelfKind::Explicit(ty, mutbl) => { + arg(mutbl, ty, mk_sp(eself.span.lo, eself_ident.span.hi)) + } + SelfKind::Value(mutbl) => arg(mutbl, infer_ty, eself.span), + SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty { id: DUMMY_NODE_ID, node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }), span: DUMMY_SP, @@ -1768,6 +1755,15 @@ pub struct FnDecl { pub variadic: bool } +impl FnDecl { + pub fn get_self(&self) -> Option<ExplicitSelf> { + self.inputs.get(0).and_then(Arg::to_self) + } + pub fn has_self(&self) -> bool { + self.inputs.get(0).map(Arg::is_self).unwrap_or(false) + } +} + #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Unsafety { Unsafe, diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index ca8708fdc83..3b13bf2fc50 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -1191,13 +1191,13 @@ impl CodeMap { } } - pub fn get_filemap(&self, filename: &str) -> Rc<FileMap> { + pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> { for fm in self.files.borrow().iter() { if filename == fm.name { - return fm.clone(); + return Some(fm.clone()); } } - panic!("asking for {} which we don't know about", filename); + None } /// For a global BytePos compute the local offset within the containing FileMap diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 7958162986c..3a1cdae9bfb 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -832,7 +832,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let pat = if subpats.is_empty() { PatKind::Path(path) } else { - PatKind::TupleStruct(path, Some(subpats)) + PatKind::TupleStruct(path, subpats, None) }; self.pat(span, pat) } @@ -842,7 +842,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.pat(span, pat) } fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { - self.pat(span, PatKind::Tup(pats)) + self.pat(span, PatKind::Tuple(pats, None)) } fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 596faac3588..ecca370fb8a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -9,7 +9,7 @@ // except according to those terms. use ast::{Block, Crate, DeclKind, PatKind}; -use ast::{Local, Ident, Mac_, Name}; +use ast::{Local, Ident, Mac_, Name, SpannedIdent}; use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind}; use ast::TokenTree; use ast; @@ -334,12 +334,12 @@ fn expand_mac_invoc<T>(mac: ast::Mac, ident: Option<Ident>, attrs: Vec<ast::Attr /// body is in a block enclosed by loop head so the renaming of loop label /// must be propagated to the enclosed context. fn expand_loop_block(loop_block: P<Block>, - opt_ident: Option<Ident>, - fld: &mut MacroExpander) -> (P<Block>, Option<Ident>) { + opt_ident: Option<SpannedIdent>, + fld: &mut MacroExpander) -> (P<Block>, Option<SpannedIdent>) { match opt_ident { Some(label) => { - let new_label = fresh_name(label); - let rename = (label, new_label); + let new_label = fresh_name(label.node); + let rename = (label.node, new_label); // The rename *must not* be added to the pending list of current // syntax context otherwise an unrelated `break` or `continue` in @@ -347,7 +347,7 @@ fn expand_loop_block(loop_block: P<Block>, // and be renamed incorrectly. let mut rename_list = vec!(rename); let mut rename_fld = IdentRenamer{renames: &mut rename_list}; - let renamed_ident = rename_fld.fold_ident(label); + let renamed_ident = rename_fld.fold_ident(label.node); // The rename *must* be added to the enclosed syntax context for // `break` or `continue` to pick up because by definition they are @@ -357,7 +357,7 @@ fn expand_loop_block(loop_block: P<Block>, let expanded_block = expand_block_elts(loop_block, fld); fld.cx.syntax_env.pop_frame(); - (expanded_block, Some(renamed_ident)) + (expanded_block, Some(Spanned { node: renamed_ident, span: label.span })) } None => (fld.fold_block(loop_block), opt_ident) } @@ -950,7 +950,6 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>, (ast::MethodSig { generics: fld.fold_generics(sig.generics), abi: sig.abi, - explicit_self: fld.fold_explicit_self(sig.explicit_self), unsafety: sig.unsafety, constness: sig.constness, decl: rewritten_fn_decl diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index dbef06f7aa4..5687099b27c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -274,7 +274,10 @@ declare_features! ( (active, drop_types_in_const, "1.9.0", Some(33156)), // Allows cfg(target_has_atomic = "..."). - (active, cfg_target_has_atomic, "1.9.0", Some(32976)) + (active, cfg_target_has_atomic, "1.9.0", Some(32976)), + + // Allows `..` in tuple (struct) patterns + (active, dotdot_in_tuple_patterns, "1.10.0", Some(33627)) ); declare_features! ( @@ -315,7 +318,6 @@ declare_features! ( // Allows `#[deprecated]` attribute (accepted, deprecated, "1.9.0", Some(29935)) ); - // (changing above list without updating src/doc/reference.md makes @cmr sad) #[derive(PartialEq, Copy, Clone, Debug)] @@ -1024,6 +1026,24 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { pattern.span, "box pattern syntax is experimental"); } + PatKind::Tuple(_, ddpos) + if ddpos.is_some() => { + gate_feature_post!(&self, dotdot_in_tuple_patterns, + pattern.span, + "`..` in tuple patterns is experimental"); + } + PatKind::TupleStruct(_, ref fields, ddpos) + if ddpos.is_some() && !fields.is_empty() => { + gate_feature_post!(&self, dotdot_in_tuple_patterns, + pattern.span, + "`..` in tuple struct patterns is experimental"); + } + PatKind::TupleStruct(_, ref fields, ddpos) + if ddpos.is_none() && fields.is_empty() => { + self.context.span_handler.struct_span_err(pattern.span, + "nullary enum variants are written with \ + no trailing `( )`").emit(); + } _ => {} } visit::walk_pat(self, pattern) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2c325080c0c..edf418e3332 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -179,14 +179,6 @@ pub trait Folder : Sized { // fold::noop_fold_mac(_mac, self) } - fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf { - noop_fold_explicit_self(es, self) - } - - fn fold_explicit_self_kind(&mut self, es: SelfKind) -> SelfKind { - noop_fold_explicit_self_kind(es, self) - } - fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime { noop_fold_lifetime(l, self) } @@ -383,7 +375,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { t.map(|Ty {id, node, span}| Ty { id: fld.new_id(id), node: match node { - TyKind::Infer => node, + TyKind::Infer | TyKind::ImplicitSelf => node, TyKind::Vec(ty) => TyKind::Vec(fld.fold_ty(ty)), TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)), TyKind::Rptr(region, mt) => { @@ -523,28 +515,6 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attr }) } -pub fn noop_fold_explicit_self_kind<T: Folder>(es: SelfKind, fld: &mut T) - -> SelfKind { - match es { - SelfKind::Static | SelfKind::Value(_) => es, - SelfKind::Region(lifetime, m, ident) => { - SelfKind::Region(fld.fold_opt_lifetime(lifetime), m, ident) - } - SelfKind::Explicit(typ, ident) => { - SelfKind::Explicit(fld.fold_ty(typ), ident) - } - } -} - -pub fn noop_fold_explicit_self<T: Folder>(Spanned {span, node}: ExplicitSelf, fld: &mut T) - -> ExplicitSelf { - Spanned { - node: fld.fold_explicit_self_kind(node), - span: fld.new_span(span) - } -} - - pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac { Spanned { node: Mac_ { @@ -1096,7 +1066,6 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method MethodSig { generics: folder.fold_generics(sig.generics), abi: sig.abi, - explicit_self: folder.fold_explicit_self(sig.explicit_self), unsafety: sig.unsafety, constness: sig.constness, decl: folder.fold_fn_decl(sig.decl) @@ -1115,9 +1084,9 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> { sub.map(|x| folder.fold_pat(x))) } PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), - PatKind::TupleStruct(pth, pats) => { + PatKind::TupleStruct(pth, pats, ddpos) => { PatKind::TupleStruct(folder.fold_path(pth), - pats.map(|pats| pats.move_map(|x| folder.fold_pat(x)))) + pats.move_map(|x| folder.fold_pat(x)), ddpos) } PatKind::Path(pth) => { PatKind::Path(folder.fold_path(pth)) @@ -1138,7 +1107,9 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> { }); PatKind::Struct(pth, fs, etc) } - PatKind::Tup(elts) => PatKind::Tup(elts.move_map(|x| folder.fold_pat(x))), + PatKind::Tuple(elts, ddpos) => { + PatKind::Tuple(elts.move_map(|x| folder.fold_pat(x)), ddpos) + } PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)), PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl), PatKind::Range(e1, e2) => { @@ -1212,23 +1183,27 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu ExprKind::While(cond, body, opt_ident) => { ExprKind::While(folder.fold_expr(cond), folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) + opt_ident.map(|label| respan(folder.new_span(label.span), + folder.fold_ident(label.node)))) } ExprKind::WhileLet(pat, expr, body, opt_ident) => { ExprKind::WhileLet(folder.fold_pat(pat), folder.fold_expr(expr), folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) + opt_ident.map(|label| respan(folder.new_span(label.span), + folder.fold_ident(label.node)))) } ExprKind::ForLoop(pat, iter, body, opt_ident) => { ExprKind::ForLoop(folder.fold_pat(pat), folder.fold_expr(iter), folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) + opt_ident.map(|label| respan(folder.new_span(label.span), + folder.fold_ident(label.node)))) } ExprKind::Loop(body, opt_ident) => { ExprKind::Loop(folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) + opt_ident.map(|label| respan(folder.new_span(label.span), + folder.fold_ident(label.node)))) } ExprKind::Match(expr, arms) => { ExprKind::Match(folder.fold_expr(expr), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fc62cee92fd..de74cdc8fb3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -17,7 +17,7 @@ use ast::Block; use ast::{BlockCheckMode, CaptureBy}; use ast::{Constness, Crate, CrateConfig}; use ast::{Decl, DeclKind, Defaultness}; -use ast::{EMPTY_CTXT, EnumDef, ExplicitSelf}; +use ast::{EMPTY_CTXT, EnumDef}; use ast::{Expr, ExprKind, RangeLimits}; use ast::{Field, FnDecl}; use ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; @@ -954,25 +954,6 @@ impl<'a> Parser<'a> { Ok(result) } - /// Parse a sequence parameter of enum variant. For consistency purposes, - /// these should not be empty. - pub fn parse_enum_variant_seq<T, F>(&mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: F) - -> PResult<'a, Vec<T>> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, - { - let result = self.parse_unspanned_seq(bra, ket, sep, f)?; - if result.is_empty() { - let last_span = self.last_span; - self.span_err(last_span, - "nullary enum variants are written with no trailing `( )`"); - } - Ok(result) - } - // NB: Do not use this function unless you actually plan to place the // spanned list in the AST. pub fn parse_seq<T, F>(&mut self, @@ -1310,7 +1291,7 @@ impl<'a> Parser<'a> { let ident = p.parse_ident()?; let mut generics = p.parse_generics()?; - let (explicit_self, d) = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{ + let d = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{ // This is somewhat dubious; We don't want to allow // argument names to be left off if there is a // definition... @@ -1324,7 +1305,6 @@ impl<'a> Parser<'a> { decl: d, generics: generics, abi: abi, - explicit_self: explicit_self, }; let body = match p.token { @@ -2283,18 +2263,19 @@ impl<'a> Parser<'a> { return self.parse_while_expr(None, lo, attrs); } if self.token.is_lifetime() { - let lifetime = self.get_lifetime(); + let label = Spanned { node: self.get_lifetime(), + span: self.span }; let lo = self.span.lo; self.bump(); self.expect(&token::Colon)?; if self.eat_keyword(keywords::While) { - return self.parse_while_expr(Some(lifetime), lo, attrs) + return self.parse_while_expr(Some(label), lo, attrs) } if self.eat_keyword(keywords::For) { - return self.parse_for_expr(Some(lifetime), lo, attrs) + return self.parse_for_expr(Some(label), lo, attrs) } if self.eat_keyword(keywords::Loop) { - return self.parse_loop_expr(Some(lifetime), lo, attrs) + return self.parse_loop_expr(Some(label), lo, attrs) } return Err(self.fatal("expected `while`, `for`, or `loop` after a label")) } @@ -3264,7 +3245,7 @@ impl<'a> Parser<'a> { } /// Parse a 'for' .. 'in' expression ('for' token already eaten) - pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>, + pub fn parse_for_expr(&mut self, opt_ident: Option<ast::SpannedIdent>, span_lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { // Parse: `for <src_pat> in <src_expr> <src_loop_block>` @@ -3283,7 +3264,7 @@ impl<'a> Parser<'a> { } /// Parse a 'while' or 'while let' expression ('while' token already eaten) - pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>, + pub fn parse_while_expr(&mut self, opt_ident: Option<ast::SpannedIdent>, span_lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { if self.token.is_keyword(keywords::Let) { @@ -3298,7 +3279,7 @@ impl<'a> Parser<'a> { } /// Parse a 'while let' expression ('while' token already eaten) - pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>, + pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::SpannedIdent>, span_lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { self.expect_keyword(keywords::Let)?; @@ -3312,7 +3293,7 @@ impl<'a> Parser<'a> { } // parse `loop {...}`, `loop` token already eaten - pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>, + pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::SpannedIdent>, span_lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { let (iattrs, body) = self.parse_inner_attrs_and_block()?; @@ -3433,21 +3414,33 @@ impl<'a> Parser<'a> { }; } - fn parse_pat_tuple_elements(&mut self) -> PResult<'a, Vec<P<Pat>>> { + fn parse_pat_tuple_elements(&mut self, unary_needs_comma: bool) + -> PResult<'a, (Vec<P<Pat>>, Option<usize>)> { let mut fields = vec![]; - if !self.check(&token::CloseDelim(token::Paren)) { - fields.push(self.parse_pat()?); - if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) { - while self.eat(&token::Comma) && - !self.check(&token::CloseDelim(token::Paren)) { + let mut ddpos = None; + + while !self.check(&token::CloseDelim(token::Paren)) { + if ddpos.is_none() && self.eat(&token::DotDot) { + ddpos = Some(fields.len()); + if self.eat(&token::Comma) { + // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed. fields.push(self.parse_pat()?); } + } else if ddpos.is_some() && self.eat(&token::DotDot) { + // Emit a friendly error, ignore `..` and continue parsing + self.span_err(self.last_span, "`..` can only be used once per \ + tuple or tuple struct pattern"); + } else { + fields.push(self.parse_pat()?); } - if fields.len() == 1 { + + if !self.check(&token::CloseDelim(token::Paren)) || + (unary_needs_comma && fields.len() == 1 && ddpos.is_none()) { self.expect(&token::Comma)?; } } - Ok(fields) + + Ok((fields, ddpos)) } fn parse_pat_vec_elements( @@ -3626,9 +3619,9 @@ impl<'a> Parser<'a> { token::OpenDelim(token::Paren) => { // Parse (pat,pat,pat,...) as tuple pattern self.bump(); - let fields = self.parse_pat_tuple_elements()?; + let (fields, ddpos) = self.parse_pat_tuple_elements(true)?; self.expect(&token::CloseDelim(token::Paren))?; - pat = PatKind::Tup(fields); + pat = PatKind::Tuple(fields, ddpos); } token::OpenDelim(token::Bracket) => { // Parse [pat,pat,...] as slice pattern @@ -3713,20 +3706,10 @@ impl<'a> Parser<'a> { return Err(self.fatal("unexpected `(` after qualified path")); } // Parse tuple struct or enum pattern - if self.look_ahead(1, |t| *t == token::DotDot) { - // This is a "top constructor only" pat - self.bump(); - self.bump(); - self.expect(&token::CloseDelim(token::Paren))?; - pat = PatKind::TupleStruct(path, None); - } else { - let args = self.parse_enum_variant_seq( - &token::OpenDelim(token::Paren), - &token::CloseDelim(token::Paren), - SeqSep::trailing_allowed(token::Comma), - |p| p.parse_pat())?; - pat = PatKind::TupleStruct(path, Some(args)); - } + self.bump(); + let (fields, ddpos) = self.parse_pat_tuple_elements(false)?; + self.expect(&token::CloseDelim(token::Paren))?; + pat = PatKind::TupleStruct(path, fields, ddpos) } _ => { pat = match qself { @@ -4616,25 +4599,19 @@ impl<'a> Parser<'a> { })) } - /// Parse the parameter list and result type of a function that may have a `self` parameter. - fn parse_fn_decl_with_self<F>(&mut self, - parse_arg_fn: F) - -> PResult<'a, (ExplicitSelf, P<FnDecl>)> - where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>, - { + /// Returns the parsed optional self argument and whether a self shortcut was used. + fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> { let expect_ident = |this: &mut Self| match this.token { - token::Ident(ident) => { this.bump(); ident } // Preserve hygienic context. + // Preserve hygienic context. + token::Ident(ident) => { this.bump(); codemap::respan(this.last_span, ident) } _ => unreachable!() }; - self.expect(&token::OpenDelim(token::Paren))?; - // Parse optional self parameter of a method. // Only a limited set of initial token sequences is considered self parameters, anything // else is parsed as a normal function parameter list, so some lookahead is required. let eself_lo = self.span.lo; - let mut eself_mutbl = Mutability::Immutable; - let (eself, eself_ident_sp) = match self.token { + let (eself, eself_ident) = match self.token { token::BinOp(token::And) => { // &self // &mut self @@ -4643,30 +4620,26 @@ impl<'a> Parser<'a> { // ¬_self if self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); - (SelfKind::Region(None, Mutability::Immutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(None, Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) && self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); self.bump(); - (SelfKind::Region(None, Mutability::Mutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(None, Mutability::Mutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_lifetime()) && self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); let lt = self.parse_lifetime()?; - (SelfKind::Region(Some(lt), Mutability::Immutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(Some(lt), Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_lifetime()) && self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) && self.look_ahead(3, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); let lt = self.parse_lifetime()?; self.bump(); - (SelfKind::Region(Some(lt), Mutability::Mutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self)) } else { - (SelfKind::Static, codemap::DUMMY_SP) + return Ok(None); } } token::BinOp(token::Star) => { @@ -4678,15 +4651,15 @@ impl<'a> Parser<'a> { if self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); self.span_err(self.span, "cannot pass `self` by raw pointer"); - (SelfKind::Value(expect_ident(self)), self.last_span) + (SelfKind::Value(Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_mutability()) && self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); self.bump(); self.span_err(self.span, "cannot pass `self` by raw pointer"); - (SelfKind::Value(expect_ident(self)), self.last_span) + (SelfKind::Value(Mutability::Immutable), expect_ident(self)) } else { - (SelfKind::Static, codemap::DUMMY_SP) + return Ok(None); } } token::Ident(..) => { @@ -4694,64 +4667,69 @@ impl<'a> Parser<'a> { // self // self: TYPE let eself_ident = expect_ident(self); - let eself_ident_sp = self.last_span; if self.eat(&token::Colon) { - (SelfKind::Explicit(self.parse_ty_sum()?, eself_ident), eself_ident_sp) + let ty = self.parse_ty_sum()?; + (SelfKind::Explicit(ty, Mutability::Immutable), eself_ident) } else { - (SelfKind::Value(eself_ident), eself_ident_sp) + (SelfKind::Value(Mutability::Immutable), eself_ident) } } else if self.token.is_keyword(keywords::Mut) && self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { // mut self // mut self: TYPE - eself_mutbl = Mutability::Mutable; self.bump(); let eself_ident = expect_ident(self); - let eself_ident_sp = self.last_span; if self.eat(&token::Colon) { - (SelfKind::Explicit(self.parse_ty_sum()?, eself_ident), eself_ident_sp) + let ty = self.parse_ty_sum()?; + (SelfKind::Explicit(ty, Mutability::Mutable), eself_ident) } else { - (SelfKind::Value(eself_ident), eself_ident_sp) + (SelfKind::Value(Mutability::Mutable), eself_ident) } } else { - (SelfKind::Static, codemap::DUMMY_SP) + return Ok(None); } } - _ => (SelfKind::Static, codemap::DUMMY_SP) + _ => return Ok(None), }; - let mut eself = codemap::respan(mk_sp(eself_lo, self.last_span.hi), eself); + + let eself = codemap::respan(mk_sp(eself_lo, self.last_span.hi), eself); + Ok(Some(Arg::from_self(eself, eself_ident))) + } + + /// Parse the parameter list and result type of a function that may have a `self` parameter. + fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> PResult<'a, P<FnDecl>> + where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>, + { + self.expect(&token::OpenDelim(token::Paren))?; + + // Parse optional self argument + let self_arg = self.parse_self_arg()?; // Parse the rest of the function parameter list. let sep = SeqSep::trailing_allowed(token::Comma); - let fn_inputs = match eself.node { - SelfKind::Static => { - eself.span = codemap::DUMMY_SP; - self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn) - } - SelfKind::Value(..) | SelfKind::Region(..) | SelfKind::Explicit(..) => { - if self.check(&token::CloseDelim(token::Paren)) { - vec![Arg::from_self(eself.clone(), eself_ident_sp, eself_mutbl)] - } else if self.check(&token::Comma) { - self.bump(); - let mut fn_inputs = vec![Arg::from_self(eself.clone(), eself_ident_sp, - eself_mutbl)]; - fn_inputs.append(&mut self.parse_seq_to_before_end( - &token::CloseDelim(token::Paren), sep, parse_arg_fn) - ); - fn_inputs - } else { - return self.unexpected(); - } + let fn_inputs = if let Some(self_arg) = self_arg { + if self.check(&token::CloseDelim(token::Paren)) { + vec![self_arg] + } else if self.eat(&token::Comma) { + let mut fn_inputs = vec![self_arg]; + fn_inputs.append(&mut self.parse_seq_to_before_end( + &token::CloseDelim(token::Paren), sep, parse_arg_fn) + ); + fn_inputs + } else { + return self.unexpected(); } + } else { + self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn) }; // Parse closing paren and return type. self.expect(&token::CloseDelim(token::Paren))?; - Ok((eself, P(FnDecl { + Ok(P(FnDecl { inputs: fn_inputs, output: self.parse_ret_ty()?, variadic: false - }))) + })) } // parse the |arg, arg| header on a lambda @@ -4944,15 +4922,12 @@ impl<'a> Parser<'a> { let (constness, unsafety, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| { - p.parse_arg() - })?; + let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?; generics.where_clause = self.parse_where_clause()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig { generics: generics, abi: abi, - explicit_self: explicit_self, unsafety: unsafety, constness: constness, decl: decl diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ebb4927d69c..5b9ec924de9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -12,7 +12,7 @@ pub use self::AnnNode::*; use abi::{self, Abi}; use ast::{self, TokenTree, BlockCheckMode, PatKind}; -use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; +use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::Attribute; use attr::ThinAttributesExt; use util::parser::AssocOp; @@ -382,13 +382,12 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, constness: ast::Constness, name: ast::Ident, - opt_explicit_self: Option<&ast::SelfKind>, generics: &ast::Generics) -> String { to_string(|s| { s.head("")?; s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name), - generics, opt_explicit_self, &ast::Visibility::Inherited)?; + generics, &ast::Visibility::Inherited)?; s.end()?; // Close the head box s.end() // Close the outer box }) @@ -416,10 +415,6 @@ pub fn lit_to_string(l: &ast::Lit) -> String { to_string(|s| s.print_literal(l)) } -pub fn explicit_self_to_string(explicit_self: &ast::SelfKind) -> String { - to_string(|s| s.print_explicit_self(explicit_self, ast::Mutability::Immutable).map(|_| {})) -} - pub fn variant_to_string(var: &ast::Variant) -> String { to_string(|s| s.print_variant(var)) } @@ -1005,8 +1000,7 @@ impl<'a> State<'a> { f.unsafety, &f.decl, None, - &generics, - None)?; + &generics)?; } ast::TyKind::Path(None, ref path) => { self.print_path(path, false, 0)?; @@ -1036,6 +1030,9 @@ impl<'a> State<'a> { ast::TyKind::Infer => { word(&mut self.s, "_")?; } + ast::TyKind::ImplicitSelf => { + unreachable!(); + } ast::TyKind::Mac(ref m) => { self.print_mac(m, token::Paren)?; } @@ -1054,7 +1051,7 @@ impl<'a> State<'a> { self.print_fn(decl, ast::Unsafety::Normal, ast::Constness::NotConst, Abi::Rust, Some(item.ident), - generics, None, &item.vis)?; + generics, &item.vis)?; self.end()?; // end head-ibox word(&mut self.s, ";")?; self.end() // end the outer fn box @@ -1182,7 +1179,6 @@ impl<'a> State<'a> { abi, Some(item.ident), typarams, - None, &item.vis )?; word(&mut self.s, " ")?; @@ -1522,7 +1518,6 @@ impl<'a> State<'a> { m.abi, Some(ident), &m.generics, - None, vis) } @@ -2021,7 +2016,7 @@ impl<'a> State<'a> { } ast::ExprKind::While(ref test, ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident)?; + self.print_ident(ident.node)?; self.word_space(":")?; } self.head("while")?; @@ -2031,7 +2026,7 @@ impl<'a> State<'a> { } ast::ExprKind::WhileLet(ref pat, ref expr, ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident)?; + self.print_ident(ident.node)?; self.word_space(":")?; } self.head("while let")?; @@ -2044,7 +2039,7 @@ impl<'a> State<'a> { } ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident)?; + self.print_ident(ident.node)?; self.word_space(":")?; } self.head("for")?; @@ -2057,7 +2052,7 @@ impl<'a> State<'a> { } ast::ExprKind::Loop(ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident)?; + self.print_ident(ident.node)?; self.word_space(":")?; } self.head("loop")?; @@ -2472,17 +2467,23 @@ impl<'a> State<'a> { None => () } } - PatKind::TupleStruct(ref path, ref args_) => { + PatKind::TupleStruct(ref path, ref elts, ddpos) => { self.print_path(path, true, 0)?; - match *args_ { - None => word(&mut self.s, "(..)")?, - Some(ref args) => { - self.popen()?; - self.commasep(Inconsistent, &args[..], - |s, p| s.print_pat(&p))?; - self.pclose()?; + self.popen()?; + if let Some(ddpos) = ddpos { + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + if ddpos != 0 { + self.word_space(",")?; + } + word(&mut self.s, "..")?; + if ddpos != elts.len() { + word(&mut self.s, ",")?; + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; } + } else { + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; } + self.pclose()?; } PatKind::Path(ref path) => { self.print_path(path, true, 0)?; @@ -2513,13 +2514,23 @@ impl<'a> State<'a> { space(&mut self.s)?; word(&mut self.s, "}")?; } - PatKind::Tup(ref elts) => { + PatKind::Tuple(ref elts, ddpos) => { self.popen()?; - self.commasep(Inconsistent, - &elts[..], - |s, p| s.print_pat(&p))?; - if elts.len() == 1 { - word(&mut self.s, ",")?; + if let Some(ddpos) = ddpos { + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + if ddpos != 0 { + self.word_space(",")?; + } + word(&mut self.s, "..")?; + if ddpos != elts.len() { + word(&mut self.s, ",")?; + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + } + } else { + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + if elts.len() == 1 { + word(&mut self.s, ",")?; + } } self.pclose()?; } @@ -2610,29 +2621,25 @@ impl<'a> State<'a> { self.end() // close enclosing cbox } - // Returns whether it printed anything - fn print_explicit_self(&mut self, - explicit_self: &ast::SelfKind, - mutbl: ast::Mutability) -> io::Result<bool> { - self.print_mutability(mutbl)?; - match *explicit_self { - ast::SelfKind::Static => { return Ok(false); } - ast::SelfKind::Value(_) => { - word(&mut self.s, "self")?; + fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Result<()> { + match explicit_self.node { + SelfKind::Value(m) => { + self.print_mutability(m)?; + word(&mut self.s, "self") } - ast::SelfKind::Region(ref lt, m, _) => { + SelfKind::Region(ref lt, m) => { word(&mut self.s, "&")?; self.print_opt_lifetime(lt)?; self.print_mutability(m)?; - word(&mut self.s, "self")?; + word(&mut self.s, "self") } - ast::SelfKind::Explicit(ref typ, _) => { + SelfKind::Explicit(ref typ, m) => { + self.print_mutability(m)?; word(&mut self.s, "self")?; self.word_space(":")?; - self.print_type(&typ)?; + self.print_type(&typ) } } - return Ok(true); } pub fn print_fn(&mut self, @@ -2642,7 +2649,6 @@ impl<'a> State<'a> { abi: abi::Abi, name: Option<ast::Ident>, generics: &ast::Generics, - opt_explicit_self: Option<&ast::SelfKind>, vis: &ast::Visibility) -> io::Result<()> { self.print_fn_header_info(unsafety, constness, abi, vis)?; @@ -2651,21 +2657,14 @@ impl<'a> State<'a> { self.print_ident(name)?; } self.print_generics(generics)?; - self.print_fn_args_and_ret(decl, opt_explicit_self)?; + self.print_fn_args_and_ret(decl)?; self.print_where_clause(&generics.where_clause) } - pub fn print_fn_args(&mut self, decl: &ast::FnDecl, - _: Option<&ast::SelfKind>, - is_closure: bool) -> io::Result<()> { - self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, is_closure)) - } - - pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl, - opt_explicit_self: Option<&ast::SelfKind>) + pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl) -> io::Result<()> { self.popen()?; - self.print_fn_args(decl, opt_explicit_self, false)?; + self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?; if decl.variadic { word(&mut self.s, ", ...")?; } @@ -2679,7 +2678,7 @@ impl<'a> State<'a> { decl: &ast::FnDecl) -> io::Result<()> { word(&mut self.s, "|")?; - self.print_fn_args(decl, None, true)?; + self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?; word(&mut self.s, "|")?; if let ast::FunctionRetTy::Default(..) = decl.output { @@ -2929,17 +2928,14 @@ impl<'a> State<'a> { match input.ty.node { ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?, _ => { - let (mutbl, invalid) = match input.pat.node { - PatKind::Ident(ast::BindingMode::ByValue(mutbl), ident, _) | - PatKind::Ident(ast::BindingMode::ByRef(mutbl), ident, _) => { - (mutbl, ident.node.name == keywords::Invalid.name()) - } - _ => (ast::Mutability::Immutable, false) - }; - if let Some(eself) = input.to_self() { - self.print_explicit_self(&eself.node, mutbl)?; + self.print_explicit_self(&eself)?; } else { + let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node { + ident.node.name == keywords::Invalid.name() + } else { + false + }; if !invalid { self.print_pat(&input.pat)?; word(&mut self.s, ":")?; @@ -2980,8 +2976,7 @@ impl<'a> State<'a> { unsafety: ast::Unsafety, decl: &ast::FnDecl, name: Option<ast::Ident>, - generics: &ast::Generics, - opt_explicit_self: Option<&ast::SelfKind>) + generics: &ast::Generics) -> io::Result<()> { self.ibox(INDENT_UNIT)?; if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { @@ -3002,7 +2997,6 @@ impl<'a> State<'a> { abi, name, &generics, - opt_explicit_self, &ast::Visibility::Inherited)?; self.end() } @@ -3126,8 +3120,7 @@ mod tests { let generics = ast::Generics::default(); assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal, ast::Constness::NotConst, - abba_ident, - None, &generics), + abba_ident, &generics), "fn abba()"); } diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs index e692ec4452c..919dd84b117 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/libsyntax/util/node_count.rs @@ -129,10 +129,6 @@ impl<'v> Visitor<'v> for NodeCounter { self.count += 1; walk_lifetime_def(self, lifetime) } - fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) { - self.count += 1; - walk_explicit_self(self, es) - } fn visit_mac(&mut self, _mac: &'v Mac) { self.count += 1; walk_mac(self, _mac) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index f50a480e5e5..8a02e549d4c 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -26,7 +26,7 @@ use abi::Abi; use ast::*; use attr::ThinAttributesExt; -use codemap::Span; +use codemap::{Span, Spanned}; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { @@ -99,9 +99,6 @@ pub trait Visitor<'v> : Sized { fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) { walk_lifetime_def(self, lifetime) } - fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) { - walk_explicit_self(self, es) - } fn visit_mac(&mut self, _mac: &'v Mac) { panic!("visit_mac disabled by default"); // NB: see note about macros above. @@ -149,17 +146,24 @@ macro_rules! walk_list { } pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) { - for name in opt_name { + if let Some(name) = opt_name { visitor.visit_name(span, name); } } pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option<Ident>) { - for ident in opt_ident { + if let Some(ident) = opt_ident { visitor.visit_ident(span, ident); } } +pub fn walk_opt_sp_ident<'v, V: Visitor<'v>>(visitor: &mut V, + opt_sp_ident: &Option<Spanned<Ident>>) { + if let Some(ref sp_ident) = *opt_sp_ident { + visitor.visit_ident(sp_ident.span, sp_ident.node); + } +} + pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) { visitor.visit_name(span, ident.name); } @@ -196,24 +200,6 @@ pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, walk_list!(visitor, visit_lifetime, &lifetime_def.bounds); } -pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, - explicit_self: &'v ExplicitSelf) { - match explicit_self.node { - SelfKind::Static => {}, - SelfKind::Value(ident) => { - visitor.visit_ident(explicit_self.span, ident) - } - SelfKind::Region(ref opt_lifetime, _, ident) => { - visitor.visit_ident(explicit_self.span, ident); - walk_list!(visitor, visit_lifetime, opt_lifetime); - } - SelfKind::Explicit(ref typ, ident) => { - visitor.visit_ident(explicit_self.span, ident); - visitor.visit_ty(typ) - } - } -} - pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v PolyTraitRef, _modifier: &'v TraitBoundModifier) @@ -369,7 +355,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyKind::Typeof(ref expression) => { visitor.visit_expr(expression) } - TyKind::Infer => {} + TyKind::Infer | TyKind::ImplicitSelf => {} TyKind::Mac(ref mac) => { visitor.visit_mac(mac) } @@ -423,11 +409,9 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { match pattern.node { - PatKind::TupleStruct(ref path, ref opt_children) => { + PatKind::TupleStruct(ref path, ref children, _) => { visitor.visit_path(path, pattern.id); - if let Some(ref children) = *opt_children { - walk_list!(visitor, visit_pat, children); - } + walk_list!(visitor, visit_pat, children); } PatKind::Path(ref path) => { visitor.visit_path(path, pattern.id); @@ -443,7 +427,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { visitor.visit_pat(&field.node.pat) } } - PatKind::Tup(ref tuple_elements) => { + PatKind::Tuple(ref tuple_elements, _) => { walk_list!(visitor, visit_pat, tuple_elements); } PatKind::Box(ref subpattern) | @@ -553,7 +537,6 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, } FnKind::Method(_, ref sig, _) => { visitor.visit_generics(&sig.generics); - visitor.visit_explicit_self(&sig.explicit_self); } FnKind::Closure => {} } @@ -578,7 +561,6 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai walk_list!(visitor, visit_expr, default); } TraitItemKind::Method(ref sig, None) => { - visitor.visit_explicit_self(&sig.explicit_self); visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, &sig.decl); } @@ -712,10 +694,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_block(if_block); walk_list!(visitor, visit_expr, optional_else); } - ExprKind::While(ref subexpression, ref block, opt_ident) => { + ExprKind::While(ref subexpression, ref block, ref opt_sp_ident) => { visitor.visit_expr(subexpression); visitor.visit_block(block); - walk_opt_ident(visitor, expression.span, opt_ident) + walk_opt_sp_ident(visitor, opt_sp_ident); } ExprKind::IfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => { visitor.visit_pat(pattern); @@ -723,21 +705,21 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_block(if_block); walk_list!(visitor, visit_expr, optional_else); } - ExprKind::WhileLet(ref pattern, ref subexpression, ref block, opt_ident) => { + ExprKind::WhileLet(ref pattern, ref subexpression, ref block, ref opt_sp_ident) => { visitor.visit_pat(pattern); visitor.visit_expr(subexpression); visitor.visit_block(block); - walk_opt_ident(visitor, expression.span, opt_ident) + walk_opt_sp_ident(visitor, opt_sp_ident); } - ExprKind::ForLoop(ref pattern, ref subexpression, ref block, opt_ident) => { + ExprKind::ForLoop(ref pattern, ref subexpression, ref block, ref opt_sp_ident) => { visitor.visit_pat(pattern); visitor.visit_expr(subexpression); visitor.visit_block(block); - walk_opt_ident(visitor, expression.span, opt_ident) + walk_opt_sp_ident(visitor, opt_sp_ident); } - ExprKind::Loop(ref block, opt_ident) => { + ExprKind::Loop(ref block, ref opt_sp_ident) => { visitor.visit_block(block); - walk_opt_ident(visitor, expression.span, opt_ident) + walk_opt_sp_ident(visitor, opt_sp_ident); } ExprKind::Match(ref subexpression, ref arms) => { visitor.visit_expr(subexpression); @@ -781,9 +763,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_path(path, expression.id) } ExprKind::Break(ref opt_sp_ident) | ExprKind::Again(ref opt_sp_ident) => { - for sp_ident in opt_sp_ident { - visitor.visit_ident(sp_ident.span, sp_ident.node); - } + walk_opt_sp_ident(visitor, opt_sp_ident); } ExprKind::Ret(ref optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); |
