Simple reader macro turns compiler warnings into errors
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))
(destructurin
(when indices (error "bracketed-access ignores the &rest indices argument but is passed here"))
`(elt ,place ,i0)))
(set-macro-
(set-syntax-
```
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-
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:
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::
<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~
`*features*`:
```
(:SLYNK :QUICKLISP :SB-BSD-
:ASDF2 :ASDF :OS-UNIX :NON-BASE-
:64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS
:C-STACK-
:COMPARE-
:FP-AND-
:IMMOBILE-SPACE :INLINE-CONSTANTS :INTEGER-EQL-VOP :LARGEFILE :LINKAGE-TABLE
:LINUX :LITTLE-ENDIAN :MEMORY-
:OS-PROVIDES-
:OS-PROVIDES-
:OS-PROVIDES-
:RAW-SIGNED-WORD :RELOCATABLE-HEAP :SB-AFTER-XC-CORE :SB-CORE-
:SB-DOC :SB-EVAL :SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK
:SB-SOURCE-
:STACK-
:STACK-
:STACK-
:UNDEFINED-
```
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: :ARG-COUNT- ERROR]
too few elements in
()
to satisfy lambda list
(PLACE I0 &REST INDICES):
at least 2 expected, but got 0
[Condition of type SB-KERNEL:
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: CHECK-DS- LIST/&REST #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument>) :READ-MAYBE- NOTHING #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #\[) :READ-MAYBE- NOTHING #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #\() :%READ- PRESERVING- WHITESPACE #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> T (NIL) T) :%READ- PRESERVING- WHITESPACE #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> T (NIL) NIL) SOURCE- PATH-PARSER: :SKIP-TOPLEVEL- FORMS 1 #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}>) SOURCE- PATH-PARSER: SOURCE- PATH-FILE- POSITION (0) #P"/tmp/let1.lisp") SBCL::LOCATE- COMPILER- NOTE #P"/tmp/let1.lisp" (0) " (LET (A) ..) SBCL::COMPILER- NOTE-LOCATION #<SB-INT: SIMPLE- STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}> #<SB-C: :COMPILER- ERROR-CONTEXT >) SBCL::SIGNAL- COMPILER- CONDITION #<SB-INT: SIMPLE- STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}> #<SB-C: :COMPILER- ERROR-CONTEXT >) SIMPLE- STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}>) COMPILER- STYLE-WARNING- HANDLER #<SB-INT: SIMPLE- STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}>) SIMPLE- STYLE-WARNING "The variable ~S is defined but never used." {100DDB2443}>) CODE;WARM- ERROR.LISP" ) "The variable ~S is defined but never used." #<SB-KERNEL: :CONDITION- CLASSOID STYLE-WARNING> SB-INT: SIMPLE- STYLE-WARNING A) STYLE-WARN "The variable ~S is defined but never used." A) NOTE-UNREFERENC ED-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..
0: (SB-C::
1: (BRACKETED-ACCESS #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #<unused argument>)
2: (SB-IMPL:
3: (SB-IMPL::READ-LIST #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> #<unused argument>)
4: (SB-IMPL:
5: (SB-IMPL:
6: (SB-IMPL:
7: (READ #<SB-SYS:FD-STREAM for "file /tmp/let1.lisp" {100DDB40F3}> T NIL NIL)
8: (SWANK/
9: (SWANK/
10: (SWANK/
11: (SWANK/
12: (SWANK/
13: (SB-KERNEL::%SIGNAL #<SB-INT:
14: (SB-C::
15: (SB-KERNEL::%SIGNAL #<SB-INT:
16: ((FLET SB-KERNEL::%WARN :IN "SYS:SRC;
17: (SB-C:COMPILER-
18: (SB-C::
...
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.