diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index d4268f919e..2c9b5fcab9 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -3124,6 +3124,27 @@ (if (<= y x) (* x y) '-)))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure that a procedure used in a first-order +;; way bound by `letrec' can have a typed closure element: + +(let ([e `(module m racket/base + (provide f) + (define (f v) + (let ([y (vector-length v)]) + (letrec ([foo (lambda (r) + (if (zero? r) + y + (foo (sub1 r))))]) + foo))))] + [o (open-output-bytes)]) + (write (compile e) o) + (parameterize ([current-namespace (make-base-namespace)]) + (eval + (parameterize ([read-accept-compiled #t]) + (read (open-input-bytes (get-output-bytes o))))) + (((dynamic-require ''m 'f) (vector 1)) 0))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/validate.c b/src/racket/src/validate.c index efd6cc50a8..ac697b7564 100644 --- a/src/racket/src/validate.c +++ b/src/racket/src/validate.c @@ -1812,6 +1812,7 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr, case scheme_letrec_type: { Scheme_Letrec *l = (Scheme_Letrec *)expr; + Scheme_Closure_Data *data; int i, c; c = l->count; @@ -1830,10 +1831,20 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr, scheme_ill_formed_code(port); #endif stack[delta + i] = VALID_VAL; - if (SCHEME_CLOSURE_DATA_FLAGS(((Scheme_Closure_Data *)l->procs[i])) & CLOS_HAS_TYPED_ARGS) { - procs = scheme_hash_tree_set(as_nonempty_procs(procs), - scheme_make_integer(delta + i), - l->procs[i]); + data = (Scheme_Closure_Data *)l->procs[i]; + if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) { + /* If any arguments (as opposed to closure slots) are typed, then + add the procedure to `procs': */ + int j; + for (j = data->num_params; j--; ) { + if (scheme_boxmap_get(data->closure_map, j, data->closure_size)) + break; + } + if (j >= 0) { + procs = scheme_hash_tree_set(as_nonempty_procs(procs), + scheme_make_integer(delta + i), + l->procs[i]); + } } }