Comment 4 for bug 1053198

Revision history for this message
Christophe Rhodes (csr21-cantab) wrote : Re: [Bug 1053198] Re: PCL walker doesn't know that SYMBOL-MACROLET can be shadowed by rebindings

Christophe Rhodes <email address hidden> writes:

> I think the tagbody problem can be fairly straightforwardly fixed: the
> problem was the tagbody walker trying to handle symbols specially by
> passing a particular CONTEXT, but no other walker function inspecting
> the context in any way.

I think this is still correct: I suspect that what the original writer
was aiming for was (walk-template form 'quote context env) rather than
(walk-form-internal form 'quote env).

However. That thinkg about "no walker function inspecting CONTEXT"... I
have realised to my horror that this should not be true. Firstly, the
PCL walker and (since b3ccf16b40858c0147229cbe61e0d89e9bea9ff0)
macroexpand-all both check that they are walking something in :eval
context, so hooray. However, even after the tagbody change, either my
original one or one to go to walk-template, the basic walker is
vulnerable to confusion because as well as :eval context there is :set
context. We correctly expand symbol macros in :set context; however, we
incorrectly expand normal macros too:

  (let ((sb-walker:*walk-form-expand-macros-p* t))
    (sb-walker:walk-form '(macrolet ((x () 'y)) (setq (x) 3))))

(This is invisible to anything that uses our exported interfaces, which
only do anything if the context argument is :eval).

The problems with scoping of symbol-macrolets remain; here's another
one:

  (symbol-macrolet ((tag (slot-value x 'y)))
    (defmethod foo ((x z))
      (tagbody tag
        (print "here")
        (if (= tag 0) 'done (go tag)))))

The PCL walker correctly doesn't expand the tagbody/go tags, but also
doesn't expand the tag that *is* evaluated, so slot-value optimization
doesn't get performed -- variable-symbol-macro-p of TAG returns NIL.