with-redefs used on a macro permanently changes it to a function

Description

If you use with-redefs to redefine a macro (which is likely a mistake), the macro loses its macro status after the with-redefs call completes.

Presumably the fix depends on whether we think there is a valid use of with-redefs on a macro (which would only work if you're calling eval or equivalent in the body, and would require knowing enough about what you're doing to add the two extra macro args to your function) – if so, we would keep it from losing the macro status; if not, we might also have it throw an exception if you accidentally use it on a macro.

Demonstration of the effect:

Environment

None

Activity

Show:

gfredericksDecember 10, 2015 at 6:04 PM

Looks like the root cause is that with-redefs uses Var#bindRoot which intentionally clears the macro flag: https://github.com/clojure/clojure/blob/5cfe5111ccb5afec4f9c73b46bba29ecab6a5899/src/jvm/clojure/lang/Var.java#L270

Details

Assignee

Reporter

Approval

Triaged

Priority

Affects versions

Created December 10, 2015 at 5:58 PM
Updated December 10, 2015 at 7:26 PM