IGNORE and IGNORABLE are not recognized as free declarations

Bug #736345 reported by Jean-Philippe Paradis
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Incomplete
Undecided
Unassigned

Bug Description

[edit: I had forgotten to actually use LIST-STRUCTURE inside FOO but outside the DESTRUCTURING-BIND, which defeated the whole point of the example o_o]

What I do:
(defun foo (list-structure)
  (print list-structure) ; use foo, one way or another
  (destructuring-bind (some pattern here) list-structure
    (declare (ignore list-structure)) ; for better readability
    'big-body-never-using-list-structure
    (values some pattern here)))

What happens:
SBCL says: "caught STYLE-WARNING: declaring unknown variable LIST-STRUCTURE to be ignored". It also doesn't complain about reading an ignored variable if I actually use LIST-STRUCTURE in scope of the declaration.

It seems that SBCL treats IGNORE and IGNORABLE as a "bound-only" declaration.

What I expected to happen:
If I understand correctly, IGNORE and IGNORABLE should be acceptable as free declarations further down than where the variable or function was introduced, and indicates that the variable or function won't be or might not be used within its scope, respectively.

I note that the CLHS page for IGNORE and IGNORABLE makes no mention at all of whether these are bound declarations or free declarations, which is troubling because there's at least one explicit mention in that regard for every other declaration on their respective pages. Seems like a bug in the spec to me.

Here's a workaround, but introducing an additional level of indentation for this is a little ridiculous IMHO, especially since the whole point is to make the big-body-never-using-list-structure more readable by assuring the reader that we're definitely not accessing LIST-STRUCTURE:

(defun foo (list-structure)
  (print foo)
  (destructuring-bind (some pattern here) list-structure
    (let ((list-structure list-structure))
      (declare (ignore list-structure))
      'some-big-body-never-using-list-structure
      (values some pattern here))))

SBCL version: 1.0.42
uname -a: Linux dynamorph 2.6.32-29-generic #58-Ubuntu SMP Fri Feb 11 19:00:09 UTC 2011 i686 GNU/Linux

*features*:
(:SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF2 :ASDF :ANSI-CL :COMMON-LISP
 :SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL
 :SB-SOURCE-LOCATIONS :IEEE-FLOATING-POINT :X86 :UNIX :ELF :LINUX :SB-THREAD
 :LARGEFILE :GENCGC :STACK-GROWS-DOWNWARD-NOT-UPWARD :C-STACK-IS-CONTROL-STACK
 :COMPARE-AND-SWAP-VOPS :UNWIND-TO-FRAME-AND-CALL-VOP :RAW-INSTANCE-INIT-VOPS
 :STACK-ALLOCATABLE-CLOSURES :STACK-ALLOCATABLE-VECTORS
 :STACK-ALLOCATABLE-LISTS :STACK-ALLOCATABLE-FIXED-OBJECTS :ALIEN-CALLBACKS
 :CYCLE-COUNTER :INLINE-CONSTANTS :MEMORY-BARRIER-VOPS :LINKAGE-TABLE
 :OS-PROVIDES-DLOPEN :OS-PROVIDES-PUTWC :OS-PROVIDES-SUSECONDS-T)

description: updated
Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

I haven't checked the spec just now, but I'm pretty sure IGNORE and IGNORABLE are indeed valid only as bound declarations -- in SBCL this is currently intentional, not an accident.

If you can point out language in the spec that requires silently accepting IGNORE and IGNORABLE for bindings established in an outer scope, please do so -- because absent that I don't see any reason to change this. In the typical use case this warning is exactly right and preferable, since it _is_ in the wrong scope.

All that said, I do think the message could be improved. Logged bug 736383 about that.

Changed in sbcl:
status: New → Incomplete
Revision history for this message
Jean-Philippe Paradis (hexstream) wrote :

After reading the spec page for IGNORE/IGNORABLE yet again, I'm pretty sure that IGNORE/IGNORABLE were not meant to be bound-only declarations, though it might well be that it's the case in most or all implementations (I haven't checked).

The spec doesn't specify this explicitly and I wish it did, but absent that, I think the spec strongly hints at the behavior I'm wishing for. Here are two quotes from the IGNORE/IGNORABLE spec page (they're one after the other):

Exhibit 1:

"The ignore and ignorable declarations refer to for-value references to variable bindings for the vars and to function bindings for the fns."

Exhibit 2:

"An ignore declaration specifies that for-value references to the indicated bindings will not occur within the scope of the declaration."

First of all, notice how it's said in both places that this affects *for-value references*, not the variable bindings themselves. To me this indicates that IGNORE/IGNORABLE are free declarations, not bound declarations. The IGNORE declaration is saying "There will be no for-value references to this binding within my scope.", not "This binding will not be referenced from anywhere".

This situation is similar to a TYPE declaration referring to a variable of an enclosing scope, where only for-value references are affected, not the binding itself.

Second, within Exhibit 2, notice that it's said that for-value references to the indicated bindings will not occur *within the scope of the declaration*. Why would this last bit be mentioned at all if it was the case that IGNORE/IGNORABLE declarations are bound-only and only ever affect bindings introduced by the form carrying these declarations??

----

By the way, I still think that the following should get a STYLE-WARNING, despite the apparent status of these declarations as free declarations:

(let* ((x 8)
       (y x))
  (declare (ignore x))
  y)

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.