diff --git a/pkgs/racket-test-core/tests/racket/chaperone.rktl b/pkgs/racket-test-core/tests/racket/chaperone.rktl index 66f4aad880..03c19ddb3f 100644 --- a/pkgs/racket-test-core/tests/racket/chaperone.rktl +++ b/pkgs/racket-test-core/tests/racket/chaperone.rktl @@ -3419,6 +3419,39 @@ (test #t procedure? group-rows*) (test #t has-impersonator-prop:contracted? group-rows*) (test 1 'apply (group-rows* #:group 10))) + +;; ---------------------------------------- +;; Check that position-consuming accessor and mutators work with +;; `impersonate-struct`. + +(let () + (define-values (struct:s make-s s? s-ref s-set!) + (make-struct-type 's #f 1 0 #f)) + + (define a-s (make-s 0)) + + (test '(0) + s-ref + (impersonate-struct + a-s + s-ref + (lambda (k v) (list v)) + s-set! + (lambda (k v) (list v))) + 0) + + (test (void) + s-set! + (impersonate-struct + a-s + s-ref + (lambda (k v) (list v)) + s-set! + (lambda (k v) (list v))) + 0 + 7) + + (test '(7) s-ref a-s 0)) ;; ---------------------------------------- diff --git a/racket/src/cs/rumble/struct.ss b/racket/src/cs/rumble/struct.ss index 0d723790bb..72dd9ab4ca 100644 --- a/racket/src/cs/rumble/struct.ss +++ b/racket/src/cs/rumble/struct.ss @@ -398,10 +398,16 @@ #t)) (define (struct-accessor-procedure-rtd+pos v) - (with-global-lock* (hashtable-ref struct-field-accessors v #f))) + (if (position-based-accessor? v) + (cons (position-based-accessor-rtd v) + (position-based-accessor-offset v)) + (with-global-lock* (hashtable-ref struct-field-accessors v #f)))) (define (struct-mutator-procedure-rtd+pos v) - (with-global-lock* (hashtable-ref struct-field-mutators v #f))) + (if (position-based-mutator? v) + (cons (position-based-mutator-rtd v) + (position-based-mutator-offset v)) + (with-global-lock* (hashtable-ref struct-field-mutators v #f)))) ;; This indirection prevents the whole-program optimizer from inlining ;; the `with-glocal-lock*` expansion --- which, at the time of