The bug is not in `case` but is a result of calling `with-symbol-macros` on it.
Normally `case` expands to use a `sorted-map` for the lookup of case values when you have a compact set of test values (as opposed to a sparse set). You can see that here:
user=> (macroexpand '(case \a (\0 \1 \2 \3 \4 \5 \6 \7 \8) true false))
(let* [G__873 \a] (case* G__873 0 0 false {48 [\0 true], 49 [\1 true], 50 [\2 true], 51 [\3 true], 52 [\4 true], 53 [\5 true], 54 [\6 true], 55 [\7 true], 56 [\8 true]} :compact :hash-equiv nil))
Here, the keys are in order and so the compiler can create an array to hold the values based on (56-48)+1 as the length.
Based on my reading of the clojure.tools.macro source, `with-symbol-macros` forces the expansion and recursively goes into the map and reconstructs it as a regular (unsorted) map as can be seen here:
user=> (macroexpand '(clojure.tools.macro/with-symbol-macros (case \a (\0 \1 \2 \3 \4 \5 \6 \7 \8) true false)))
(do (let* [G__865 \a] (case* G__865 0 0 false {55 [\7 true], 54 [\6 true], 48 [\0 true], 50 [\2 true], 56 [\8 true], 51 [\3 true], 53 [\5 true], 52 [\4 true], 49 [\1 true]} :compact :hash-equiv nil)))
When confronted with this, the compiler attempts to calculate (49-55)+1 and gets the exception you saw.
I believe that the fix - to clojure.tools.macro - would be to add special treatment for the `case*` form:
Although it sounds like you have a reasonable workaround?
Sean