                         n.ejs_env.closed.map (sym) ->
                                 new_mapping[sym] = create_intrinsic "slot", [ (create_identifier env_name), (create_number_literal n.ejs_env.slot_mapping[sym]), (create_string_literal sym) ]
 
-                        @mappings.push new_mapping
-                        @visitFunctionBody n
+                # remove all mappings for variables declared in this function
+                if n.ejs_decls?
+                        new_mapping = reject new_mapping, (sym) -> (n.ejs_decls.has sym) and not (n.ejs_env.closed.has sym)
+
+                @mappings.push new_mapping
+                @visitFunctionBody n
+                if prepends?
                         n.body.body = prepends.concat n.body.body
-                        @mappings.pop()
+                @mappings.pop()
 
                 # convert function expressions to an explicit closure creation, so:
                 # 

                        return create_intrinsic "builtinUndefined", []
                n

class InlineSomeIIFEs extends TreeTransformer

        constructor: ->
                @function_stack = new Stack
                @iife_generator = startGenerator()

        visitFunction: (n) ->
                @function_stack.push n
                rv = super
                @function_stack.pop
                rv
                
        visitExpressionStatement: (n) ->
                # bail out early if we know we aren't in the right place
                if is_intrinsic "invokeClosure", n.expression
                        candidate = n.expression
                else if is_intrinsic "setSlot", n.expression
                        candidate = n.expression.arguments[2]
                else if (is_intrinsic "setGlobal", n.expression) or (is_intrinsic "setLocal", n.expression)
                        candidate = n.expression.arguments[1]
                else
                        return n

                return n if not is_intrinsic "invokeClosure", candidate
                return n if not (is_intrinsic "makeClosure", candidate.arguments[0]) and not (is_intrinsic "makeAnonClosure", candidate.arguments[0])

                arity = candidate.arguments[0].arguments[1].params.length
                arg_count = candidate.arguments.length - 1 # %invokeClosure's first arg is the callee

                console.warn "arity = #{arity}.  arg_count = #{arg_count}"

                return n if arg_count > arity

                # at this point we know we have a zero arg IIFE in an expression statement, ala:
                #
                # (function(x, ...) { ...body...})(y, ...);
                #

                                exp.ejs_decls = decls
                                exp.ejs_free_vars = uses.subtract decls
                        when syntax.FunctionDeclaration
                                # this should only happen for the toplevel function we create to wrap the source file
                                param_names = @param_names exp.params
                                param_names.add exp.rest.name if exp.rest?
                                exp.ejs_free_vars = (@free exp.body).subtract param_names
