[racket-dev] Strange issue with identifier-binding being wrong for lexical variables
I've found what I think is a bug in the expander where lexical
references can get an `identifier-binding` result that suggests that
they're module-bound.
In particular, you need these three files:
bugtest.rkt:
(module bugtest "wraptest.rkt")
bugtest.scm:
(define (gcbench)
(define main #f)
main)
(define main #f)
wraptest.rkt:
#lang racket/base
(provide (rename-out (module-begin #%module-begin)))
(require racket/include
(for-syntax racket/base))
(define-syntax (module-begin stx)
(define name (syntax-property stx 'enclosing-module-name))
#`(#%module-begin
(include #,(format "~a.scm" name))))
Then run the macro stepper with macro hiding off on "bugtest.rkt".
Click on the reference to `main` inside `gcbench`. You'll see that it
says that it's a module-bound variable named `main.2` which is defined
in this module.
Then try changing the name of the top-level definition in bugtest.scm
to `main2`. Re-run the macro stepper, and you'll see that the
identifier-binding is now lexical.
I tried a few things to get this to go away (such as using
`#%plain-module-begin`) which didn't work. Reducing it to two files,
ie doing the include directly in bugtest.rkt, made the problem
disappear.
Changing the body of the `module-begin` macro to:
(define-syntax (module-begin stx)
(define name (syntax-property stx 'enclosing-module-name))
#`(#%module-begin
#,(datum->syntax stx `(include ,(format "~a.scm" name)))
#,(datum->syntax stx '(main))))
and then providing a bunch of extra stuff made the issue go away.
Because there's the workaround, the issue isn't urgent.
Sam (and Tobias, who found this bug)