From 04311341197ddabc420a8cffc0d26c12228d445b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 3 Feb 2015 11:34:05 -0500 Subject: Remove the explicit closure kind syntax from the parser and AST; upgrade the inference based on expected type so that it is able to infer the fn kind in isolation even if the full signature is not available (and we could perhaps do better still in some cases, such as extracting just the types of the arguments but not the return value). --- src/libsyntax/ast.rs | 10 +------ src/libsyntax/ast_map/blocks.rs | 2 +- src/libsyntax/ext/build.rs | 4 +-- src/libsyntax/ext/expand.rs | 3 +- src/libsyntax/fold.rs | 3 +- src/libsyntax/parse/obsolete.rs | 5 ++++ src/libsyntax/parse/parser.rs | 62 ++++++++++++++++++++++------------------- src/libsyntax/print/pprust.rs | 19 ++++--------- src/libsyntax/visit.rs | 2 +- 9 files changed, 50 insertions(+), 60 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d7283db25a5..34eeedeaa76 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -48,7 +48,6 @@ pub use self::TraitItem::*; pub use self::Ty_::*; pub use self::TyParamBound::*; pub use self::UintTy::*; -pub use self::ClosureKind::*; pub use self::UnOp::*; pub use self::UnsafeSource::*; pub use self::VariantKind::*; @@ -736,7 +735,7 @@ pub enum Expr_ { // FIXME #6993: change to Option ... or not, if these are hygienic. ExprLoop(P, Option), ExprMatch(P, Vec, MatchSource), - ExprClosure(CaptureClause, Option, P, P), + ExprClosure(CaptureClause, P, P), ExprBlock(P), ExprAssign(P, P), @@ -1687,13 +1686,6 @@ impl ForeignItem_ { } } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum ClosureKind { - FnClosureKind, - FnMutClosureKind, - FnOnceClosureKind, -} - /// The data we save and restore about an inlined item or method. This is not /// part of the AST that we parse from a file, but it becomes part of the tree /// that we trans. diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 53787d71eef..a85b87f47d6 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -218,7 +218,7 @@ impl<'a> FnLikeNode<'a> { } } ast_map::NodeExpr(e) => match e.node { - ast::ExprClosure(_, _, ref decl, ref block) => + ast::ExprClosure(_, ref decl, ref block) => closure(ClosureParts::new(&**decl, &**block, e.id, e.span)), _ => panic!("expr FnLikeNode that is not fn-like"), }, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 2b3a7212683..53c35ef34cd 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -876,14 +876,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn lambda_fn_decl(&self, span: Span, fn_decl: P, blk: P) -> P { - self.expr(span, ast::ExprClosure(ast::CaptureByRef, None, fn_decl, blk)) + self.expr(span, ast::ExprClosure(ast::CaptureByRef, fn_decl, blk)) } fn lambda(&self, span: Span, ids: Vec, blk: P) -> P { let fn_decl = self.fn_decl( ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), self.ty_infer(span)); - self.expr(span, ast::ExprClosure(ast::CaptureByRef, None, fn_decl, blk)) + self.expr(span, ast::ExprClosure(ast::CaptureByRef, fn_decl, blk)) } fn lambda0(&self, span: Span, blk: P) -> P { self.lambda(span, Vec::new(), blk) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6eacb344018..77440914342 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -322,11 +322,10 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { fld.cx.expr_match(span, into_iter_expr, vec![iter_arm]) } - ast::ExprClosure(capture_clause, opt_kind, fn_decl, block) => { + ast::ExprClosure(capture_clause, fn_decl, block) => { let (rewritten_fn_decl, rewritten_block) = expand_and_rename_fn_decl_and_block(fn_decl, block, fld); let new_node = ast::ExprClosure(capture_clause, - opt_kind, rewritten_fn_decl, rewritten_block); P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)}) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 9012ec2114d..07b6af651f6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1325,9 +1325,8 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> arms.move_map(|x| folder.fold_arm(x)), source) } - ExprClosure(capture_clause, opt_kind, decl, body) => { + ExprClosure(capture_clause, decl, body) => { ExprClosure(capture_clause, - opt_kind, folder.fold_fn_decl(decl), folder.fold_block(body)) } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index a3600506057..60de6c909b7 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -27,6 +27,7 @@ pub enum ObsoleteSyntax { ProcType, ProcExpr, ClosureType, + ClosureKind, } pub trait ParserObsoleteMethods { @@ -65,6 +66,10 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { "`|usize| -> bool` closure type syntax", "use unboxed closures instead, no type annotation needed" ), + ObsoleteSyntax::ClosureKind => ( + "`:`, `&mut:`, or `&:` syntax", + "rely on inference instead" + ), ObsoleteSyntax::Sized => ( "`Sized? T` syntax for removing the `Sized` bound", "write `T: ?Sized` instead" diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c3182602a4b..385c0a48f87 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -28,8 +28,6 @@ use ast::{ExprLit, ExprLoop, ExprMac, ExprRange}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; -use ast::{FnClosureKind, FnMutClosureKind}; -use ast::{FnOnceClosureKind}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy}; use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic}; use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst}; @@ -57,7 +55,7 @@ use ast::{TyFixedLengthVec, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; -use ast::{TypeImplItem, TypeTraitItem, Typedef, ClosureKind}; +use ast::{TypeImplItem, TypeTraitItem, Typedef,}; use ast::{UnnamedField, UnsafeBlock}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; @@ -1139,29 +1137,36 @@ impl<'a> Parser<'a> { TyInfer } - /// Parses an optional closure kind (`&:`, `&mut:`, or `:`). - pub fn parse_optional_closure_kind(&mut self) -> Option { - if self.check(&token::BinOp(token::And)) && - self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) && - self.look_ahead(2, |t| *t == token::Colon) { + /// Parses an obsolete closure kind (`&:`, `&mut:`, or `:`). + pub fn parse_obsolete_closure_kind(&mut self) { + // let lo = self.span.lo; + if + self.check(&token::BinOp(token::And)) && + self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) && + self.look_ahead(2, |t| *t == token::Colon) + { self.bump(); self.bump(); self.bump(); - return Some(FnMutClosureKind) - } - - if self.token == token::BinOp(token::And) && - self.look_ahead(1, |t| *t == token::Colon) { + } else if + self.token == token::BinOp(token::And) && + self.look_ahead(1, |t| *t == token::Colon) + { self.bump(); self.bump(); - return Some(FnClosureKind) - } - - if self.eat(&token::Colon) { - return Some(FnOnceClosureKind) + return; + } else if + self.eat(&token::Colon) + { + /* nothing */ + } else { + return; } - return None + // SNAP a45e117 + // Enable these obsolete errors after snapshot: + // let span = mk_sp(lo, self.span.hi); + // self.obsolete(span, ObsoleteSyntax::ClosureKind); } pub fn parse_ty_bare_fn_or_ty_closure(&mut self, lifetime_defs: Vec) -> Ty_ { @@ -3047,7 +3052,7 @@ impl<'a> Parser<'a> { -> P { let lo = self.span.lo; - let (decl, optional_closure_kind) = self.parse_fn_block_decl(); + let decl = self.parse_fn_block_decl(); let body = self.parse_expr(); let fakeblock = P(ast::Block { id: ast::DUMMY_NODE_ID, @@ -3060,7 +3065,7 @@ impl<'a> Parser<'a> { self.mk_expr( lo, fakeblock.span.hi, - ExprClosure(capture_clause, optional_closure_kind, decl, fakeblock)) + ExprClosure(capture_clause, decl, fakeblock)) } pub fn parse_else_expr(&mut self) -> P { @@ -4529,30 +4534,29 @@ impl<'a> Parser<'a> { } // parse the |arg, arg| header on a lambda - fn parse_fn_block_decl(&mut self) -> (P, Option) { - let (optional_closure_kind, inputs_captures) = { + fn parse_fn_block_decl(&mut self) -> P { + let inputs_captures = { if self.eat(&token::OrOr) { - (None, Vec::new()) + Vec::new() } else { self.expect(&token::BinOp(token::Or)); - let optional_closure_kind = - self.parse_optional_closure_kind(); + self.parse_obsolete_closure_kind(); let args = self.parse_seq_to_before_end( &token::BinOp(token::Or), seq_sep_trailing_allowed(token::Comma), |p| p.parse_fn_block_arg() ); self.bump(); - (optional_closure_kind, args) + args } }; let output = self.parse_ret_ty(); - (P(FnDecl { + P(FnDecl { inputs: inputs_captures, output: output, variadic: false - }), optional_closure_kind) + }) } /// Parses the `(arg, arg) -> return_type` header on a procedure. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e6d895a49fc..ee8e207fa6c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -11,11 +11,9 @@ pub use self::AnnNode::*; use abi; -use ast::{self, FnClosureKind, FnMutClosureKind}; -use ast::{FnOnceClosureKind}; +use ast; use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; -use ast::{ClosureKind}; use ast_util; use owned_slice::OwnedSlice; use attr::{AttrMetaMethods, AttributeMethods}; @@ -350,7 +348,7 @@ pub fn method_to_string(p: &ast::Method) -> String { } pub fn fn_block_to_string(p: &ast::FnDecl) -> String { - $to_string(|s| s.print_fn_block_args(p, None)) + $to_string(|s| s.print_fn_block_args(p)) } pub fn path_to_string(p: &ast::Path) -> String { @@ -1747,10 +1745,10 @@ impl<'a> State<'a> { } try!(self.bclose_(expr.span, indent_unit)); } - ast::ExprClosure(capture_clause, opt_kind, ref decl, ref body) => { + ast::ExprClosure(capture_clause, ref decl, ref body) => { try!(self.print_capture_clause(capture_clause)); - try!(self.print_fn_block_args(&**decl, opt_kind)); + try!(self.print_fn_block_args(&**decl)); try!(space(&mut self.s)); if !body.stmts.is_empty() || !body.expr.is_some() { @@ -2350,16 +2348,9 @@ impl<'a> State<'a> { pub fn print_fn_block_args( &mut self, - decl: &ast::FnDecl, - closure_kind: Option) + decl: &ast::FnDecl) -> IoResult<()> { try!(word(&mut self.s, "|")); - match closure_kind { - None => {} - Some(FnClosureKind) => try!(self.word_space("&:")), - Some(FnMutClosureKind) => try!(self.word_space("&mut:")), - Some(FnOnceClosureKind) => try!(self.word_space(":")), - } try!(self.print_fn_args(decl, None)); try!(word(&mut self.s, "|")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bd84306fe17..fbcfcaadf12 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -836,7 +836,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_arm(arm) } } - ExprClosure(_, _, ref function_declaration, ref body) => { + ExprClosure(_, ref function_declaration, ref body) => { visitor.visit_fn(FkFnBlock, &**function_declaration, &**body, -- cgit 1.4.1-3-g733a5 From 68ad6949d4c3e2160098c94007b9c48abc94aaad Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 3 Feb 2015 13:14:29 -0500 Subject: Correct one case where the inference was detecting a looser result than the explicit annotation, leading to "extra `mut` declaration" lint errors. --- src/libsyntax/ext/deriving/rand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 9fd5091e194..739c73a70b0 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -66,7 +66,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) cx.ident_of("Rand"), cx.ident_of("rand") ); - let mut rand_call = |&mut: cx: &mut ExtCtxt, span| { + let rand_call = |&: cx: &mut ExtCtxt, span| { cx.expr_call_global(span, rand_ident.clone(), vec!(rng.clone())) -- cgit 1.4.1-3-g733a5 From 8ddcb06b1d021560bfe641c0dbc452a04e80388e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 3 Feb 2015 13:14:36 -0500 Subject: Update for new snapshot after rebasing. --- src/libsyntax/parse/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 385c0a48f87..2cb265033c3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1163,7 +1163,7 @@ impl<'a> Parser<'a> { return; } - // SNAP a45e117 + // SNAP 474b324 // Enable these obsolete errors after snapshot: // let span = mk_sp(lo, self.span.hi); // self.obsolete(span, ObsoleteSyntax::ClosureKind); -- cgit 1.4.1-3-g733a5