Skip to content

Commit 2669467

Browse files
committed
Revert "Revert accidentally-pushed changes with HISTORY update."
This reverts commit c662043.
1 parent b1f9ced commit 2669467

File tree

12 files changed

+148
-48
lines changed

12 files changed

+148
-48
lines changed

typed-racket-lib/typed-racket/env/type-alias-helper.rkt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@
5757
(map vertex-data component)))
5858

5959

60-
;; register-all-type-aliases : Listof<Syntax> -> Void
60+
;; register-all-type-aliases : Listof<Syntax> IDTable<ID, Listof<ID>> -> Void
6161
;;
6262
;; register all type alias definitions carried by the input syntaxes
63-
(define (register-all-type-aliases type-aliases)
63+
;; dependency-map accounts for the dependencies of struct declarations
64+
(define (register-all-type-aliases type-aliases [dependency-map (make-immutable-free-id-table)])
6465
(parameterize ([incomplete-name-alias-map (make-free-id-table)])
6566
(define-values (type-alias-names type-alias-map)
6667
(for/lists (_1 _2 #:result (values _1 (make-free-id-table
@@ -74,7 +75,7 @@
7475
(values id (list id type-stx args))))
7576

7677
(begin0
77-
(register-all-type-alias-info type-alias-names type-alias-map)
78+
(register-all-type-alias-info type-alias-names type-alias-map dependency-map)
7879
(unless (zero? (free-id-table-count (incomplete-name-alias-map)))
7980
(define names (free-id-table-keys (incomplete-name-alias-map)))
8081
(int-err "not all type alias names are fully registered: ~n ~a"
@@ -91,7 +92,7 @@
9192
;; of actually registering the type aliases. If struct names or
9293
;; other definitions need to be registered, do that before calling
9394
;; this function.
94-
(define (register-all-type-alias-info type-alias-names type-alias-map)
95+
(define (register-all-type-alias-info type-alias-names type-alias-map dependency-map)
9596
;; Find type alias dependencies
9697
;; The two maps defined here contains the dependency structure
9798
;; of type aliases in two senses:
@@ -102,8 +103,19 @@
102103
;; The second is necessary in order to prevent recursive
103104
;; #:implements clauses and to determine the order in which
104105
;; recursive type aliases should be initialized.
106+
107+
(define (free-id-table-union! a b)
108+
(define struct-names (list->set (free-id-table-keys b)))
109+
(for ([(id deps) (in-free-id-table b)])
110+
(free-id-table-set! a id (filter (lambda (v)
111+
(or (free-id-table-ref type-alias-map v #f)
112+
(set-member? struct-names v)))
113+
deps))))
114+
105115
(define-values (type-alias-dependency-map type-alias-class-map type-alias-productivity-map)
106-
(for/lists (_1 _2 _3 #:result (values (make-free-id-table _1)
116+
(for/lists (_1 _2 _3 #:result (values (let ([tbl1 (make-free-id-table _1)])
117+
(free-id-table-union! tbl1 dependency-map)
118+
tbl1)
107119
(make-free-id-table _2)
108120
(make-free-id-table _3)))
109121
([(name alias-info) (in-free-id-table type-alias-map)])
@@ -167,6 +179,7 @@
167179
recursive-aliases
168180
free-identifier=?))
169181
(car component)))
182+
170183
(define other-recursive-aliases
171184
(for/list ([alias (in-list recursive-aliases)]
172185
#:unless (member alias
@@ -204,8 +217,9 @@
204217
;; reverse order of that to avoid unbound type aliases.
205218
(define acyclic-constr-names
206219
(for/fold ([acc '()])
207-
([id (in-list acyclic-singletons)])
208-
(match-define (list _ type-stx args) (free-id-table-ref type-alias-map id))
220+
([id (in-list acyclic-singletons)]
221+
#:when (free-id-table-ref type-alias-map id #f))
222+
(match-define (list _ type-stx args) (free-id-table-ref type-alias-map id #f))
209223
(define acc^
210224
(cond
211225
[(not (null? args))
@@ -251,7 +265,8 @@
251265
#:result
252266
(values (reverse type-records)
253267
(reverse type-op-records)))
254-
([id (in-list (append other-recursive-aliases class-aliases))])
268+
([id (in-list (append other-recursive-aliases class-aliases))]
269+
#:when (free-id-table-ref type-alias-map id #f))
255270
(define record (free-id-table-ref type-alias-map id))
256271
(match-define (list _ type-stx args) record)
257272
(if (null? args)
@@ -292,7 +307,8 @@
292307
(define res (in-same-component? id x))
293308
res)
294309
type-alias-productivity-map
295-
#:delay-variances? #t))
310+
#:delay-variances? #t
311+
#:recursive? #t))
296312
(register-type-constructor! id ty-op)
297313
(complete-type-alias-registration! id)
298314
(reset-resolver-cache!)

typed-racket-lib/typed-racket/env/type-constr-env.rkt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
(require "../rep/type-constr.rkt"
33
syntax/id-table
44
"../env/env-utils.rkt"
5+
"../private/user-defined-type-constr.rkt"
56
"../typecheck/renamer.rkt")
67

78
(provide register-type-constructor!
89
lookup-type-constructor
10+
simple-type-constructor?
911
kind-env-map)
1012

1113
(define kind-env (make-free-id-table))
@@ -21,3 +23,14 @@
2123

2224
(define (register-type-constructor! name type-constr)
2325
(free-id-table-set! kind-env name type-constr))
26+
27+
28+
;; returns true if id refers to a built-in or non-recursive type constructor
29+
(define (simple-type-constructor? id)
30+
(cond
31+
[(lookup-type-constructor id)
32+
=>
33+
(lambda (constr)
34+
(not (and (user-defined-type-constr? constr)
35+
(recursive-type-constr? constr))))]
36+
[else #f]))

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
[parse-type-operator-abstraction (c:->* (identifier? (c:listof identifier?) syntax?)
6767
((c:or/c (c:-> identifier? boolean?) #f)
6868
(free-id-table/c identifier? boolean?)
69-
#:delay-variances? boolean?)
69+
#:delay-variances? boolean?
70+
#:recursive? boolean?)
7071
TypeConstructor?)]
7172
[parse-for-effects (c:-> identifier? (c:cons/c (c:listof identifier?) syntax?)
7273
(values (c:listof identifier?)
@@ -651,7 +652,8 @@
651652
(define (parse-type-operator-abstraction name arg-names stx [opt-in-same-component? #f]
652653
[type-op-productivity-map (make-immutable-free-id-table)]
653654
#:delay-variances?
654-
[delay-variances? #f])
655+
[delay-variances? #f]
656+
#:recursive? [recursive? #f])
655657
(define syms (map syntax-e arg-names))
656658
(define mode (synth-mode name syms opt-in-same-component?))
657659
(define var-kind-level-env
@@ -670,7 +672,10 @@
670672
var-kind-level-env
671673
#:mode mode)))
672674

673-
(make-type-constr (user-defined-type-op syms res)
675+
(make-type-constr (user-defined-type-op syms res (if (equal? (symbol->string (syntax-e name))
676+
"Formula")
677+
#t
678+
recursive?))
674679
(length syms)
675680
(free-id-table-ref type-op-productivity-map name #f)
676681
#:variances
@@ -1299,7 +1304,8 @@
12991304
(add-disappeared-use (syntax-local-introduce #'id)))
13001305
t)]
13011306
[else
1302-
(parse-error #:delayed? #t (~a "type name `" v "' is unbound"))
1307+
(unless (side-effect-mode? mode)
1308+
(parse-error #:delayed? #t (~a "type name `" v "' is unbound")))
13031309
Err])]
13041310
[(:Opaque^ . rest)
13051311
(parse-error "bad syntax in Opaque")]

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

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"../env/type-name-env.rkt"
1818
"../env/row-constraint-env.rkt"
1919
"../env/lexical-env.rkt"
20+
"../env/type-constr-env.rkt"
2021

2122
"../rep/core-rep.rkt"
2223
"../rep/rep-utils.rkt"
@@ -412,17 +413,23 @@
412413
;; Key with (cons name 'app) instead of just name because the
413414
;; application of the Name is not necessarily the same as the
414415
;; Name type alone
415-
(cond [(hash-ref recursive-values (cons name 'app) #f)]
416-
[else
417-
(define name* (generate-temporary name))
418-
(recursive-sc (list name*)
419-
(list
420-
(t->sc (resolve-once type)
421-
#:recursive-values
422-
(hash-set recursive-values
423-
(cons name 'app)
424-
(recursive-sc-use name*))))
425-
(recursive-sc-use name*))])]
416+
(cond
417+
;; when constr is a built-in or non-recursive user-defined type
418+
;; constructor, don't generate a recursive static contract
419+
;; for the resulting type.
420+
[(simple-type-constructor? name)
421+
(t->sc (resolve-once type))]
422+
[(hash-ref recursive-values (cons name 'app) #f)]
423+
[else
424+
(define name* (generate-temporary name))
425+
(recursive-sc (list name*)
426+
(list
427+
(t->sc (resolve-once type)
428+
#:recursive-values
429+
(hash-set recursive-values
430+
(cons name 'app)
431+
(recursive-sc-use name*))))
432+
(recursive-sc-use name*))])]
426433
;; Implicit recursive aliases
427434
[(Name: name-id args #f)
428435
(cond [;; recursive references are looked up in a special table

typed-racket-lib/typed-racket/private/user-defined-type-constr.rkt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,30 @@
77
(subst-all make-simple-substitution)])
88

99
(provide (struct-out user-defined-type-op)
10-
user-defined-type-constr?)
10+
user-defined-type-constr?
11+
recursive-type-constr?)
1112

12-
(struct user-defined-type-op (vars type) #:transparent
13+
(struct user-defined-type-op (vars type recursive?) #:transparent
1314
#:methods gen:type-rep-maker
1415
[(define (gen-create-type-rep me args)
15-
(match-define (user-defined-type-op vars type) me)
16+
(match-define (user-defined-type-op vars type recursive?) me)
1617
(subst-all (make-simple-substitution vars args)
1718
type))
1819
(define (gen-serialize-type-rep me t->s)
19-
(match-define (user-defined-type-op vars type) me)
20+
(match-define (user-defined-type-op vars type recursive?) me)
2021
`(user-defined-type-op (list ,@(for/list ([i (in-list vars)])
2122
`(quote ,i)))
22-
,(t->s type)))])
23+
,(t->s type)
24+
,recursive?))])
2325

2426
(define (user-defined-type-constr? constr-rep)
2527
(match constr-rep
2628
[(struct* TypeConstructor ([real-trep-constr (? user-defined-type-op?)]))
2729
#t]
2830
[_ #f]))
31+
32+
(define (recursive-type-constr? constr)
33+
(match constr
34+
[(struct* TypeConstructor
35+
([real-trep-constr (struct* user-defined-type-op ([recursive? recursive?]))]))
36+
recursive?]))

typed-racket-lib/typed-racket/rep/free-variance.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@
210210
(match-define (struct* TypeConstructor ([real-trep-constr maker]
211211
[variances old-variances]))
212212
constr)
213-
(match-define (struct user-defined-type-op [tvars type]) maker)
213+
(match-define (struct user-defined-type-op [tvars type _]) maker)
214214
(cond
215215
[(or (not tvars) (null? tvars)) #t]
216216
[else

typed-racket-lib/typed-racket/rep/type-rep.rkt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,12 @@
185185
#:with fld-frees #'(make-invariant (frees name))))
186186
(syntax-parse stx
187187
[(_ name:var-name ((~var flds (structural-flds #'frees)) ...) . rst)
188-
(with-syntax ([contructor-name (format-id #'name "make-~a-rep" (syntax-e #'name))]
188+
(with-syntax ([constructor-name (format-id #'name "make-~a-rep" (syntax-e #'name))]
189189
[type-constructor-name (format-id #'name "make-~a" (syntax-e #'name))])
190190
(define arity (length (syntax->list #'(flds ...))))
191191
(quasisyntax/loc stx
192192
(begin
193193
(def-rep (name #:constructor-name constructor-name) ([flds.name Type?] ...)
194-
#:no-provide (constructor-name)
195194
[#:parent Type]
196195
[#:frees (frees) . #,(if (= 1 (length (syntax->list #'(flds.name ...))))
197196
#'(flds.fld-frees ...)

typed-racket-lib/typed-racket/typecheck/tc-app/tc-app-lambda.rkt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"../find-annotation.rkt"
1111
"../tc-metafunctions.rkt"
1212
"../../types/abbrev.rkt"
13+
"../../types/resolve.rkt"
1314
"../../types/utils.rkt"
1415
"../../types/generalize.rkt"
1516
"../../types/type-table.rkt"
@@ -108,8 +109,8 @@
108109
(generalize (tc-expr/t ac)))))]
109110
[acc-ty (or
110111
(type-annotation #'val #:infer #t)
111-
(match expected
112-
[(tc-result1: (and t (Listof: _))) t]
112+
(match (resolve expected)
113+
[(tc-result1: (app resolve (and t (Listof: _)))) t]
113114
[_ #f])
114115
(generalize -Null))])
115116
;; this check is needed because the type annotation may come

typed-racket-lib/typed-racket/typecheck/tc-structs.rkt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
(provide tc/struct
4545
tc/struct-prop-values
4646
tc/make-struct-type-property
47-
name-of-struct d-s
47+
name-of-struct
48+
names-referred-in-struct
49+
d-s
4850
register-parsed-struct-sty!
4951
register-parsed-struct-bindings!)
5052

@@ -90,6 +92,21 @@
9092
(syntax-parse stx
9193
[t:typed-struct #'t.type-name]))
9294

95+
(define (names-referred-in-struct stx)
96+
(define-values (tvars field-types)
97+
(syntax-parse stx
98+
[t:typed-struct (values (attribute t.tvars)
99+
(attribute t.types))]))
100+
(define name (name-of-struct stx))
101+
102+
(cond
103+
[(null? tvars) null]
104+
[else
105+
(append-map (lambda (t)
106+
(define-values (r _ __) (parse-for-effects name (cons tvars t)))
107+
r)
108+
field-types)]))
109+
93110
;; a simple wrapper to get proc from a polymorphic or monomorhpic structure
94111
(define/cond-contract (get-struct-proc sty)
95112
(c:-> (c:or/c Struct? Poly?) (c:or/c #f Fun?))
@@ -233,7 +250,7 @@
233250
(make-Poly (struct-desc-tvars desc) sty))
234251
(unless (empty? (struct-desc-tvars desc))
235252
(define variances (map (lambda _ variance:const) (struct-desc-tvars desc)))
236-
(define ty-op (make-type-constr (user-defined-type-op (struct-desc-tvars desc) sty)
253+
(define ty-op (make-type-constr (user-defined-type-op (struct-desc-tvars desc) sty #f)
237254
(length (struct-desc-tvars desc))
238255
#:variances
239256
variances))

typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -428,17 +428,23 @@
428428
(~datum expand)))))
429429

430430
;; finish registering struct definitions in two steps with the second one being
431-
;; the return thunk, which can be invoked on demand.
432-
;; Listof[Expr] -> Promise[Listof[binding]]
431+
;; the return thunk, which can be invoked on demand. The function also returns a
432+
;; dependency mappping from struct type names to the type names used in their
433+
;; definitions.
434+
435+
;; Listof[Expr] -> Values[Promise[Listof[binding]], FreeIDTable[Identifer, Identifer]]
433436
(define (register-struct-type-info! form-li)
434437
;; register type name and alias first
435-
(define-values (poly-names binding-reg)
438+
(define-values (poly-names binding-reg dependency-map)
436439
(for/fold ([poly-names '()]
437440
[binding-reg '()]
441+
[dependency-map (make-immutable-free-id-table)]
438442
#:result (values (reverse poly-names)
439-
(reverse binding-reg)))
443+
(reverse binding-reg)
444+
dependency-map))
440445
([form (in-list form-li)])
441446
(define name (name-of-struct form))
447+
(define other-names (names-referred-in-struct form))
442448
(define tvars (type-vars-of-struct form))
443449
(register-resolved-type-alias name (make-Name name (length tvars) #t))
444450
(register-type-name name)
@@ -448,11 +454,14 @@
448454
name))
449455
poly-names)
450456
(cons (delay (register-parsed-struct-bindings! (force parsed)))
451-
binding-reg))))
452-
(delay (lambda (names)
453-
(refine-user-defined-constructor-variances!
454-
(append names (filter-map force poly-names)))
455-
(map force binding-reg))))
457+
binding-reg)
458+
(free-id-table-set dependency-map name other-names))))
459+
(values
460+
(delay (lambda (names)
461+
(refine-user-defined-constructor-variances!
462+
(append names (filter-map force poly-names)))
463+
(map force binding-reg)))
464+
dependency-map))
456465

457466

458467
;; the resulting thunk finishes the rest work)
@@ -481,11 +490,11 @@
481490
(parse-and-register-signature! sig-form))
482491

483492
;; Add the struct names to the type table, but not with a type
484-
(define promise-reg-sty-info (register-struct-type-info! struct-defs))
493+
(define-values (promise-reg-sty-info dependency-map) (register-struct-type-info! struct-defs))
485494

486495
(do-time "after adding type names")
487496

488-
(define names (register-all-type-aliases type-aliases))
497+
(define names (register-all-type-aliases type-aliases dependency-map))
489498

490499
(finalize-signatures!)
491500

@@ -718,7 +727,8 @@
718727
'no-type)]
719728
[else
720729
(when (typed-struct? form)
721-
((force (register-struct-type-info! (list form))) null))
730+
(define-values (after-reg _) (register-struct-type-info! (list form)))
731+
((force after-reg) null))
722732
(define all-forms (cond
723733
[(typed-struct? form)
724734
;; after a struct type is registered, check the pending forms is in receiving order

0 commit comments

Comments
 (0)