Variable scoping in macros: Deprecated syntax `implicit assignment to global variable`

I’m running into a deprecation when running the test/perf/micro benchmarks in 0.7-DEV. The issue is implicit declaration and assignment of global variables in the @timeit macro in test/perf/perfutils.jl. Here it is boiled down to a minimal working example:

ulia> macro timeit(ex)
           quote
               t = Float64[]  # no problem!
               tot = 0.0      # deprecated! 
               i = 0          # deprecated! 
               while i < 5 || tot < 0.0001
                   e = 1000*(@elapsed $(esc(ex)))
                   tot += e
                   if i > 0
                       # warm up on first iteration
                       push!(t, e)
                   end
                   i += 1
               end
               @show tot, t
           end
       end
@timeit (macro with 1 method)

julia> expression = Meta.parse("x=2; y=3; x+y")
:($(Expr(:toplevel, :(x = 2), :(y = 3), :(x + y))))

julia> @timeit(expression)
┌ Warning: Deprecated syntax `implicit assignment to global variable `#2#tot``.
│ Use `global #2#tot` instead.
└ @ nothing none:0
┌ Warning: Deprecated syntax `implicit assignment to global variable `#3#i``.
│ Use `global #3#i` instead.
└ @ nothing none:0
(tot, t) = (0.00020499999999999997, [1.6e-5, 6.3e-5, 2.1e-5, 2.0e-5])
(0.00020499999999999997, [1.6e-5, 6.3e-5, 2.1e-5, 2.0e-5])

julia> versioninfo()
Julia Version 0.7.0-DEV.3234
Commit 2cc82d29e1* (2018-01-02 11:44 UTC)
Platform Info:
  OS: Linux (x86_64-suse-linux)
  CPU: Intel(R) Core(TM) i7-3960X CPU @ 3.30GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, sandybridge)
Environment:

Is there a good way to force a local scope inside the macro in order to suppress the warning? Or should this be accomplished by turning the macro into a function? Or is a macro necessary to avoid overhead in timing the evaluating the expression?

Any help appreciated.

How about wrapping everything in a let block e.g.

quote
    let
        ...
    end
end

Ideally, the perf benchmarks should just be rewritten to use BenchmarkTools though.

That does the job. Thank you. (I’d tried begin ... end and C-style enclosing braces. Still learning Julia basics…)

About updating to BenchmarkTools, should I take that as an order? :slight_smile: I wasn’t sure if the non-use of BenchmarkTools was just historical, or if it was to maximize transparency and similarity to timing algorithms in other languages.