diff --git a/pkgs/racket-test/tests/racket/contract/hash.rkt b/pkgs/racket-test/tests/racket/contract/hash.rkt index e15def0b05..fac55229c8 100644 --- a/pkgs/racket-test/tests/racket/contract/hash.rkt +++ b/pkgs/racket-test/tests/racket/contract/hash.rkt @@ -191,6 +191,51 @@ (for ([(k v) (in-hash h)]) (hash-ref k v)))) + (test/spec-passed + 'hash/c14 + '(let () + (define h (hash 1 #f)) + (hash-set (contract (hash/c integer? boolean?) h 'pos 'neg) + 1 "x"))) + + (test/spec-passed/result + 'hash/c15 + '(let () + (define h (hash 1 #f)) + (chaperone-of? (contract (hash/c integer? boolean?) h 'pos 'neg) + h)) + #t) + + (test/spec-passed + 'hash/c16 + '(let () + (define h (hash 1 #f)) + (define c-h + (chaperone-hash + h + (λ (h k) (values k (λ (h k v) v))) + (λ (h k v) (values k v)) + (λ (h k) k) + (λ (h k) k))) + (hash-set (contract (hash/c integer? boolean?) c-h 'pos 'neg) + 1 "x"))) + + (test/spec-passed/result + 'hash/c17 + '(let () + (define h (hash 1 #f)) + (define c-h + (chaperone-hash + h + (λ (h k) (values k (λ (h k v) v))) + (λ (h k v) (values k v)) + (λ (h k) k) + (λ (h k) k))) + (chaperone-of? (contract (hash/c integer? boolean?) c-h 'pos 'neg) + c-h)) + #t) + + (test/pos-blame 'hash/dc1 '(contract (hash/dc [d integer?] [r (d) (if (even? d) string? symbol?)]) diff --git a/racket/collects/racket/contract/private/hash.rkt b/racket/collects/racket/contract/private/hash.rkt index 7bd4b3a6fd..9f4d0cb616 100644 --- a/racket/collects/racket/contract/private/hash.rkt +++ b/racket/collects/racket/contract/private/hash.rkt @@ -237,16 +237,11 @@ (define (handle-the-hash val neg-party pos-dom-proj neg-dom-proj mk-pos-rng-proj mk-neg-rng-proj chaperone-or-impersonate-hash ctc blame) - (if (and (immutable? val) (not (chaperone? val))) - (let ([hash-maker - (cond - [(hash-equal? val) make-immutable-hash] - [(hash-eqv? val) make-immutable-hasheqv] - [(hash-eq? val) make-immutable-hasheq])]) - (hash-maker - (for/list ([(k v) (in-hash val)]) - (cons ((pos-dom-proj k) neg-party) - (((mk-pos-rng-proj k) v) neg-party))))) + (if (immutable? val) + (for/fold ([h val]) ([(k v) (in-hash val)]) + (hash-set h + ((pos-dom-proj k) neg-party) + (((mk-pos-rng-proj k) v) neg-party))) (chaperone-or-impersonate-hash val (λ (h k)