diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index fe5925f26f0ac..3a50306bb8766 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -226,7 +226,9 @@ struct env { idstack: @mut ~[NodeId] } -struct CheckItemRecursionVisitor; +struct CheckItemRecursionVisitor { + env: env, +} // Make sure a const item doesn't recursively refer to itself // FIXME: Should use the dependency graph when it's available (#1356) @@ -242,27 +244,27 @@ pub fn check_item_recursion(sess: Session, idstack: @mut ~[] }; - let mut visitor = CheckItemRecursionVisitor; - visitor.visit_item(it, env); + let mut visitor = CheckItemRecursionVisitor { env: env }; + visitor.visit_item(it, ()); } -impl Visitor for CheckItemRecursionVisitor { - fn visit_item(&mut self, it: @item, env: env) { - if env.idstack.iter().any(|x| x == &(it.id)) { - env.sess.span_fatal(env.root_it.span, "recursive constant"); +impl Visitor<()> for CheckItemRecursionVisitor { + fn visit_item(&mut self, it: @item, _: ()) { + if self.env.idstack.iter().any(|x| x == &(it.id)) { + self.env.sess.span_fatal(self.env.root_it.span, "recursive constant"); } - env.idstack.push(it.id); - visit::walk_item(self, it, env); - env.idstack.pop(); + self.env.idstack.push(it.id); + visit::walk_item(self, it, ()); + self.env.idstack.pop(); } - fn visit_expr(&mut self, e: @Expr, env: env) { + fn visit_expr(&mut self, e: @Expr, _: ()) { match e.node { - ExprPath(*) => match env.def_map.find(&e.id) { + ExprPath(*) => match self.env.def_map.find(&e.id) { Some(&DefStatic(def_id, _)) if ast_util::is_local(def_id) => - match env.ast_map.get_copy(&def_id.node) { + match self.env.ast_map.get_copy(&def_id.node) { ast_map::node_item(it, _) => { - self.visit_item(it, env); + self.visit_item(it, ()); } _ => fail!("const not bound to an item") }, @@ -270,6 +272,6 @@ impl Visitor for CheckItemRecursionVisitor { }, _ => () } - visit::walk_expr(self, e, env); + visit::walk_expr(self, e, ()); } } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 1b3224a2217f0..270babb9cf3e2 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -54,43 +54,38 @@ use syntax::visit::Visitor; pub struct Context { tcx: ty::ctxt, method_map: typeck::method_map, - current_item: NodeId } -struct KindAnalysisVisitor; +impl Visitor<()> for Context { -impl Visitor for KindAnalysisVisitor { - - fn visit_expr(&mut self, ex:@Expr, e:Context) { - check_expr(self, ex, e); + fn visit_expr(&mut self, ex:@Expr, _:()) { + check_expr(self, ex); } - fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, e:Context) { - check_fn(self, fk, fd, b, s, n, e); + fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, _:()) { + check_fn(self, fk, fd, b, s, n); } - fn visit_ty(&mut self, t:&Ty, e:Context) { - check_ty(self, t, e); + fn visit_ty(&mut self, t:&Ty, _:()) { + check_ty(self, t); } - fn visit_item(&mut self, i:@item, e:Context) { - check_item(self, i, e); + fn visit_item(&mut self, i:@item, _:()) { + check_item(self, i); } } pub fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, crate: &Crate) { - let ctx = Context { + let mut ctx = Context { tcx: tcx, method_map: method_map, - current_item: -1 }; - let mut visit = KindAnalysisVisitor; - visit::walk_crate(&mut visit, crate, ctx); + visit::walk_crate(&mut ctx, crate, ()); tcx.sess.abort_if_errors(); } -fn check_struct_safe_for_destructor(cx: Context, +fn check_struct_safe_for_destructor(cx: &mut Context, span: Span, struct_did: DefId) { let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did); @@ -120,7 +115,7 @@ fn check_struct_safe_for_destructor(cx: Context, } } -fn check_impl_of_trait(cx: Context, it: @item, trait_ref: &trait_ref, self_type: &Ty) { +fn check_impl_of_trait(cx: &mut Context, it: @item, trait_ref: &trait_ref, self_type: &Ty) { let ast_trait_def = cx.tcx.def_map.find(&trait_ref.ref_id) .expect("trait ref not in def map!"); let trait_def_id = ast_util::def_id_of_def(*ast_trait_def); @@ -156,7 +151,7 @@ fn check_impl_of_trait(cx: Context, it: @item, trait_ref: &trait_ref, self_type: } } -fn check_item(visitor: &mut KindAnalysisVisitor, item: @item, cx: Context) { +fn check_item(cx: &mut Context, item: @item) { if !attr::contains_name(item.attrs, "unsafe_destructor") { match item.node { item_impl(_, Some(ref trait_ref), ref self_type, _) => { @@ -166,16 +161,15 @@ fn check_item(visitor: &mut KindAnalysisVisitor, item: @item, cx: Context) { } } - let cx = Context { current_item: item.id, ..cx }; - visit::walk_item(visitor, item, cx); + visit::walk_item(cx, item, ()); } // Yields the appropriate function to check the kind of closed over // variables. `id` is the NodeId for some expression that creates the // closure. -fn with_appropriate_checker(cx: Context, id: NodeId, - b: &fn(checker: &fn(Context, @freevar_entry))) { - fn check_for_uniq(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { +fn with_appropriate_checker(cx: &Context, id: NodeId, + b: &fn(checker: &fn(&Context, @freevar_entry))) { + fn check_for_uniq(cx: &Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned, regardless of whether it is // moved in or copied in. let id = ast_util::def_id_of_def(fv.def).node; @@ -187,7 +181,7 @@ fn with_appropriate_checker(cx: Context, id: NodeId, check_freevar_bounds(cx, fv.span, var_t, bounds, None); } - fn check_for_box(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { + fn check_for_box(cx: &Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); @@ -198,7 +192,7 @@ fn with_appropriate_checker(cx: Context, id: NodeId, check_freevar_bounds(cx, fv.span, var_t, bounds, None); } - fn check_for_block(cx: Context, fv: &freevar_entry, + fn check_for_block(cx: &Context, fv: &freevar_entry, bounds: ty::BuiltinBounds, region: ty::Region) { let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); @@ -209,7 +203,7 @@ fn with_appropriate_checker(cx: Context, id: NodeId, bounds, Some(var_t)); } - fn check_for_bare(cx: Context, fv: @freevar_entry) { + fn check_for_bare(cx: &Context, fv: @freevar_entry) { cx.tcx.sess.span_err( fv.span, "can't capture dynamic environment in a fn item; \ @@ -252,13 +246,12 @@ fn with_appropriate_checker(cx: Context, id: NodeId, // Check that the free variables used in a shared/sendable closure conform // to the copy/move kind bounds. Then recursively check the function body. fn check_fn( - v: &mut KindAnalysisVisitor, + cx: &mut Context, fk: &visit::fn_kind, decl: &fn_decl, body: &Block, sp: Span, - fn_id: NodeId, - cx: Context) { + fn_id: NodeId) { // Check kinds on free variables: do with_appropriate_checker(cx, fn_id) |chk| { @@ -268,10 +261,10 @@ fn check_fn( } } - visit::walk_fn(v, fk, decl, body, sp, fn_id, cx); + visit::walk_fn(cx, fk, decl, body, sp, fn_id, ()); } -pub fn check_expr(v: &mut KindAnalysisVisitor, e: @Expr, cx: Context) { +pub fn check_expr(cx: &mut Context, e: @Expr) { debug!("kind::check_expr(%s)", expr_to_str(e, cx.tcx.sess.intr())); // Handle any kind bounds on type parameters @@ -336,10 +329,10 @@ pub fn check_expr(v: &mut KindAnalysisVisitor, e: @Expr, cx: Context) { } _ => {} } - visit::walk_expr(v, e, cx); + visit::walk_expr(cx, e, ()); } -fn check_ty(v: &mut KindAnalysisVisitor, aty: &Ty, cx: Context) { +fn check_ty(cx: &mut Context, aty: &Ty) { match aty.node { ty_path(_, _, id) => { let r = cx.tcx.node_type_substs.find(&id); @@ -354,11 +347,11 @@ fn check_ty(v: &mut KindAnalysisVisitor, aty: &Ty, cx: Context) { } _ => {} } - visit::walk_ty(v, aty, cx); + visit::walk_ty(cx, aty, ()); } // Calls "any_missing" if any bounds were missing. -pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds, +pub fn check_builtin_bounds(cx: &Context, ty: ty::t, bounds: ty::BuiltinBounds, any_missing: &fn(ty::BuiltinBounds)) { let kind = ty::type_contents(cx.tcx, ty); @@ -373,7 +366,7 @@ pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds, } } -pub fn check_typaram_bounds(cx: Context, +pub fn check_typaram_bounds(cx: &Context, _type_parameter_id: NodeId, sp: Span, ty: ty::t, @@ -389,7 +382,7 @@ pub fn check_typaram_bounds(cx: Context, } } -pub fn check_freevar_bounds(cx: Context, sp: Span, ty: ty::t, +pub fn check_freevar_bounds(cx: &Context, sp: Span, ty: ty::t, bounds: ty::BuiltinBounds, referenced_ty: Option) { do check_builtin_bounds(cx, ty, bounds) |missing| { @@ -412,7 +405,7 @@ pub fn check_freevar_bounds(cx: Context, sp: Span, ty: ty::t, } } -pub fn check_trait_cast_bounds(cx: Context, sp: Span, ty: ty::t, +pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t, bounds: ty::BuiltinBounds) { do check_builtin_bounds(cx, ty, bounds) |missing| { cx.tcx.sess.span_err(sp, @@ -423,7 +416,7 @@ pub fn check_trait_cast_bounds(cx: Context, sp: Span, ty: ty::t, } } -fn is_nullary_variant(cx: Context, ex: @Expr) -> bool { +fn is_nullary_variant(cx: &Context, ex: @Expr) -> bool { match ex.node { ExprPath(_) => { match cx.tcx.def_map.get_copy(&ex.id) { @@ -437,7 +430,7 @@ fn is_nullary_variant(cx: Context, ex: @Expr) -> bool { } } -fn check_imm_free_var(cx: Context, def: Def, sp: Span) { +fn check_imm_free_var(cx: &Context, def: Def, sp: Span) { match def { DefLocal(_, is_mutbl) => { if is_mutbl { @@ -457,7 +450,7 @@ fn check_imm_free_var(cx: Context, def: Def, sp: Span) { } } -fn check_copy(cx: Context, ty: ty::t, sp: Span, reason: &str) { +fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) { debug!("type_contents(%s)=%s", ty_to_str(cx.tcx, ty), ty::type_contents(cx.tcx, ty).to_str()); @@ -469,7 +462,7 @@ fn check_copy(cx: Context, ty: ty::t, sp: Span, reason: &str) { } } -pub fn check_send(cx: Context, ty: ty::t, sp: Span) -> bool { +pub fn check_send(cx: &Context, ty: ty::t, sp: Span) -> bool { if !ty::type_is_sendable(cx.tcx, ty) { cx.tcx.sess.span_err( sp, fmt!("value has non-sendable type `%s`", @@ -525,7 +518,7 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: Span) -> bool { /// /// FIXME(#5723)---This code should probably move into regionck. pub fn check_cast_for_escaping_regions( - cx: Context, + cx: &Context, source: &Expr, target: &Expr) { @@ -601,7 +594,7 @@ pub fn check_cast_for_escaping_regions( } } - fn is_subregion_of(cx: Context, r_sub: ty::Region, r_sup: ty::Region) -> bool { + fn is_subregion_of(cx: &Context, r_sub: ty::Region, r_sup: ty::Region) -> bool { cx.tcx.region_maps.is_subregion_of(r_sub, r_sup) } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d8a7096982f09..9e28bfcb964c4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -345,20 +345,18 @@ impl IrMaps { } } -struct ErrorCheckVisitor; - -impl Visitor<@Liveness> for ErrorCheckVisitor { - fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, e:@Liveness) { - check_fn(self, fk, fd, b, s, n, e); +impl Visitor<()> for Liveness { + fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, _:()) { + check_fn(self, fk, fd, b, s, n); } - fn visit_local(&mut self, l:@Local, e:@Liveness) { - check_local(self, l, e); + fn visit_local(&mut self, l:@Local, _:()) { + check_local(self, l); } - fn visit_expr(&mut self, ex:@Expr, e:@Liveness) { - check_expr(self, ex, e); + fn visit_expr(&mut self, ex:@Expr, _:()) { + check_expr(self, ex); } - fn visit_arm(&mut self, a:&Arm, e:@Liveness) { - check_arm(self, a, e); + fn visit_arm(&mut self, a:&Arm, _:()) { + check_arm(self, a); } } @@ -419,12 +417,11 @@ fn visit_fn(v: &mut LivenessVisitor, }; // compute liveness - let lsets = @Liveness(fn_maps, specials); - let entry_ln = (*lsets).compute(decl, body); + let mut lsets = Liveness(fn_maps, specials); + let entry_ln = lsets.compute(decl, body); // check for various error conditions - let mut check_vt = ErrorCheckVisitor; - check_vt.visit_block(body, lsets); + lsets.visit_block(body, ()); lsets.check_ret(id, sp, fk, entry_ln); lsets.warn_about_unused_args(decl, entry_ln); } @@ -1423,7 +1420,7 @@ impl Liveness { // _______________________________________________________________________ // Checking for error conditions -fn check_local(vt: &mut ErrorCheckVisitor, local: @Local, this: @Liveness) { +fn check_local(this: &mut Liveness, local: @Local) { match local.init { Some(_) => { this.warn_about_unused_or_dead_vars_in_pat(local.pat); @@ -1449,48 +1446,48 @@ fn check_local(vt: &mut ErrorCheckVisitor, local: @Local, this: @Liveness) { } } - visit::walk_local(vt, local, this); + visit::walk_local(this, local, ()); } -fn check_arm(vt: &mut ErrorCheckVisitor, arm: &Arm, this: @Liveness) { +fn check_arm(this: &mut Liveness, arm: &Arm) { do this.arm_pats_bindings(arm.pats) |ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); } - visit::walk_arm(vt, arm, this); + visit::walk_arm(this, arm, ()); } -fn check_expr(vt: &mut ErrorCheckVisitor, expr: @Expr, this: @Liveness) { +fn check_expr(this: &mut Liveness, expr: @Expr) { match expr.node { ExprAssign(l, r) => { - this.check_lvalue(l, vt); - vt.visit_expr(r, this); + this.check_lvalue(l); + this.visit_expr(r, ()); - visit::walk_expr(vt, expr, this); + visit::walk_expr(this, expr, ()); } ExprAssignOp(_, _, l, _) => { - this.check_lvalue(l, vt); + this.check_lvalue(l); - visit::walk_expr(vt, expr, this); + visit::walk_expr(this, expr, ()); } ExprInlineAsm(ref ia) => { for &(_, input) in ia.inputs.iter() { - vt.visit_expr(input, this); + this.visit_expr(input, ()); } // Output operands must be lvalues for &(_, out) in ia.outputs.iter() { match out.node { ExprAddrOf(_, inner) => { - this.check_lvalue(inner, vt); + this.check_lvalue(inner); } _ => {} } - vt.visit_expr(out, this); + this.visit_expr(out, ()); } - visit::walk_expr(vt, expr, this); + visit::walk_expr(this, expr, ()); } // no correctness conditions related to liveness @@ -1502,19 +1499,18 @@ fn check_expr(vt: &mut ErrorCheckVisitor, expr: @Expr, this: @Liveness) { ExprAgain(*) | ExprLit(_) | ExprBlock(*) | ExprMac(*) | ExprAddrOf(*) | ExprStruct(*) | ExprRepeat(*) | ExprParen(*) | ExprFnBlock(*) | ExprPath(*) | ExprSelf(*) => { - visit::walk_expr(vt, expr, this); + visit::walk_expr(this, expr, ()); } ExprForLoop(*) => fail!("non-desugared expr_for_loop") } } -fn check_fn(_v: &mut ErrorCheckVisitor, +fn check_fn(_v: &Liveness, _fk: &visit::fn_kind, _decl: &fn_decl, _body: &Block, _sp: Span, - _id: NodeId, - _self: @Liveness) { + _id: NodeId) { // do not check contents of nested fns } @@ -1549,7 +1545,7 @@ impl Liveness { } } - pub fn check_lvalue(@self, expr: @Expr, vt: &mut ErrorCheckVisitor) { + pub fn check_lvalue(&mut self, expr: @Expr) { match expr.node { ExprPath(_) => { match self.tcx.def_map.get_copy(&expr.id) { @@ -1578,7 +1574,7 @@ impl Liveness { _ => { // For other kinds of lvalues, no checks are required, // and any embedded expressions are actually rvalues - visit::walk_expr(vt, expr, self); + visit::walk_expr(self, expr, ()); } } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index c4e20137271d3..5b6bb3a7b752a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -65,12 +65,6 @@ pub struct RegionMaps { #[deriving(Clone)] pub struct Context { - sess: Session, - def_map: resolve::DefMap, - - // Generated maps: - region_maps: @mut RegionMaps, - // Scope where variables should be parented to var_parent: Option, @@ -78,6 +72,15 @@ pub struct Context { parent: Option, } +struct RegionResolutionVisitor { + sess: Session, + def_map: resolve::DefMap, + + // Generated maps: + region_maps: @mut RegionMaps, +} + + impl RegionMaps { pub fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) { match self.free_region_map.find_mut(&sub) { @@ -318,11 +321,12 @@ impl RegionMaps { } /// Records the current parent (if any) as the parent of `child_id`. -fn parent_to_expr(cx: Context, child_id: ast::NodeId, sp: Span) { +fn parent_to_expr(visitor: &mut RegionResolutionVisitor, + cx: Context, child_id: ast::NodeId, sp: Span) { debug!("region::parent_to_expr(span=%?)", - cx.sess.codemap.span_to_str(sp)); + visitor.sess.codemap.span_to_str(sp)); for parent_id in cx.parent.iter() { - cx.region_maps.record_parent(child_id, *parent_id); + visitor.region_maps.record_parent(child_id, *parent_id); } } @@ -330,12 +334,11 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block, cx: Context) { // Record the parent of this block. - parent_to_expr(cx, blk.id, blk.span); + parent_to_expr(visitor, cx, blk.id, blk.span); // Descend. let new_cx = Context {var_parent: Some(blk.id), - parent: Some(blk.id), - ..cx}; + parent: Some(blk.id)}; visit::walk_block(visitor, blk, new_cx); } @@ -349,7 +352,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: @ast::Pat, cx: Context) { assert_eq!(cx.var_parent, cx.parent); - parent_to_expr(cx, pat.id, pat.span); + parent_to_expr(visitor, cx, pat.id, pat.span); visit::walk_pat(visitor, pat, cx); } @@ -362,18 +365,18 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, } ast::StmtExpr(_, stmt_id) | ast::StmtSemi(_, stmt_id) => { - parent_to_expr(cx, stmt_id, stmt.span); + parent_to_expr(visitor, cx, stmt_id, stmt.span); let expr_cx = Context {parent: Some(stmt_id), ..cx}; visit::walk_stmt(visitor, stmt, expr_cx); } - ast::StmtMac(*) => cx.sess.bug("unexpanded macro") + ast::StmtMac(*) => visitor.sess.bug("unexpanded macro") } } fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: @ast::Expr, cx: Context) { - parent_to_expr(cx, expr.id, expr.span); + parent_to_expr(visitor, cx, expr.id, expr.span); let mut new_cx = cx; new_cx.parent = Some(expr.id); @@ -415,7 +418,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: @ast::Local, cx: Context) { assert_eq!(cx.var_parent, cx.parent); - parent_to_expr(cx, local.id, local.span); + parent_to_expr(visitor, cx, local.id, local.span); visit::walk_local(visitor, local, cx); } @@ -439,7 +442,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor, body.id=%?, \ cx.parent=%?)", id, - cx.sess.codemap.span_to_str(sp), + visitor.sess.codemap.span_to_str(sp), body.id, cx.parent); @@ -449,7 +452,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor, ..cx}; match *fk { visit::fk_method(_, _, method) => { - cx.region_maps.record_parent(method.self_id, body.id); + visitor.region_maps.record_parent(method.self_id, body.id); } _ => {} } @@ -470,8 +473,6 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor, visitor.visit_block(body, body_cx); } -struct RegionResolutionVisitor; - impl Visitor for RegionResolutionVisitor { fn visit_block(&mut self, b:&Block, cx:Context) { @@ -511,12 +512,13 @@ pub fn resolve_crate(sess: Session, free_region_map: HashMap::new(), cleanup_scopes: HashSet::new(), }; - let cx = Context {sess: sess, - def_map: def_map, - region_maps: region_maps, - parent: None, + let cx = Context {parent: None, var_parent: None}; - let mut visitor = RegionResolutionVisitor; + let mut visitor = RegionResolutionVisitor { + sess: sess, + def_map: def_map, + region_maps: region_maps, + }; visit::walk_crate(&mut visitor, crate, cx); return region_maps; } @@ -733,10 +735,9 @@ impl DetermineRpCtxt { } fn determine_rp_in_item(visitor: &mut DetermineRpVisitor, - item: @ast::item, - cx: @mut DetermineRpCtxt) { - do cx.with(item.id, true) { - visit::walk_item(visitor, item, cx); + item: @ast::item) { + do visitor.cx.with(item.id, true) { + visit::walk_item(visitor, item, ()); } } @@ -745,32 +746,33 @@ fn determine_rp_in_fn(visitor: &mut DetermineRpVisitor, decl: &ast::fn_decl, body: &ast::Block, _: Span, - _: ast::NodeId, - cx: @mut DetermineRpCtxt) { + _: ast::NodeId) { + let cx = visitor.cx; do cx.with(cx.item_id, false) { do cx.with_ambient_variance(rv_contravariant) { for a in decl.inputs.iter() { - visitor.visit_ty(&a.ty, cx); + visitor.visit_ty(&a.ty, ()); } } - visitor.visit_ty(&decl.output, cx); + visitor.visit_ty(&decl.output, ()); let generics = visit::generics_of_fn(fk); - visitor.visit_generics(&generics, cx); - visitor.visit_block(body, cx); + visitor.visit_generics(&generics, ()); + visitor.visit_block(body, ()); } } fn determine_rp_in_ty_method(visitor: &mut DetermineRpVisitor, - ty_m: &ast::TypeMethod, - cx: @mut DetermineRpCtxt) { + ty_m: &ast::TypeMethod) { + let cx = visitor.cx; do cx.with(cx.item_id, false) { - visit::walk_ty_method(visitor, ty_m, cx); + visit::walk_ty_method(visitor, ty_m, ()); } } fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor, - ty: &ast::Ty, - cx: @mut DetermineRpCtxt) { + ty: &ast::Ty) { + let cx = visitor.cx; + // we are only interested in types that will require an item to // be region-parameterized. if cx.item_id is zero, then this type // is not a member of a type defn nor is it a constitutent of an @@ -854,14 +856,14 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor, match ty.node { ast::ty_box(ref mt) | ast::ty_uniq(ref mt) | ast::ty_vec(ref mt) | ast::ty_rptr(_, ref mt) | ast::ty_ptr(ref mt) => { - visit_mt(visitor, mt, cx); + visit_mt(visitor, mt); } ast::ty_path(ref path, _, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { for tp in path.segments.iter().flat_map(|s| s.types.iter()) { - visitor.visit_ty(tp, cx); + visitor.visit_ty(tp, ()); } } } @@ -874,57 +876,58 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor, // parameters are contravariant do cx.with_ambient_variance(rv_contravariant) { for a in decl.inputs.iter() { - visitor.visit_ty(&a.ty, cx); + visitor.visit_ty(&a.ty, ()); } } - visitor.visit_ty(&decl.output, cx); + visitor.visit_ty(&decl.output, ()); } } _ => { - visit::walk_ty(visitor, ty, cx); + visit::walk_ty(visitor, ty, ()); } } fn visit_mt(visitor: &mut DetermineRpVisitor, - mt: &ast::mt, - cx: @mut DetermineRpCtxt) { + mt: &ast::mt) { + let cx = visitor.cx; // mutability is invariant if mt.mutbl == ast::MutMutable { do cx.with_ambient_variance(rv_invariant) { - visitor.visit_ty(mt.ty, cx); + visitor.visit_ty(mt.ty, ()); } } else { - visitor.visit_ty(mt.ty, cx); + visitor.visit_ty(mt.ty, ()); } } } fn determine_rp_in_struct_field(visitor: &mut DetermineRpVisitor, - cm: @ast::struct_field, - cx: @mut DetermineRpCtxt) { - visit::walk_struct_field(visitor, cm, cx); + cm: @ast::struct_field) { + visit::walk_struct_field(visitor, cm, ()); } -struct DetermineRpVisitor; +struct DetermineRpVisitor { + cx: @mut DetermineRpCtxt +} -impl Visitor<@mut DetermineRpCtxt> for DetermineRpVisitor { +impl Visitor<()> for DetermineRpVisitor { fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, - b:&Block, s:Span, n:NodeId, e:@mut DetermineRpCtxt) { - determine_rp_in_fn(self, fk, fd, b, s, n, e); + b:&Block, s:Span, n:NodeId, _:()) { + determine_rp_in_fn(self, fk, fd, b, s, n); } - fn visit_item(&mut self, i:@item, e:@mut DetermineRpCtxt) { - determine_rp_in_item(self, i, e); + fn visit_item(&mut self, i:@item, _:()) { + determine_rp_in_item(self, i); } - fn visit_ty(&mut self, t:&Ty, e:@mut DetermineRpCtxt) { - determine_rp_in_ty(self, t, e); + fn visit_ty(&mut self, t:&Ty, _:()) { + determine_rp_in_ty(self, t); } - fn visit_ty_method(&mut self, t:&TypeMethod, e:@mut DetermineRpCtxt) { - determine_rp_in_ty_method(self, t, e); + fn visit_ty_method(&mut self, t:&TypeMethod, _:()) { + determine_rp_in_ty_method(self, t); } - fn visit_struct_field(&mut self, s:@struct_field, e:@mut DetermineRpCtxt) { - determine_rp_in_struct_field(self, s, e); + fn visit_struct_field(&mut self, s:@struct_field, _:()) { + determine_rp_in_struct_field(self, s); } } @@ -947,8 +950,8 @@ pub fn determine_rp_in_crate(sess: Session, }; // Gather up the base set, worklist and dep_map - let mut visitor = DetermineRpVisitor; - visit::walk_crate(&mut visitor, crate, cx); + let mut visitor = DetermineRpVisitor { cx: cx }; + visit::walk_crate(&mut visitor, crate, ()); // Propagate indirect dependencies // diff --git a/src/librustc/middle/stack_check.rs b/src/librustc/middle/stack_check.rs index 5388e64348c6e..44de6fde05070 100644 --- a/src/librustc/middle/stack_check.rs +++ b/src/librustc/middle/stack_check.rs @@ -28,56 +28,53 @@ use util::ppaux::Repr; #[deriving(Clone)] struct Context { - tcx: ty::ctxt, safe_stack: bool } -struct StackCheckVisitor; +struct StackCheckVisitor { + tcx: ty::ctxt, +} impl Visitor for StackCheckVisitor { fn visit_item(&mut self, i:@ast::item, e:Context) { - stack_check_item(*self, i, e); + stack_check_item(self, i, e); } fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl, b:&ast::Block, s:Span, n:ast::NodeId, e:Context) { - stack_check_fn(*self, fk, fd, b, s, n, e); + stack_check_fn(self, fk, fd, b, s, n, e); } fn visit_expr(&mut self, ex:@ast::Expr, e:Context) { - stack_check_expr(*self, ex, e); + stack_check_expr(self, ex, e); } } pub fn stack_check_crate(tcx: ty::ctxt, crate: &ast::Crate) { - let new_cx = Context { - tcx: tcx, - safe_stack: false - }; - let mut visitor = StackCheckVisitor; + let new_cx = Context { safe_stack: false }; + let mut visitor = StackCheckVisitor { tcx: tcx }; visit::walk_crate(&mut visitor, crate, new_cx); } -fn stack_check_item(v: StackCheckVisitor, +fn stack_check_item(v: &mut StackCheckVisitor, item: @ast::item, in_cx: Context) { - let mut v = v; match item.node { ast::item_fn(_, ast::extern_fn, _, _, _) => { // an extern fn is already being called from C code... - let new_cx = Context {safe_stack: true, ..in_cx}; - visit::walk_item(&mut v, item, new_cx); + let new_cx = Context {safe_stack: true}; + visit::walk_item(v, item, new_cx); } ast::item_fn(*) => { let safe_stack = fixed_stack_segment(item.attrs); - let new_cx = Context {safe_stack: safe_stack, ..in_cx}; - visit::walk_item(&mut v, item, new_cx); + let new_cx = Context {safe_stack: safe_stack}; + visit::walk_item(v, item, new_cx); } ast::item_impl(_, _, _, ref methods) => { // visit_method() would make this nicer for &method in methods.iter() { let safe_stack = fixed_stack_segment(method.attrs); - let new_cx = Context {safe_stack: safe_stack, ..in_cx}; - visit::walk_method_helper(&mut v, method, new_cx); + let new_cx = Context {safe_stack: safe_stack}; + visit::walk_method_helper(v, method, new_cx); } } ast::item_trait(_, _, ref methods) => { @@ -85,15 +82,15 @@ fn stack_check_item(v: StackCheckVisitor, match *method { ast::provided(@ref method) => { let safe_stack = fixed_stack_segment(method.attrs); - let new_cx = Context {safe_stack: safe_stack, ..in_cx}; - visit::walk_method_helper(&mut v, method, new_cx); + let new_cx = Context {safe_stack: safe_stack}; + visit::walk_method_helper(v, method, new_cx); } ast::required(*) => () } } } _ => { - visit::walk_item(&mut v, item, in_cx); + visit::walk_item(v, item, in_cx); } } @@ -102,7 +99,7 @@ fn stack_check_item(v: StackCheckVisitor, } } -fn stack_check_fn<'a>(v: StackCheckVisitor, +fn stack_check_fn<'a>(v: &mut StackCheckVisitor, fk: &visit::fn_kind, decl: &ast::fn_decl, body: &ast::Block, @@ -114,7 +111,7 @@ fn stack_check_fn<'a>(v: StackCheckVisitor, in_cx.safe_stack // see stack_check_item above } visit::fk_anon(*) | visit::fk_fn_block => { - match ty::get(ty::node_id_to_type(in_cx.tcx, id)).sty { + match ty::get(ty::node_id_to_type(v.tcx, id)).sty { ty::ty_bare_fn(*) | ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => { false @@ -125,26 +122,25 @@ fn stack_check_fn<'a>(v: StackCheckVisitor, } } }; - let new_cx = Context {safe_stack: safe_stack, ..in_cx}; + let new_cx = Context {safe_stack: safe_stack}; debug!("stack_check_fn(safe_stack=%b, id=%?)", safe_stack, id); - let mut v = v; - visit::walk_fn(&mut v, fk, decl, body, sp, id, new_cx); + visit::walk_fn(v, fk, decl, body, sp, id, new_cx); } -fn stack_check_expr<'a>(v: StackCheckVisitor, +fn stack_check_expr<'a>(v: &mut StackCheckVisitor, expr: @ast::Expr, cx: Context) { debug!("stack_check_expr(safe_stack=%b, expr=%s)", - cx.safe_stack, expr.repr(cx.tcx)); + cx.safe_stack, expr.repr(v.tcx)); if !cx.safe_stack { match expr.node { ast::ExprCall(callee, _, _) => { - let callee_ty = ty::expr_ty(cx.tcx, callee); - debug!("callee_ty=%s", callee_ty.repr(cx.tcx)); + let callee_ty = ty::expr_ty(v.tcx, callee); + debug!("callee_ty=%s", callee_ty.repr(v.tcx)); match ty::get(callee_ty).sty { ty::ty_bare_fn(ref fty) => { if !fty.abis.is_rust() && !fty.abis.is_intrinsic() { - call_to_extern_fn(cx, callee); + call_to_extern_fn(v, callee); } } _ => {} @@ -153,18 +149,17 @@ fn stack_check_expr<'a>(v: StackCheckVisitor, _ => {} } } - let mut v = v; - visit::walk_expr(&mut v, expr, cx); + visit::walk_expr(v, expr, cx); } -fn call_to_extern_fn(cx: Context, callee: @ast::Expr) { +fn call_to_extern_fn(v: &mut StackCheckVisitor, callee: @ast::Expr) { // Permit direct calls to extern fns that are annotated with // #[rust_stack]. This is naturally a horrible pain to achieve. match callee.node { ast::ExprPath(*) => { - match cx.tcx.def_map.find(&callee.id) { + match v.tcx.def_map.find(&callee.id) { Some(&ast::DefFn(id, _)) if id.crate == ast::LOCAL_CRATE => { - match cx.tcx.items.find(&id.node) { + match v.tcx.items.find(&id.node) { Some(&ast_map::node_foreign_item(item, _, _, _)) => { if attr::contains_name(item.attrs, "rust_stack") { return; @@ -179,7 +174,7 @@ fn call_to_extern_fn(cx: Context, callee: @ast::Expr) { _ => {} } - cx.tcx.sess.add_lint(lint::cstack, + v.tcx.sess.add_lint(lint::cstack, callee.id, callee.span, fmt!("invoking non-Rust fn in fn without \ diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 41126128cddf8..3095aa0753316 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2194,11 +2194,13 @@ pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def, } } -pub struct TransItemVisitor; +pub struct TransItemVisitor { + ccx: @mut CrateContext, +} -impl Visitor<@mut CrateContext> for TransItemVisitor { - fn visit_item(&mut self, i: @ast::item, ccx: @mut CrateContext) { - trans_item(ccx, i); +impl Visitor<()> for TransItemVisitor { + fn visit_item(&mut self, i: @ast::item, _:()) { + trans_item(self.ccx, i); } } @@ -2235,8 +2237,8 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { } else { // Be sure to travel more than just one layer deep to catch nested // items in blocks and such. - let mut v = TransItemVisitor; - v.visit_block(body, ccx); + let mut v = TransItemVisitor{ ccx: ccx }; + v.visit_block(body, ()); } } ast::item_impl(ref generics, _, _, ref ms) => { @@ -2288,8 +2290,8 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { // functions, but the trait still needs to be walked. Otherwise default // methods with items will not get translated and will cause ICE's when // metadata time comes around. - let mut v = TransItemVisitor; - visit::walk_item(&mut v, item, ccx); + let mut v = TransItemVisitor{ ccx: ccx }; + visit::walk_item(&mut v, item, ()); } _ => {/* fall through */ } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 54c905a4c1651..a327b2e193939 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -570,18 +570,20 @@ pub fn trans_lang_call_with_type_params(bcx: @mut Block, } -struct CalleeTranslationVisitor; +struct CalleeTranslationVisitor { + flag: bool, +} -impl Visitor<@mut bool> for CalleeTranslationVisitor { +impl Visitor<()> for CalleeTranslationVisitor { - fn visit_item(&mut self, _:@ast::item, _:@mut bool) { } + fn visit_item(&mut self, _:@ast::item, _:()) { } - fn visit_expr(&mut self, e:@ast::Expr, cx:@mut bool) { + fn visit_expr(&mut self, e:@ast::Expr, _:()) { - if !*cx { + if !self.flag { match e.node { - ast::ExprRet(_) => *cx = true, - _ => visit::walk_expr(self, e, cx), + ast::ExprRet(_) => self.flag = true, + _ => visit::walk_expr(self, e, ()), } } } @@ -589,10 +591,9 @@ impl Visitor<@mut bool> for CalleeTranslationVisitor { } pub fn body_contains_ret(body: &ast::Block) -> bool { - let cx = @mut false; - let mut v = CalleeTranslationVisitor; - visit::walk_block(&mut v, body, cx); - *cx + let mut v = CalleeTranslationVisitor{ flag: false }; + visit::walk_block(&mut v, body, ()); + v.flag } pub fn trans_call_inner(in_cx: @mut Block, diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 934dfabbb4de4..fd35d05f0fde7 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -61,9 +61,9 @@ pub fn trans_impl(ccx: @mut CrateContext, // Both here and below with generic methods, be sure to recurse and look for // items that we need to translate. if !generics.ty_params.is_empty() { - let mut v = TransItemVisitor; + let mut v = TransItemVisitor{ ccx: ccx }; for method in methods.iter() { - visit::walk_method_helper(&mut v, *method, ccx); + visit::walk_method_helper(&mut v, *method, ()); } return; } @@ -80,8 +80,8 @@ pub fn trans_impl(ccx: @mut CrateContext, None, llfn); } else { - let mut v = TransItemVisitor; - visit::walk_method_helper(&mut v, *method, ccx); + let mut v = TransItemVisitor{ ccx: ccx }; + visit::walk_method_helper(&mut v, *method, ()); } } } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 1cccca9630811..6ae196226d575 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -81,7 +81,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: DefId, n_tps: uint) // Conservatively assume full use for recursive loops ccx.type_use_cache.insert(fn_id, @vec::from_elem(n_tps, use_all)); - let cx = Context { + let mut cx = Context { ccx: ccx, uses: @mut vec::from_elem(n_tps, 0u) }; @@ -112,7 +112,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: DefId, n_tps: uint) ast_map::node_item(@ast::item { node: item_fn(_, _, _, _, ref body), _ }, _) | ast_map::node_method(@ast::method {body: ref body, _}, _, _) => { - handle_body(&cx, body); + handle_body(&mut cx, body); } ast_map::node_trait_method(*) => { // This will be a static trait method. For now, we just assume @@ -414,39 +414,36 @@ pub fn mark_for_expr(cx: &Context, e: &Expr) { } } -struct TypeUseVisitor; +impl Visitor<()> for Context { -impl<'self> Visitor<&'self Context> for TypeUseVisitor { - - fn visit_expr<'a>(&mut self, e:@Expr, cx: &'a Context) { - visit::walk_expr(self, e, cx); - mark_for_expr(cx, e); + fn visit_expr(&mut self, e:@Expr, _: ()) { + visit::walk_expr(self, e, ()); + mark_for_expr(self, e); } - fn visit_local<'a>(&mut self, l:@Local, cx: &'a Context) { - visit::walk_local(self, l, cx); - node_type_needs(cx, use_repr, l.id); + fn visit_local(&mut self, l:@Local, _:()) { + visit::walk_local(self, l, ()); + node_type_needs(self, use_repr, l.id); } - fn visit_pat<'a>(&mut self, p:@Pat, cx: &'a Context) { - visit::walk_pat(self, p, cx); - node_type_needs(cx, use_repr, p.id); + fn visit_pat(&mut self, p:@Pat, _: ()) { + visit::walk_pat(self, p, ()); + node_type_needs(self, use_repr, p.id); } - fn visit_block<'a>(&mut self, b:&Block, cx: &'a Context) { - visit::walk_block(self, b, cx); + fn visit_block(&mut self, b:&Block, _: ()) { + visit::walk_block(self, b, ()); for e in b.expr.iter() { - node_type_needs(cx, use_repr, e.id); + node_type_needs(self, use_repr, e.id); } } - fn visit_item<'a>(&mut self, _:@item, _: &'a Context) { + fn visit_item(&mut self, _:@item, _: ()) { // do nothing } } -pub fn handle_body(cx: &Context, body: &Block) { - let mut v = TypeUseVisitor; - v.visit_block(body, cx); +pub fn handle_body(cx: &mut Context, body: &Block) { + cx.visit_block(body, ()); } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 8337354724a44..eeef2b798e20a 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -61,17 +61,18 @@ pub fn field_exprs(fields: ~[ast::Field]) -> ~[@ast::Expr] { } struct LoopQueryVisitor<'self> { - p: &'self fn(&ast::Expr_) -> bool + p: &'self fn(&ast::Expr_) -> bool, + flag: bool, } -impl<'self> Visitor<@mut bool> for LoopQueryVisitor<'self> { - fn visit_expr(&mut self, e: @ast::Expr, flag: @mut bool) { - *flag |= (self.p)(&e.node); +impl<'self> Visitor<()> for LoopQueryVisitor<'self> { + fn visit_expr(&mut self, e: @ast::Expr, _: ()) { + self.flag |= (self.p)(&e.node); match e.node { // Skip inner loops, since a break in the inner loop isn't a // break inside the outer loop ast::ExprLoop(*) | ast::ExprWhile(*) => {} - _ => visit::walk_expr(self, e, flag) + _ => visit::walk_expr(self, e, ()) } } } @@ -79,34 +80,35 @@ impl<'self> Visitor<@mut bool> for LoopQueryVisitor<'self> { // Takes a predicate p, returns true iff p is true for any subexpressions // of b -- skipping any inner loops (loop, while, loop_body) pub fn loop_query(b: &ast::Block, p: &fn(&ast::Expr_) -> bool) -> bool { - let rs = @mut false; let mut v = LoopQueryVisitor { p: p, + flag: false, }; - visit::walk_block(&mut v, b, rs); - return *rs; + visit::walk_block(&mut v, b, ()); + return v.flag; } struct BlockQueryVisitor<'self> { - p: &'self fn(@ast::Expr) -> bool + p: &'self fn(@ast::Expr) -> bool, + flag: bool, } -impl<'self> Visitor<@mut bool> for BlockQueryVisitor<'self> { - fn visit_expr(&mut self, e: @ast::Expr, flag: @mut bool) { - *flag |= (self.p)(e); - visit::walk_expr(self, e, flag) +impl<'self> Visitor<()> for BlockQueryVisitor<'self> { + fn visit_expr(&mut self, e: @ast::Expr, _:()) { + self.flag |= (self.p)(e); + visit::walk_expr(self, e, ()) } } // Takes a predicate p, returns true iff p is true for any subexpressions // of b -- skipping any inner loops (loop, while, loop_body) pub fn block_query(b: &ast::Block, p: &fn(@ast::Expr) -> bool) -> bool { - let rs = @mut false; let mut v = BlockQueryVisitor { p: p, + flag: false, }; - visit::walk_block(&mut v, b, rs); - return *rs; + visit::walk_block(&mut v, b, ()); + return v.flag; } pub fn local_rhs_span(l: @ast::Local, def: Span) -> Span {