Clojure

Recur mismatch causes infinite loop in compiler

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: Release 1.3
  • Fix Version/s: Release 1.3
  • Component/s: None
  • Labels:
    None
  • Approval:
    Ok

Description

In cases like

(set! warn-on-reflection true)

(defn gcd [x y]
(loop [x (long x) y (long y)]
(if (== y 0)
x
(recur y (rem x y)))))

I'd expect either both x and y to be auto-boxed or an error from the primitive local mismatch.
Instead the compiler (1.3.0-alpha2) goes into an infinite loop in LetExpr.Parser.parse():

NO_SOURCE_FILE:3 recur arg for primitive local: y is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: y
NO_SOURCE_FILE:3 recur arg for primitive local: x is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: x
NO_SOURCE_FILE:3 recur arg for primitive local: y is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: y
NO_SOURCE_FILE:3 recur arg for primitive local: x is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: x
.
.
.

The previous case has been fixed as described in the comments. The defect can still be seen this way:

(set! warn-on-reflection true)

(defn gcd [x y]
(loop [x (long x) y (long y)]
(if (== y 0)
x
(recur y ^Long(rem x y)))))

Activity

Hide
Juha Arpiainen added a comment -

Attached patch (CA is now in mail).

With this patch the loop body will be analyzed n times in cases like

(loop [v1 0 v2 0 v3 0 vn 0]
(recur v2 v3 vn (identity vn)))

Show
Juha Arpiainen added a comment - Attached patch (CA is now in mail). With this patch the loop body will be analyzed n times in cases like (loop [v1 0 v2 0 v3 0 vn 0] (recur v2 v3 vn (identity vn)))
Hide
Stuart Halloway added a comment -

The long casts are not necessary here, but if they are present, they appear to cause an infinite loop regardless of whether warn-on-reflection is set.

Show
Stuart Halloway added a comment - The long casts are not necessary here, but if they are present, they appear to cause an infinite loop regardless of whether warn-on-reflection is set.
Hide
Alexander Taggart added a comment -

Test case no longer results in erroneous behaviour using current master branch.

Show
Alexander Taggart added a comment - Test case no longer results in erroneous behaviour using current master branch.
Hide
Christopher Redinger added a comment -

Confirmed that this is no longer an issue on alpha-6

Show
Christopher Redinger added a comment - Confirmed that this is no longer an issue on alpha-6
Hide
Juha Arpiainen added a comment -

Test case works because of improved type inference for #'rem. Changing (rem x y) to ^Long (rem x y) in test case still causes the loop in f0a46155ba3...

Show
Juha Arpiainen added a comment - Test case works because of improved type inference for #'rem. Changing (rem x y) to ^Long (rem x y) in test case still causes the loop in f0a46155ba3...
Hide
Christopher Redinger added a comment -

Updating test case to show present day failure

Show
Christopher Redinger added a comment - Updating test case to show present day failure
Hide
Christopher Redinger added a comment -

Jahu is resending a CA, we did not receive the first one.

Show
Christopher Redinger added a comment - Jahu is resending a CA, we did not receive the first one.
Hide
Fogus added a comment -

Added regression for this patch. Waiting on CA for final approval.

Show
Fogus added a comment - Added regression for this patch. Waiting on CA for final approval.
Hide
Christopher Redinger added a comment -

We've received the CA. This patch is ready to go.

Show
Christopher Redinger added a comment - We've received the CA. This patch is ready to go.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: