diff --git a/racket/src/cs/rumble/error-rewrite.ss b/racket/src/cs/rumble/error-rewrite.ss index 199ed0d1fa..1cefbe23f0 100644 --- a/racket/src/cs/rumble/error-rewrite.ss +++ b/racket/src/cs/rumble/error-rewrite.ss @@ -56,7 +56,9 @@ (define (rewrite-format str irritants) (cond [(equal? str "attempt to reference undefined variable ~s") - (values "~a: undefined;\n cannot reference an identifier before its definition" + (values (string-append + "~a: undefined;\n cannot reference an identifier before its definition" + "\n alert: compiler pass failed to add more specific guard!") irritants)] [else (let ([str (string-copy str)] diff --git a/racket/src/schemify/mutated-state.rkt b/racket/src/schemify/mutated-state.rkt index 580ddb2043..d86913f0a0 100644 --- a/racket/src/schemify/mutated-state.rkt +++ b/racket/src/schemify/mutated-state.rkt @@ -49,12 +49,13 @@ (eq? v 'too-early)) ;; When referecing an exported identifier, we need to consistently go -;; through a `variable` record when it can be `set!`ed. We don't need -;; to go through a `variable` record if the identifier might simply be -;; used too early, because the host Scheme takes care of that issue. +;; through a `variable` record when it can be `set!`ed or is not yet +;; ready (as indicated by 'too-early, which is changed to 'too-eary/ready +;; as the variable becomes ready) (define (via-variable-mutated-state? v) (or (eq? v 'set!ed) - (eq? v 'undefined))) + (eq? v 'undefined) + (eq? v 'too-early))) ;; At the end of a linklet, known-value information is reliable unless ;; the identifier is mutated diff --git a/racket/src/schemify/schemify.rkt b/racket/src/schemify/schemify.rkt index f4561de5c2..b2e7a2b400 100644 --- a/racket/src/schemify/schemify.rkt +++ b/racket/src/schemify/schemify.rkt @@ -44,6 +44,12 @@ ;; `#%app` whenever a call might go through something other than a ;; plain function; ;; +;; - convert all `letrec` patterns that might involve `call/cc` to +;; ensure that locations are allocated at the right time; +;; +;; - explicily handle all potential too-early variable uses, so that +;; the right name and enclosing module are reported; +;; ;; - convert `make-struct-type` bindings to a pattern that Chez can ;; recognize; ;; @@ -51,6 +57,8 @@ ;; important to make keyword-argument function calls work directly ;; without keywords; ;; +;; - similarly optimize away `variable-reference-from-unsafe?`; +;; ;; - simplify `define-values` and `let-values` to `define` and ;; `let`, when possible, and generally avoid `let-values`. @@ -58,10 +66,10 @@ ;; called from the Racket expander, those annotation will be ;; "correlated" objects that just support source locations. -;; Returns (values schemified-linklet import-abi export-info) +;; Returns (values schemified-linklet import-abi export-info). ;; An import ABI is a list of list of booleans, parallel to the ;; linklet imports, where #t to means that a value is expected, and #f -;; means that a variable (which boxes a value) is expected +;; means that a variable (which boxes a value) is expected. (define (schemify-linklet lk serializable? datum-intern? for-jitify? allow-set!-undefined? unsafe-mode? no-prompt? prim-knowns get-import-knowns import-keys) @@ -229,7 +237,7 @@ ;; For the case that the right-hand side won't capture a ;; continuation or return multiple times, we can generate a ;; simple definition: - (define (finish-definition ids) + (define (finish-definition ids [accum-exprs accum-exprs] [accum-ids accum-ids]) (append (make-expr-defns accum-exprs) (cons @@ -305,8 +313,10 @@ (match form [`(define-values ,ids ,_) ;; This is a rearranged `struct` form where any necessary - ;; prompt is in place already - (finish-definition ids)] + ;; prompt is in place already. There may be arbitrary expressions + ;; for properties, though, so sync exported variables + (define set-vars (make-set-variables)) + (finish-definition ids (append set-vars accum-exprs) null)] [`,_ (cond [(simple? #:pure? #f schemified prim-knowns knowns imports mutated)