patch: check duplicates before making an or/c for hash keys
The contract for `(U (I-Hash k1 v1) (M-Hash k2 v2) (W-Hash k3 v3))` is now `(hash/c (or/c k1 k2 k3) (or/c v1 v2 v3))` ONLY WHEN the key and value types are distinct. The contract should no longer include duplicate key or value types.
This commit is contained in:
parent
fae58e140d
commit
6c2a7eb512
|
@ -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)
|
||||
|
|
9
typed-racket-test/succeed/pr390-variation-6.rkt
Normal file
9
typed-racket-test/succeed/pr390-variation-6.rkt
Normal file
|
@ -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)
|
Loading…
Reference in New Issue
Block a user