Simple reader macro turns compiler warnings into errors

Bug #1879535 reported by Anish Moorthy
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Undecided
Unassigned

Bug Description

Brief
-------------------------------------------------------
Once a certain reader macro has been defined, unused variable warnings from file compilation where said reader macro is used turn into errors. These errors appear (incorrectly) to originate from the reader macro itself.

Detailed Description & Tests
-------------------------------------------------------
In a fresh image, we eval the following block to define a reader macro on "[". Its objective is to turn expressions of the sort "[ls index]" --> "(elt ls index)", though that shouldn't be important.

```
(defun bracketed-access (stream char)
  (declare (ignore char))
  (destructuring-bind (place i0 &rest indices) (read-delimited-list #\] stream t)
    (when indices (error "bracketed-access ignores the &rest indices argument but is passed here"))
    `(elt ,place ,i0)))

(set-macro-character #\[ #'bracketed-access)
(set-syntax-from-char #\] #\))
```

However, this confuses file compilation somehow. This file will compile without any issues, and produces the correct output when evaluated

```
;; let1.lisp
(let ()
  ['(a b c) 2])
```

However, file compilation of this one gives errors

```
;; let2.lisp
(let (a)
  ['(a b c) 2])
```

The error (end of this section) is only thrown when using `sly-compile-file` & `sly-compile-and-load-file` (or, as phoe helped me confirm on discord, their slime counterparts). Compilation of the `let` using the `compile-region` or `compile-defun` functions works fine.

The only difference between `let1` and `let2` should be that the second generates an unused variable warning. In fact, inserting a `(declare (ignore a))` in `let2` will allow file compilation without issue.

Below is the error generated by file compilation. Somehow, the message is flatly incorrect.

```
error while parsing arguments to DESTRUCTURING-BIND:
  too few elements in
    ()
  to satisfy lambda list
    (PLACE I0 &REST INDICES):
  at least 2 expected, but got 0
   [Condition of type SB-KERNEL::ARG-COUNT-ERROR]

Restarts:
 0: [MUFFLE-WARNING] Skip warning.
 1: [ABORT] Abort compilation.
 2: [*ABORT] Return to SLY's top level.
 3: [ABORT] abort thread (#<THREAD "slynk-worker" RUNNING {1003246663}>)

Backtrace:
 0: (SB-C::COMPILER-STYLE-WARNING-HANDLER #<SB-INT:SIMPLE-STYLE-WARNING "The variable ~S is defined but never used." {1003277BC3}>)
 <I've deleted the rest of the backtrace>
```

-------------------------------------------------------

System information

SBCL Version: SBCL 1.4.5.debian
System Info: Linux pop-os 5.3.0-7642-generic #34~1584407623~18.04~36777b2-Ubuntu SMP Tue Mar 17 03:29:38 UTC x86_64 x86_64 x86_64 GNU/Linux
`*features*`:
```
(:SLYNK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3
 :ASDF2 :ASDF :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :64-BIT
 :64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS
 :C-STACK-IS-CONTROL-STACK :CALL-SYMBOL :COMMON-LISP :COMPACT-INSTANCE-HEADER
 :COMPARE-AND-SWAP-VOPS :COMPLEX-FLOAT-VOPS :CYCLE-COUNTER :ELF :FLOAT-EQL-VOPS
 :FP-AND-PC-STANDARD-SAVE :GCC-TLS :GENCGC :IEEE-FLOATING-POINT :IMMOBILE-CODE
 :IMMOBILE-SPACE :INLINE-CONSTANTS :INTEGER-EQL-VOP :LARGEFILE :LINKAGE-TABLE
 :LINUX :LITTLE-ENDIAN :MEMORY-BARRIER-VOPS :MULTIPLY-HIGH-VOPS
 :OS-PROVIDES-BLKSIZE-T :OS-PROVIDES-DLADDR :OS-PROVIDES-DLOPEN
 :OS-PROVIDES-GETPROTOBY-R :OS-PROVIDES-POLL :OS-PROVIDES-PUTWC
 :OS-PROVIDES-SUSECONDS-T :PACKAGE-LOCAL-NICKNAMES :RAW-INSTANCE-INIT-VOPS
 :RAW-SIGNED-WORD :RELOCATABLE-HEAP :SB-AFTER-XC-CORE :SB-CORE-COMPRESSION
 :SB-DOC :SB-EVAL :SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK
 :SB-SOURCE-LOCATIONS :SB-THREAD :SB-UNICODE :SB-XREF-FOR-INTERNALS :SBCL
 :STACK-ALLOCATABLE-CLOSURES :STACK-ALLOCATABLE-FIXED-OBJECTS
 :STACK-ALLOCATABLE-LISTS :STACK-ALLOCATABLE-VECTORS
 :STACK-GROWS-DOWNWARD-NOT-UPWARD :SYMBOL-INFO-VOPS :UNBIND-N-VOP
 :UNDEFINED-FUN-RESTARTS :UNIX :UNWIND-TO-FRAME-AND-CALL-VOP :X86-64)
```

Revision history for this message
Jan Moringen (scymtym) wrote :

This looks comes form an interaction between the custom reader macro and SLIME/SLY. The interesting part of the complete backtrace is:

Error while parsing arguments to DESTRUCTURING-BIND:
  too few elements in
    ()
  to satisfy lambda list
    (PLACE I0 &REST INDICES):
  at least 2 expected, but got 0
   [Condition of type SB-KERNEL::ARG-COUNT-ERROR]

Restarts:
 0: [MUFFLE-WARNING] Skip warning.
 1: [ABORT] Abort compilation.
 2: [*ABORT] Return to SLIME's top level.
 3: [ABORT] abort thread (#<THREAD "worker" RUNNING {100DD63093}>)

Backtrace:
  0: (SB-C::CHECK-DS-LIST/&REST #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument>)
  1: (BRACKETED-ACCESS #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #<unused argument>)
  2: (SB-IMPL::READ-MAYBE-NOTHING #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #\[)
  3: (SB-IMPL::READ-LIST #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #<unused argument>)
  4: (SB-IMPL::READ-MAYBE-NOTHING #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #\()
  5: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> T (NIL) T)
  6: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> T (NIL) NIL)
  7: (READ #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> T NIL NIL)
  8: (SWANK/SOURCE-PATH-PARSER::SKIP-TOPLEVEL-FORMS 1 #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}>)
  9: (SWANK/SOURCE-PATH-PARSER:SOURCE-PATH-FILE-POSITION (0) #P"/tmp/let1.lisp")
 10: (SWANK/SBCL::LOCATE-COMPILER-NOTE #P"/tmp/let1.lisp" (0) " (LET (A) ..)
 11: (SWANK/SBCL::COMPILER-NOTE-LOCATION #<SB-INT:SIMPLE-STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}> #<SB-C::COMPILER-ERROR-CONTEXT >)
 12: (SWANK/SBCL::SIGNAL-COMPILER-CONDITION #<SB-INT:SIMPLE-STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}> #<SB-C::COMPILER-ERROR-CONTEXT >)
 13: (SB-KERNEL::%SIGNAL #<SB-INT:SIMPLE-STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}>)
 14: (SB-C::COMPILER-STYLE-WARNING-HANDLER #<SB-INT:SIMPLE-STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}>)
 15: (SB-KERNEL::%SIGNAL #<SB-INT:SIMPLE-STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}>)
 16: ((FLET SB-KERNEL::%WARN :IN "SYS:SRC;CODE;WARM-ERROR.LISP") "The variable ~S is defined but never used." #<SB-KERNEL::CONDITION-CLASSOID STYLE-WARNING> SB-INT:SIMPLE-STYLE-WARNING A)
 17: (SB-C:COMPILER-STYLE-WARN "The variable ~S is defined but never used." A)
 18: (SB-C::NOTE-UNREFERENCED-VARS (#<SB-C::LAMBDA-VAR :%SOURCE-NAME A {100DDAECA3}>) #<SB-KERNEL:BIND :LAMBDA #<SB-C::CLAMBDA :%SOURCE-NAME SB-C::.ANONYMOUS. :%DEBUG-NAME (LET #) :KIND :LET :TYPE #<SB-KER..
...

So the compiler signals a style-warning which SLIME handles by invoking its source parser which intern calls the reader macro. The reader macro then signals an error presumably it was invoked at a position in the input that does not have the expected form.

Revision history for this message
Jan Moringen (scymtym) wrote :

I can't find a way to edit my comment. I wanted to correct "This looks comes form" -> "This seem to come from" and "which intern calls" -> "which in turn" and "presumably it was" -> "presumably because it was".

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.