language. Recommend `move||` instead.
impl Copy for Closure {}
-/// The representation of a Rust procedure (`proc()`)
-#[repr(C)]
-pub struct Procedure {
- pub code: *mut (),
- pub env: *mut (),
-}
-
-impl Copy for Procedure {}
-
/// The representation of a Rust trait object.
///
/// This struct does not have a `Repr` implementation
ast::ExprMac(..) |
ast::ExprClosure(..) |
- ast::ExprProc(..) |
ast::ExprLit(..) |
ast::ExprPath(..) => {
self.straightline(expr, pred, None::<ast::Expr>.iter())
self.visit_expr(&**e);
self.with_context(Loop, |v| v.visit_block(&**b));
}
- ast::ExprClosure(_, _, _, ref b) |
- ast::ExprProc(_, ref b) => {
+ ast::ExprClosure(_, _, _, ref b) => {
self.with_context(Closure, |v| v.visit_block(&**b));
}
ast::ExprBreak(_) => self.require_loop("break", e.span),
self.consume_expr(&**count);
}
- ast::ExprClosure(..) |
- ast::ExprProc(..) => {
+ ast::ExprClosure(..) => {
self.walk_captures(expr)
}
sub,
"");
}
- infer::ProcCapture(span, id) => {
- self.tcx.sess.span_err(
- span,
- format!("captured variable `{}` must be 'static \
- to be captured in a proc",
- ty::local_var_name_str(self.tcx, id).get())
- .as_slice());
- note_and_explain_region(
- self.tcx,
- "captured variable is only valid for ",
- sup,
- "");
- }
infer::IndexSlice(span) => {
self.tcx.sess.span_err(span,
"index of slice outside its lifetime");
sup,
"");
}
- infer::RelateProcBound(span, var_node_id, ty) => {
- self.tcx.sess.span_err(
- span,
- format!(
- "the type `{}` of captured variable `{}` \
- outlives the `proc()` it \
- is captured in",
- self.ty_to_string(ty),
- ty::local_var_name_str(self.tcx,
- var_node_id)).as_slice());
- note_and_explain_region(
- self.tcx,
- "`proc()` is valid for ",
- sub,
- "");
- note_and_explain_region(
- self.tcx,
- format!("the type `{}` is only valid for ",
- self.ty_to_string(ty)).as_slice(),
- sup,
- "");
- }
infer::RelateParamBound(span, ty) => {
self.tcx.sess.span_err(
span,
self.tcx,
id).get().to_string()).as_slice());
}
- infer::ProcCapture(span, id) => {
- self.tcx.sess.span_note(
- span,
- format!("...so that captured variable `{}` \
- is 'static",
- ty::local_var_name_str(
- self.tcx,
- id).get()).as_slice());
- }
infer::IndexSlice(span) => {
self.tcx.sess.span_note(
span,
span,
"...so that it can be closed over into an object");
}
- infer::RelateProcBound(span, var_node_id, _ty) => {
- self.tcx.sess.span_note(
- span,
- format!(
- "...so that the variable `{}` can be captured \
- into a proc",
- ty::local_var_name_str(self.tcx,
- var_node_id)).as_slice());
- }
infer::CallRcvr(span) => {
self.tcx.sess.span_note(
span,
// Closure bound must not outlive captured free variables
FreeVariable(Span, ast::NodeId),
- // Proc upvars must be 'static
- ProcCapture(Span, ast::NodeId),
-
// Index into slice must be within its lifetime
IndexSlice(Span),
// relating `'a` to `'b`
RelateObjectBound(Span),
- // When closing over a variable in a closure/proc, ensure that the
- // type of the variable outlives the lifetime bound.
- RelateProcBound(Span, ast::NodeId, Ty<'tcx>),
-
// Some type parameter was instantiated with the given type,
// and that type must outlive some region.
RelateParamBound(Span, Ty<'tcx>),
InvokeClosure(a) => a,
DerefPointer(a) => a,
FreeVariable(a, _) => a,
- ProcCapture(a, _) => a,
IndexSlice(a) => a,
RelateObjectBound(a) => a,
- RelateProcBound(a, _, _) => a,
RelateParamBound(a, _) => a,
RelateRegionParamBound(a) => a,
RelateDefaultParamBound(a, _) => a,
FreeVariable(a, b) => {
format!("FreeVariable({}, {})", a.repr(tcx), b)
}
- ProcCapture(a, b) => {
- format!("ProcCapture({}, {})", a.repr(tcx), b)
- }
IndexSlice(a) => {
format!("IndexSlice({})", a.repr(tcx))
}
RelateObjectBound(a) => {
format!("RelateObjectBound({})", a.repr(tcx))
}
- RelateProcBound(a, b, c) => {
- format!("RelateProcBound({},{},{})",
- a.repr(tcx),
- b,
- c.repr(tcx))
- }
RelateParamBound(a, b) => {
format!("RelateParamBound({},{})",
a.repr(tcx),
}
visit::walk_expr(ir, expr);
}
- ast::ExprClosure(..) | ast::ExprProc(..) => {
+ ast::ExprClosure(..) => {
// Interesting control flow (for loops can contain labeled
// breaks or continues)
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
self.propagate_through_expr(&**e, succ)
}
- ast::ExprClosure(_, _, _, ref blk) |
- ast::ExprProc(_, ref blk) => {
- debug!("{} is an ExprClosure or ExprProc",
+ ast::ExprClosure(_, _, _, ref blk) => {
+ debug!("{} is an ExprClosure",
expr_to_string(expr));
/*
ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) |
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
- ast::ExprClosure(..) | ast::ExprProc(..) |
- ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => {
+ ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => {
visit::walk_expr(this, expr);
}
ast::ExprIfLet(..) => {
ast::ExprAddrOf(..) | ast::ExprCall(..) |
ast::ExprAssign(..) | ast::ExprAssignOp(..) |
- ast::ExprClosure(..) | ast::ExprProc(..) |
- ast::ExprRet(..) |
+ ast::ExprClosure(..) | ast::ExprRet(..) |
ast::ExprUnary(..) | ast::ExprSlice(..) |
ast::ExprMethodCall(..) | ast::ExprCast(..) |
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
};
match fn_expr.node {
- ast::ExprProc(_, ref body) |
ast::ExprClosure(_, _, _, ref body) => body.id,
_ => unreachable!()
}
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
-use syntax::ast::{ExprPath, ExprProc, ExprStruct, FnDecl};
+use syntax::ast::{ExprPath, ExprStruct, FnDecl};
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
-use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyProc, TyQPath};
+use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
use syntax::ast::{TypeImplItem, UnnamedField};
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
}
- TyClosure(ref c) | TyProc(ref c) => {
+ TyClosure(ref c) => {
self.resolve_type_parameter_bounds(
ty.id,
&c.bounds,
&**block);
}
- ExprProc(ref fn_decl, ref block) => {
- self.capture_mode_map.insert(expr.id, ast::CaptureByValue);
- self.resolve_function(ClosureRibKind(expr.id, block.id),
- Some(&**fn_decl), NoTypeParameters,
- &**block);
- }
-
ExprStruct(ref path, _, _) => {
// Resolve the path to the structure it goes to. We don't
// check to ensure that the path is actually a structure; that
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
- ast::TyClosure(ref c) | ast::TyProc(ref c) => {
+ ast::TyClosure(ref c) => {
// Careful, the bounds on a closure/proc are *not* within its binder.
visit::walk_ty_param_bounds_helper(self, &c.bounds);
visit::walk_lifetime_decls_helper(self, &c.lifetimes);
_ => { return Ok(()); }
};
- debug!("assemble_unboxed_candidates: self_ty={} obligation={}",
+ debug!("assemble_unboxed_candidates: self_ty={} kind={} obligation={}",
self_ty.repr(self.tcx()),
+ kind,
obligation.repr(self.tcx()));
let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
}
};
+ debug!("closure_kind = {}", closure_kind);
+
if closure_kind == kind {
candidates.vec.push(UnboxedClosureCandidate(closure_def_id, substs.clone()));
}
candidate: &Candidate<'tcx>)
-> EvaluationResult<'tcx>
{
- debug!("winnow_candidate: candidate={}", candidate.repr(self.tcx()));
- self.infcx.probe(|| {
+ /*!
+ * Further evaluate `candidate` to decide whether all type parameters match
+ * and whether nested obligations are met. Returns true if `candidate` remains
+ * viable after this further scrutiny.
+ */
+
+ debug!("winnow_candidate: depth={} candidate={}",
+ stack.obligation.recursion_depth, candidate.repr(self.tcx()));
+ let result = self.infcx.probe(|| {
let candidate = (*candidate).clone();
match self.confirm_candidate(stack.obligation, candidate) {
Ok(selection) => self.winnow_selection(Some(stack), selection),
Err(error) => EvaluatedToErr(error),
}
- })
+ });
+ debug!("winnow_candidate depth={} result={}",
+ stack.obligation.recursion_depth, result);
+ result
}
fn winnow_selection<'o>(&mut self,
substs: substs,
});
+ debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
+ closure_def_id.repr(self.tcx()),
+ trait_ref.repr(self.tcx()));
+
self.confirm(obligation.cause,
obligation.trait_ref.clone(),
trait_ref)
ast::ExprIf(..) |
ast::ExprMatch(..) |
ast::ExprClosure(..) |
- ast::ExprProc(..) |
ast::ExprBlock(..) |
ast::ExprRepeat(..) |
ast::ExprVec(..) => {
let unboxed_closures = cx.unboxed_closures.borrow();
unboxed_closures.get(did).map(|cl| {
closure_to_string(cx, &cl.closure_type.subst(cx, substs))
- }).unwrap_or_else(|| "closure".to_string())
+ }).unwrap_or_else(|| {
+ if did.krate == ast::LOCAL_CRATE {
+ let span = cx.map.span(did.node);
+ format!("closure[{}]", span.repr(cx))
+ } else {
+ format!("closure")
+ }
+ })
}
ty_vec(t, sz) => {
let inner_str = ty_to_string(cx, t);
SawExprWhile,
SawExprMatch,
SawExprClosure,
- SawExprProc,
SawExprBlock,
SawExprAssign,
SawExprAssignOp(ast::BinOp),
ExprLoop(_, id) => SawExprLoop(id.map(content)),
ExprMatch(..) => SawExprMatch,
ExprClosure(..) => SawExprClosure,
- ExprProc(..) => SawExprProc,
ExprBlock(..) => SawExprBlock,
ExprAssign(..) => SawExprAssign,
ExprAssignOp(op, _, _) => SawExprAssignOp(op),
tcx: &ty::ctxt) -> ast::NodeId {
match tcx.map.get(closure_id) {
ast_map::NodeExpr(expr) => match expr.node {
- ast::ExprProc(_, ref block) |
ast::ExprClosure(_, _, _, ref block) => {
block.id
}
}
Some(ast_map::NodeExpr(e)) => {
match e.node {
- ast::ExprClosure(_, _, _, ref blk) |
- ast::ExprProc(_, ref blk) => {
+ ast::ExprClosure(_, _, _, ref blk) => {
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_expr(&mut explicit, e);
}
ast_map::NodeExpr(ref expr) => {
match expr.node {
- ast::ExprProc(ref fn_decl, ref top_level_block) |
ast::ExprClosure(_, _, ref fn_decl, ref top_level_block) => {
let name = format!("fn{}", token::gensym("fn"));
let name = token::str_to_ident(name.as_slice());
})
}
- ast::ExprProc(ref decl, ref block) |
ast::ExprClosure(_, _, ref decl, ref block) => {
with_new_scope(cx,
block.span,
ast::ExprVec(..) | ast::ExprRepeat(..) => {
tvec::trans_fixed_vstore(bcx, expr, dest)
}
- ast::ExprClosure(_, _, ref decl, ref body) |
- ast::ExprProc(ref decl, ref body) => {
+ ast::ExprClosure(_, _, ref decl, ref body) => {
// Check the side-table to see whether this is an unboxed
// closure or an older, legacy style closure. Store this
// into a variable to ensure the the RefCell-lock is
None);
ty::mk_closure(tcx, fn_decl)
}
- ast::TyProc(ref f) => {
- // Use corresponding trait store to figure out default bounds
- // if none were specified.
- let bounds = conv_existential_bounds(this,
- rscope,
- ast_ty.span,
- None,
- f.bounds.as_slice());
-
- let fn_decl = ty_of_closure(this,
- f.fn_style,
- f.onceness,
- bounds,
- ty::UniqTraitStore,
- &*f.decl,
- abi::Rust,
- None);
-
- ty::mk_closure(tcx, fn_decl)
- }
ast::TyPolyTraitRef(ref bounds) => {
conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds.as_slice())
}
}
ast::TyInfer => {
// TyInfer also appears as the type of arguments or return
- // values in a ExprClosure or ExprProc, or as
+ // values in a ExprClosure, or as
// the type of local variables. Both of these cases are
// handled specially and will not descend into this routine.
this.ty_infer(ast_ty.span)
}
-pub fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
- expr: &ast::Expr,
- store: ty::TraitStore,
- decl: &ast::FnDecl,
- body: &ast::Block,
- expected: Expectation<'tcx>) {
+fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+ expr: &ast::Expr,
+ store: ty::TraitStore,
+ decl: &ast::FnDecl,
+ body: &ast::Block,
+ expected: Expectation<'tcx>) {
let tcx = fcx.ccx.tcx;
// Find the expected input/output types (if any). Substitute
}
_ => {
// Not an error! Means we're inferring the closure type
- let (bounds, onceness) = match expr.node {
- ast::ExprProc(..) => {
- let mut bounds = ty::region_existential_bound(ty::ReStatic);
- bounds.builtin_bounds.insert(ty::BoundSend); // FIXME
- (bounds, ast::Once)
- }
- _ => {
- let region = fcx.infcx().next_region_var(
- infer::AddrOfRegion(expr.span));
- (ty::region_existential_bound(region), ast::Many)
- }
- };
+ let region = fcx.infcx().next_region_var(
+ infer::AddrOfRegion(expr.span));
+ let bounds = ty::region_existential_bound(region);
+ let onceness = ast::Many;
(None, onceness, bounds)
}
}
fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
write_call(fcx, call_expression, output_type);
- if !fcx.tcx().sess.features.borrow().unboxed_closures {
- span_err!(fcx.tcx().sess, call_expression.span, E0056,
- "overloaded calls are experimental");
- span_help!(fcx.tcx().sess, call_expression.span,
- "add `#![feature(unboxed_closures)]` to \
- the crate attributes to enable");
- }
-
return true
}
};
for (i, arg) in args.iter().take(t).enumerate() {
let is_block = match arg.node {
- ast::ExprClosure(..) | ast::ExprProc(..) => true,
+ ast::ExprClosure(..) => true,
_ => false
};
ast::ExprClosure(_, opt_kind, ref decl, ref body) => {
closure::check_expr_closure(fcx, expr, opt_kind, &**decl, &**body, expected);
}
- ast::ExprProc(ref decl, ref body) => {
- closure::check_boxed_closure(fcx,
- expr,
- ty::UniqTraitStore,
- &**decl,
- &**body,
- expected);
- }
ast::ExprBlock(ref b) => {
check_block_with_expected(fcx, &**b, expected);
fcx.write_ty(id, fcx.node_ty(b.id));
visit::walk_expr(rcx, expr);
}
- ast::ExprProc(_, ref body) |
ast::ExprClosure(_, _, _, ref body) => {
check_expr_fn_block(rcx, expr, &**body);
}
let cause = traits::ObligationCause::new(freevar.span, rcx.fcx.body_id, code);
rcx.fcx.register_builtin_bound(var_ty, builtin_bound, cause);
}
+
type_must_outlive(
- rcx, infer::RelateProcBound(expr.span, var_node_id, var_ty),
+ rcx, infer::FreeVariable(expr.span, var_node_id),
var_ty, bounds.region_bound);
}
}
MethodCall::expr(e.id));
match e.node {
- ast::ExprClosure(_, _, ref decl, _) |
- ast::ExprProc(ref decl, _) => {
+ ast::ExprClosure(_, _, ref decl, _) => {
for input in decl.inputs.iter() {
let _ = self.visit_node_id(ResolvingExpr(e.span),
input.id);
ExprLoop(P<Block>, Option<Ident>),
ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
ExprClosure(CaptureClause, Option<UnboxedClosureKind>, P<FnDecl>, P<Block>),
- ExprProc(P<FnDecl>, P<Block>),
ExprBlock(P<Block>),
ExprAssign(P<Expr>, P<Expr>),
TyRptr(Option<Lifetime>, MutTy),
/// A closure (e.g. `|uint| -> bool`)
TyClosure(P<ClosureTy>),
- /// A procedure (e.g `proc(uint) -> bool`)
- TyProc(P<ClosureTy>),
/// A bare function (e.g. `fn(uint) -> bool`)
TyBareFn(P<BareFnTy>),
/// A tuple (`(A, B, C, D,...)`)
///
/// More specifically, it is one of either:
/// - A function item,
-/// - A closure expr (i.e. an ExprClosure or ExprProc), or
+/// - A closure expr (i.e. an ExprClosure), or
/// - The default implementation for a trait method.
///
/// To construct one, use the `Code::from_node` function.
impl MaybeFnLike for ast::Expr {
fn is_fn_like(&self) -> bool {
match self.node {
- ast::ExprClosure(..) | ast::ExprProc(..) => true,
+ ast::ExprClosure(..) => true,
_ => false,
}
}
ast_map::NodeExpr(e) => match e.node {
ast::ExprClosure(_, _, ref decl, ref block) =>
closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
- ast::ExprProc(ref decl, ref block) =>
- closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
_ => panic!("expr FnLikeNode that is not fn-like"),
},
_ => panic!("other FnLikeNode that is not fn-like"),
fn visit_ty(&mut self, ty: &'ast Ty) {
match ty.node {
- TyClosure(ref fd) | TyProc(ref fd) => {
+ TyClosure(ref fd) => {
self.visit_fn_decl(&*fd.decl);
}
TyBareFn(ref fd) => {
P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)})
}
- ast::ExprProc(fn_decl, block) => {
- let (rewritten_fn_decl, rewritten_block)
- = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
- let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
- P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)})
- }
-
_ => {
P(noop_fold_expr(ast::Expr {
id: id,
0)
}
- // closure arg hygiene (ExprProc)
- // expands to fn f(){(proc(x_1 : int) {(x_2 + x_1)})(3);}
- #[test] fn closure_arg_hygiene_2(){
- run_renaming_test(
- &("macro_rules! inject_x (()=>(x))
- fn f(){ (proc(x : int){(inject_x!() + x)})(3); }",
- vec!(vec!(1)),
- true),
- 0)
- }
-
// macro_rules in method position. Sadly, unimplemented.
#[test] fn macro_in_method_posn(){
expand_crate_str(
fn visit_expr(&mut self, e: &ast::Expr) {
match e.node {
- ast::ExprClosure(_, Some(_), _, _) => {
- self.gate_feature("unboxed_closures",
- e.span,
- "unboxed closures are a work-in-progress \
- feature with known bugs");
- }
ast::ExprSlice(..) => {
self.gate_feature("slicing_syntax",
e.span,
}
}))
}
- TyProc(f) => {
- TyProc(f.map(|ClosureTy {fn_style, onceness, bounds, decl, lifetimes}| {
- ClosureTy {
- fn_style: fn_style,
- onceness: onceness,
- bounds: fld.fold_bounds(bounds),
- decl: fld.fold_fn_decl(decl),
- lifetimes: fld.fold_lifetime_defs(lifetimes)
- }
- }))
- }
TyBareFn(f) => {
TyBareFn(f.map(|BareFnTy {lifetimes, fn_style, abi, decl}| BareFnTy {
lifetimes: fld.fold_lifetime_defs(lifetimes),
arms.move_map(|x| folder.fold_arm(x)),
source)
}
- ExprProc(decl, body) => {
- ExprProc(folder.fold_fn_decl(decl),
- folder.fold_block(body))
- }
ExprClosure(capture_clause, opt_kind, decl, body) => {
ExprClosure(capture_clause,
opt_kind,
ObsoleteImportRenaming,
ObsoleteSubsliceMatch,
ObsoleteExternCrateRenaming,
+ ObsoleteProcType,
+ ObsoleteProcExpr,
}
impl Copy for ObsoleteSyntax {}
/// Reports an obsolete syntax non-fatal error.
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
let (kind_str, desc) = match kind {
+ ObsoleteProcType => (
+ "the `proc` type",
+ "use unboxed closures instead",
+ ),
+ ObsoleteProcExpr => (
+ "`proc` expression",
+ "use a `move ||` expression instead",
+ ),
ObsoleteOwnedType => (
"`~` notation for owned pointers",
"use `Box<T>` in `std::owned` instead"
use ast::{ExprBreak, ExprCall, ExprCast};
use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
use ast::{ExprLit, ExprLoop, ExprMac};
-use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
+use ast::{ExprMethodCall, ExprParen, ExprPath};
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
-use ast::{Once, Many};
+use ast::{Many};
use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
use ast::{FnOnceUnboxedClosureKind};
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
use ast::{TtDelimited, TtSequence, TtToken};
use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
-use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
+use ast::{TypeField, TyFixedLengthVec, TyClosure, TyBareFn};
use ast::{TyTypeof, TyInfer, TypeMethod};
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
Deprecated:
- for <'lt> |S| -> T
- - for <'lt> proc(S) -> T
Eventually:
| | | Bounds
| | Argument types
| Legacy lifetimes
- the `proc` keyword
+ the `proc` keyword (already consumed)
*/
- let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs);
- let (inputs, variadic) = self.parse_fn_args(false, false);
- let bounds = self.parse_colon_then_ty_param_bounds();
- let ret_ty = self.parse_ret_ty();
- let decl = P(FnDecl {
- inputs: inputs,
- output: ret_ty,
- variadic: variadic
- });
- TyProc(P(ClosureTy {
- fn_style: NormalFn,
- onceness: Once,
- bounds: bounds,
- decl: decl,
- lifetimes: lifetime_defs,
- }))
+ let proc_span = self.last_span;
+
+ // 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_ret_ty();
+
+ self.obsolete(proc_span, ObsoleteProcType);
+
+ TyInfer
}
/// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
return self.parse_lambda_expr(CaptureByValue);
}
if self.eat_keyword(keywords::Proc) {
- let decl = self.parse_proc_decl();
- let body = self.parse_expr();
- let fakeblock = P(ast::Block {
- id: ast::DUMMY_NODE_ID,
- view_items: Vec::new(),
- stmts: Vec::new(),
- rules: DefaultBlock,
- span: body.span,
- expr: Some(body),
- });
- return self.mk_expr(lo, fakeblock.span.hi, ExprProc(decl, fakeblock));
+ let span = self.last_span;
+ let _ = self.parse_proc_decl();
+ let _ = self.parse_expr();
+ return self.obsolete_expr(span, ObsoleteProcExpr);
}
if self.eat_keyword(keywords::If) {
return self.parse_if_expr();
fn needs_parentheses(expr: &ast::Expr) -> bool {
match expr.node {
ast::ExprAssign(..) | ast::ExprBinary(..) |
- ast::ExprClosure(..) | ast::ExprProc(..) |
+ ast::ExprClosure(..) |
ast::ExprAssignOp(..) | ast::ExprCast(..) => true,
_ => false,
}
Some(&generics),
None));
}
- ast::TyProc(ref f) => {
- let generics = ast::Generics {
- lifetimes: f.lifetimes.clone(),
- ty_params: OwnedSlice::empty(),
- where_clause: ast::WhereClause {
- id: ast::DUMMY_NODE_ID,
- predicates: Vec::new(),
- },
- };
- try!(self.print_ty_fn(None,
- Some('~'),
- f.fn_style,
- f.onceness,
- &*f.decl,
- None,
- &f.bounds,
- Some(&generics),
- None));
- }
ast::TyPath(ref path, _) => {
try!(self.print_path(path, false));
}
// empty box to satisfy the close.
try!(self.ibox(0));
}
- ast::ExprProc(ref decl, ref body) => {
- // in do/for blocks we don't want to show an empty
- // argument list, but at this point we don't know which
- // we are inside.
- //
- // if !decl.inputs.is_empty() {
- try!(self.print_proc_args(&**decl));
- try!(space(&mut self.s));
- // }
- assert!(body.stmts.is_empty());
- assert!(body.expr.is_some());
- // we extract the block, so as not to create another set of boxes
- match body.expr.as_ref().unwrap().node {
- ast::ExprBlock(ref blk) => {
- try!(self.print_block_unclosed(&**blk));
- }
- _ => {
- // this is a bare expression
- try!(self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap()));
- try!(self.end()); // need to close a box
- }
- }
- // a box will be closed by print_expr, but we didn't want an overall
- // wrapper so we closed the corresponding opening. so create an
- // empty box to satisfy the close.
- try!(self.ibox(0));
- }
ast::ExprBlock(ref blk) => {
// containing cbox, will be closed by print-block at }
try!(self.cbox(indent_unit));
match data.output {
None => { }
Some(ref ty) => {
+ try!(self.space_if_not_bol());
try!(self.word_space("->"));
try!(self.print_type(&**ty));
}
walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
}
- TyProc(ref function_declaration) => {
- for argument in function_declaration.decl.inputs.iter() {
- visitor.visit_ty(&*argument.ty)
- }
- walk_fn_ret_ty(visitor, &function_declaration.decl.output);
- walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
- walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
- }
TyBareFn(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(&*argument.ty)
expression.span,
expression.id)
}
- ExprProc(ref function_declaration, ref body) => {
- visitor.visit_fn(FkFnBlock,
- &**function_declaration,
- &**body,
- expression.span,
- expression.id)
- }
ExprBlock(ref block) => visitor.visit_block(&**block),
ExprAssign(ref left_hand_expression, ref right_hand_expression) => {
visitor.visit_expr(&**right_hand_expression);