From fe12a32dc357f2d169f6d998d028be4d1d27b172 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Dec 2013 14:19:01 -0700 Subject: [PATCH] fix closure type tracking for a procedure with only an unused rest arg Closes PR 14259 --- .../racket-test/tests/racket/optimize.rktl | 17 +++++++++++++++++ racket/src/racket/src/resolve.c | 10 +++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-pkgs/racket-test/tests/racket/optimize.rktl b/pkgs/racket-pkgs/racket-test/tests/racket/optimize.rktl index 80335e82fb..0e1a67bb36 100644 --- a/pkgs/racket-pkgs/racket-test/tests/racket/optimize.rktl +++ b/pkgs/racket-pkgs/racket-test/tests/racket/optimize.rktl @@ -3165,6 +3165,23 @@ (void (dynamic-require ''uses-too-much-memory-for-shift #f))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure that closure fields are correctly type-tagged +;; when a function has an unused rest arg: + +(parameterize ([current-namespace (make-base-namespace)] + [read-on-demand-source #f] + [read-accept-compiled #t]) + (let ([o (open-output-bytes)]) + (write (compile '(module m racket/base + (require racket/fixnum) + (define (test l) + (define n (fxmax (length l) 1)) + (lambda _ n)))) + o) + ;; Should succeed, as opposed to a validation error: + (eval (read (open-input-bytes (get-output-bytes o)))))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/resolve.c b/racket/src/racket/src/resolve.c index ad9c626f14..03faaf1737 100644 --- a/racket/src/racket/src/resolve.c +++ b/racket/src/racket/src/resolve.c @@ -2015,8 +2015,16 @@ resolve_closure_compilation(Scheme_Object *_data, Resolve_Info *info, /* (lambda args E) where args is not in E => drop the argument */ new_info = resolve_info_extend(info, 0, 1, cl->base_closure_size); num_params = 0; - if (!just_compute_lift) + if (!just_compute_lift) { data->num_params = 0; + if (expanded_already) { + /* shift type map down: */ + for (i = 0; i < closure_size; i++) { + scheme_boxmap_set(closure_map, i, scheme_boxmap_get(closure_map, i + 1, closure_size), closure_size); + } + SCHEME_CLOSURE_DATA_FLAGS(data) |= CLOS_HAS_TYPED_ARGS; + } + } } else { new_info = resolve_info_extend(info, data->num_params, data->num_params, cl->base_closure_size + data->num_params);