Skip to content

Commit f33abfd

Browse files
committed
Fix a bug in generating contracts for prefabs.
A recursively defined prefab type caused the expansion to diverge. The changes fix this issue. close #906
1 parent ff79c88 commit f33abfd

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

typed-racket-lib/typed-racket/private/type-contract.rkt

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,17 @@
324324
(loop t 'both recursive-values))
325325
(define (t->sc/fun t) (t->sc/function t fail typed-side recursive-values loop #f))
326326
(define (t->sc/meth t) (t->sc/method t fail typed-side recursive-values loop))
327+
328+
(define (struct->recursive-sc name-base key flds sc-ctor)
329+
(define key* (generate-temporary name-base))
330+
(define rv (hash-set recursive-values
331+
key
332+
(recursive-sc-use key*)))
333+
(define ftsc (for/list ([ft (in-list flds)])
334+
(t->sc ft #:recursive-values rv)))
335+
(recursive-sc (list key*) (list (sc-ctor ftsc))
336+
(recursive-sc-use key*)))
337+
327338
(define (prop->sc p)
328339
(match p
329340
[(TypeProp: o (app t->sc tc))
@@ -715,14 +726,9 @@
715726
[(hash-ref recursive-values nm #f)]
716727
[proc (fail #:reason "procedural structs are not supported")]
717728
[poly?
718-
(define nm* (generate-temporary #'n*))
719-
(define fields
720-
(for/list ([fty (in-list flds)])
721-
(t->sc fty #:recursive-values (hash-set
722-
recursive-values
723-
nm (recursive-sc-use nm*)))))
724-
(recursive-sc (list nm*) (list (struct/sc nm (ormap values mut?) fields))
725-
(recursive-sc-use nm*))]
729+
(struct->recursive-sc #'n* nm flds
730+
(lambda (ftsc)
731+
(struct/sc nm (ormap values mut?) ftsc)))]
726732
[else (flat/sc #`(flat-named-contract '#,(syntax-e pred?) (lambda (x) (#,pred? x))))])]
727733
[(StructType: s)
728734
(if (from-untyped? typed-side)
@@ -754,7 +760,13 @@
754760
"property"
755761
#,real-prop-var)
756762
(#,pred? x)))))]
757-
[(Prefab: key (list (app t->sc fld/scs) ...)) (prefab/sc key fld/scs)]
763+
[(Prefab: (and key (list key-sym rst ...)) (list flds ...))
764+
(cond
765+
[(hash-ref recursive-values key #f)]
766+
[else
767+
(struct->recursive-sc key-sym key flds
768+
(lambda (ftsc)
769+
(prefab/sc key ftsc)))])]
758770
[(PrefabTop: key)
759771
(flat/sc #`(struct-type-make-predicate
760772
(prefab-key->struct-type (quote #,(abbreviate-prefab-key key))
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#lang typed/racket/base
2+
3+
(provide container)
4+
5+
(struct container
6+
([value : (U #f container)])
7+
#:prefab)

0 commit comments

Comments
 (0)