[racket-dev] Strange issue with identifier-binding being wrong for lexical variables

From: Sam Tobin-Hochstadt (samth at cs.indiana.edu)
Date: Tue Oct 21 22:26:26 EDT 2014

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)

Posted on the dev mailing list.