     body          = Expressions.wrap([@body])
     idt1          = @idt 1
     if range
-      sourcePart  = source.compileVariables(o)
       forPart     = source.compile merge o, index: ivar, step: @step
     else
-      [sourcePart, svar] = @source.compileReference merge(o, top: yes), precompile: yes
-      sourcePart = if sourcePart is svar then '' else "#{sourcePart};"
+      svar = @source.compile o
+      if IDENTIFIER.test(svar) and scope.check(svar, immediate: on)
+        sourcePart = svar
+      else
+        sourcePart = "#{ref = scope.freeVariable 'ref'} = #{svar}"
+        sourcePart = "(#{sourcePart})" unless @object
+        svar = ref
       namePart = if @pattern
         new Assign(@name, literal "#{svar}[#{ivar}]").compile merge o, top: on
       else if name

    parts = []
    parts.push @from if @from isnt @fromVar
    parts.push @to if @to isnt @toVar
    if parts.length then "#{parts.join('; ')}; " else ''

  # When compiled normally, the range returns the contents of the *for loop*
  # needed to iterate over the values in the range. Used by comprehensions.
  compileNode: (o) ->
    return    @compileArray(o)  unless o.index
    return    @compileSimple(o) if @fromNum and @toNum
    idx      = del o, 'index'
    step     = del o, 'step'
    vars     = "#{idx} = #{@fromVar}"
    intro    = "(#{@fromVar} <= #{@toVar} ? #{idx}"
    compare  = "#{intro} <#{@equals} #{@toVar} : #{idx} >#{@equals} #{@toVar})"
    stepPart = if step then step.compile(o) else '1'

      unless @object
        lvar      = scope.freeVariable 'len'
        stepPart  = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++"
        forPart   = "#{ivar} = 0, #{lvar} = #{sourcePart}.length; #{ivar} < #{lvar}; #{stepPart}"
    resultPart    = if rvar then "#{@tab}#{rvar} = [];\n" else ''
    returnResult  = @compileReturnValue(rvar, o)
    body          = Push.wrap(rvar, body) unless topLevel
    if @guard
