Ticket #1049 (closed defect: fixed)

Opened 2 years ago

Last modified 2 years ago

Bug in construct-setf-function-name

Reported by: fare Owned by:
Priority: normal Milestone:
Component: Compiler Version: trunk
Keywords: Cc:

Description

In level-1/l1-aprims.lisp, construct-setf-function-name should also test for #\" in the package-name, or it will confuse packages named ":" and "\":\"".

Change History

comment:1 Changed 2 years ago by fare

Also, the prin1-to-string should be wrapped in with-standard-io-syntax.

Now, if you're going to use with-standard-io-syntax, you could simply use

(defun construct-setf-function-name (sym)
   (intern
    (with-standard-io-syntax
      (let ((*package* (find-package :common-lisp)))
         (prin1-to-string sym)))
    *setf-package*))

comment:2 Changed 2 years ago by fare

Also, in case a symbol is uninterned or rehomed, something special needs to be done to avoid issues with the mapping from symbol to setf symbol.

In these cases, there also seems to be a bug in the way FASLs assume that the mapping is to be done at runtime using the same that existed at compile-time.

comment:3 Changed 2 years ago by fare

Wonderful breakage scenario: 1- load an old asdf 2- compile the new asdf, complete with symbol rehoming. 3- CCL will store the setf function under the old name, but won't store the special mapping in the fasl. 4- quit, start a new image 5- load the fasl compiled by the old asdf with its old setf symbol mapping - the mapping is not stored in the fasl 6- weep and cry, as the setf functions were stored in the fasl under the old name, but the setf-mapper uses the new name and can't find it.

I suppose my workaround is that when I rehome a symbol, I should also rehome its setf function at the same time.

comment:4 Changed 2 years ago by gb

  • Status changed from new to closed
  • Resolution set to fixed

I think that there are a couple of bugs here.

CCL has historically used symbols in a private/internal package named SETF to represent SETF function names (function names of the form (SET X)). The function CCL::CONSTRUCT-SETF-FUNCTION-NAME has to create distinct "setf function names" for distinct symbols used as arguments and historically has tried to ensure uniqueness by deriving the pname of the SETF package symbol from the pname/package of the argument symbol. Since two or more symbols can (at various times in a lisp session) have the same pname/package, this can't work. (Paying attention to packages with #\: characters in their names or using a consistent set of print options to generate a pname for the SETF package symbol might avoid conflicts in some cases, but there's no set of immutable printable symbol attributes that's guaranteed to generate a unique SETF package symbol name from an argument symbol; this has to be done differently.)

Different people use different terms to refer to the same thing; it's possible that some people use the term "symbol rehoming" to refer to something that other people would refer to as "violations of package system consistency rules." I'm not sure if that's what's being discussed here, but ... once it's been generated, a SETF function name is just a symbol in a package named SETF, and such symbols are saved to/loaded from/referenced in FASL files just like other (interned) symbols. (Interned symbols are represented as something like (LOAD-TIME-VALUE (INTERN pname package)); SETF function names have to be treated as something like (LOAD-TIME-VALUE (%SETF-NAME-FOR x)), and you're right in noting that that's not always the same SETF-package symbol in the traditional CCL implementation.)

I changed how this works in the trunk; the changes are a little hard to bootstrap and the new way of handling SETF function names is incompatible with the old way (necessitating a change to FASL version.) It's not really practical to backport these changes to 1.8, but the plan is to get a 1.9 release out Real Soon Now.

Note: See TracTickets for help on using tickets.