From c514fd3470dad254850086a11d7ec5a2345ea59d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 16 Oct 2011 07:00:04 -0700 Subject: [PATCH] fix an identifier binding bug Merge to 5.2 --- collects/tests/racket/macro.rktl | 36 ++++++++++++++++++++++++++++++++ src/racket/src/compenv.c | 9 +++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/collects/tests/racket/macro.rktl b/collects/tests/racket/macro.rktl index 1b84ae708b..96f98a9fc9 100644 --- a/collects/tests/racket/macro.rktl +++ b/collects/tests/racket/macro.rktl @@ -566,6 +566,42 @@ (q)))) (require 'm-check-varref-expand) +;; ---------------------------------------- +;; Check that a modul-level binding with 0 marks +;; but lexical context is found correctly with +;; 1 and 2 marks (test case by Carl): + +(module check-macro-introduced-via-defctx racket/base + (require (for-syntax racket/base racket/syntax)) + + (begin-for-syntax + (define env (box #false))) + + (define-syntax (one stx) + (define ctx (syntax-local-make-definition-context #false)) + (define id + (internal-definition-context-apply + ctx + (syntax-local-introduce (datum->syntax #false 'private)))) + (syntax-local-bind-syntaxes (list id) #false ctx) + (internal-definition-context-seal ctx) + #`(begin + (begin-for-syntax (set-box! env #'#,id)) + (define #,id #false))) + (one) + + (define-syntax (two stx) + (define id ((make-syntax-introducer) (unbox env))) + (unless (free-identifier=? id (syntax-local-introduce id)) + (raise-syntax-error + #false + (format "mark changes identifier's binding: ~v / ~v" + (identifier-binding id) + (identifier-binding (syntax-local-introduce id))) + id)) + #'#f) + (two)) + ;; ---------------------------------------- (report-errs) diff --git a/src/racket/src/compenv.c b/src/racket/src/compenv.c index 9bf196b9cd..2bd5720e42 100644 --- a/src/racket/src/compenv.c +++ b/src/racket/src/compenv.c @@ -1086,10 +1086,13 @@ Scheme_Object *scheme_tl_id_sym(Scheme_Env *env, Scheme_Object *id, Scheme_Objec break; } } else { - if (!SCHEME_PAIRP(marks)) { + if (SCHEME_NULLP(amarks)) { + /* can always match empty marks */ + best_match = SCHEME_CDR(a); + best_match_skipped = 0; + } else if (!SCHEME_PAIRP(marks)) { /* To be better than nothing, could only match exactly: */ - if (scheme_equal(amarks, marks) - || SCHEME_NULLP(amarks)) { + if (scheme_equal(amarks, marks)) { best_match = SCHEME_CDR(a); best_match_skipped = 0; }