diff --git a/typed-racket-lib/typed-racket/private/type-contract.rkt b/typed-racket-lib/typed-racket/private/type-contract.rkt index a9866ca3..55bf7aad 100644 --- a/typed-racket-lib/typed-racket/private/type-contract.rkt +++ b/typed-racket-lib/typed-racket/private/type-contract.rkt @@ -384,17 +384,22 @@ (define (hash-types->sc hts) (if (or (null? hts) (null? (cdr hts))) #false ;; too few types, don't merge - (let-values ([(key-scs val-scs) - (for/lists (ks vs) - ([ht (in-list hts)]) - (match ht - [(or (Immutable-HashTable: k v) - (Mutable-HashTable: k v) - (Weak-HashTable: k v)) - (values (t->sc k) (t->sc v))] - [_ - (raise-arguments-error 'hash-types->sc "expected hash/kv?" "given" ht "element of" hts)]))]) - (hash/sc (apply or/sc key-scs) (apply or/sc val-scs))))) + (let-values ([(kts vts) + (let loop ([kts '()] + [vts '()] + [hts hts]) + (if (null? hts) + (values kts vts) + (match (car hts) + [(or (Immutable-HashTable: k v) + (Mutable-HashTable: k v) + (Weak-HashTable: k v)) + (loop (if (member k kts) kts (cons k kts)) + (if (member v vts) vts (cons v vts)) + (cdr hts))] + [ht + (raise-arguments-error 'hash-types->sc "expected hash/kv?" "given" ht "element of" hts)])))]) + (hash/sc (apply or/sc (map t->sc kts)) (apply or/sc (map t->sc vts)))))) (define (only-untyped sc) (if (from-typed? typed-side) (and/sc sc any-wrap/sc) diff --git a/typed-racket-test/succeed/pr390-variation-6.rkt b/typed-racket-test/succeed/pr390-variation-6.rkt new file mode 100644 index 00000000..19efb2d2 --- /dev/null +++ b/typed-racket-test/succeed/pr390-variation-6.rkt @@ -0,0 +1,9 @@ +#lang racket/base + +(module t typed/racket + (provide h) + (define h : (U (Immutable-HashTable Symbol Any) (Mutable-HashTable Symbol Any)) + (hash 'a 1))) + +(require 't) +(hash-ref h 'a)