Skip to content

Commit f59df64

Browse files
committed
test: pass recursive kinds to optimizer
1 parent 909ca7c commit f59df64

File tree

3 files changed

+34
-40
lines changed

3 files changed

+34
-40
lines changed

typed-racket-lib/typed-racket/static-contracts/combinators/name.rkt

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,13 @@
1717
racket/match
1818
racket/syntax
1919
syntax/private/id-table
20-
(only-in syntax/private/id-set
21-
mutable-free-id-set
22-
free-id-set-add!
23-
free-id-set-member?)
2420
(for-syntax racket/base
2521
syntax/parse))
2622

2723
(provide with-new-name-tables
2824
name/sc:
2925
lookup-name-defined
30-
set-name-defined
31-
set-flat-names!)
26+
set-name-defined)
3227

3328
(provide/cond-contract
3429
[get-all-name-defs
@@ -45,12 +40,6 @@
4540

4641
(define name-sc-table (make-parameter (make-hash)))
4742
(define name-defs-table (make-parameter (make-hash)))
48-
(define current-flat-names (make-parameter (mutable-free-id-set)))
49-
50-
(define (set-flat-names! gen-names)
51-
(define cfn (current-flat-names))
52-
(for ((stx (in-list gen-names)))
53-
(free-id-set-add! cfn stx)))
5443

5544
;; Use this table to track whether a contract has already been
5645
;; generated for this name type yet. Stores booleans.
@@ -67,8 +56,7 @@
6756
(define-syntax-rule (with-new-name-tables e)
6857
(parameterize ([name-sc-table (make-hash)]
6958
[name-defs-table (make-hash)]
70-
[name-defined-table (make-free-id-table)]
71-
[current-flat-names (mutable-free-id-set)])
59+
[name-defined-table (make-free-id-table)])
7260
e))
7361

7462
(define (get-all-name-defs)
@@ -113,13 +101,8 @@
113101
(define (sc->contract v f)
114102
(name-combinator-gen-name v))
115103
(define (sc->constraints v f)
116-
(variable-contract-restrict (name-combinator-gen-name v)))
117-
(define (sc-terminal-kind v)
118-
(if (free-id-set-member? (current-flat-names) (name-combinator-gen-name v))
119-
'flat
120-
#false))])
104+
(variable-contract-restrict (name-combinator-gen-name v)))])
121105

122106
(define-match-expander name/sc:
123107
(syntax-parser
124108
[(_ var) #'(name-combinator _ var)]))
125-

typed-racket-lib/typed-racket/static-contracts/instantiate.rkt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424
(provide static-contract-may-contain-free-ids?)
2525

2626
(provide/cond-contract
27+
[instantiate/optimize
28+
(parametric->/c (a) ((static-contract? (-> reason (or/c #f string?) a))
29+
(contract-kind? #:cache hash? #:trusted-positive boolean? #:trusted-negative boolean?)
30+
. ->* . (or/c a (list/c (listof syntax?) syntax?))))]
2731
[instantiate
2832
(parametric->/c (a) ((static-contract? (-> #:reason (or/c #f string?) a))
2933
(contract-kind? #:cache hash?)
3034
. ->* . (or/c a (list/c (listof syntax?) syntax?))))]
3135
[should-inline-contract? (-> syntax? boolean?)])
32-
(provide instantiate/optimize)
3336

3437
;; Providing these so that tests can work directly with them.
3538
(module* internals #f
@@ -43,11 +46,7 @@
4346
(lambda (exn) (fail #:reason (exn:fail:constraint-failure-reason exn))))]
4447
(compute-recursive-kinds
4548
(contract-restrict-recursive-values (compute-constraints sc kind)))))
46-
(set-flat-names!
47-
(for/list ([(k v) (in-hash recursive-kinds)]
48-
#:when (eq? 'flat v))
49-
k))
50-
(define sc/opt (optimize sc #:trusted-positive trusted-positive #:trusted-negative trusted-negative))
49+
(define sc/opt (optimize sc #:trusted-positive trusted-positive #:trusted-negative trusted-negative #:recursive-kinds recursive-kinds))
5150
(instantiate sc/opt fail kind #:cache cache #:recursive-kinds recursive-kinds))
5251

5352
;; kind is the greatest kind of contract that is supported, if a greater kind would be produced the

typed-racket-lib/typed-racket/static-contracts/optimize.rkt

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
(provide/cond-contract
20-
[optimize ((static-contract?) (#:trusted-positive boolean? #:trusted-negative boolean?)
20+
[optimize ((static-contract?) (#:trusted-positive boolean? #:trusted-negative boolean? #:recursive-kinds (or/c #f hash?))
2121
. ->* . static-contract?)])
2222

2323
;; Reduce a static contract to a smaller simpler one that protects in the same way
@@ -110,25 +110,22 @@
110110

111111

112112
;; Reduce a static contract assuming that we trusted the current side
113-
(define (trusted-side-reduce sc)
113+
(define (trusted-side-reduce sc flat-sc?)
114114
(match sc
115115
[(->/sc: mand-args opt-args mand-kw-args opt-kw-args rest-arg (list (any/sc:) ...))
116116
(function/sc #t mand-args opt-args mand-kw-args opt-kw-args rest-arg #f)]
117117
[(arr/sc: args rest (list (any/sc:) ...))
118118
(arr/sc args rest #f)]
119119
[(none/sc:) any/sc]
120-
[(or/sc: (? flat-terminal-kind?) ...) any/sc]
121-
[(? flat-terminal-kind?) any/sc]
120+
[(or/sc: (? flat-sc?) ...) any/sc]
121+
[(? flat-sc?) any/sc]
122122
[(syntax/sc: (? recursive-sc?))
123123
;;bg; _temporary_ case to allow contracts from the `Syntax` type.
124124
;; This is temporary until TR has types for immutable-vector
125125
;; and box-immutable & changes the definition of the `Syntax` type.
126126
any/sc]
127127
[else sc]))
128128

129-
(define (flat-terminal-kind? sc)
130-
(eq? 'flat (sc-terminal-kind sc)))
131-
132129
;; The side of a static contract describes the source of the values that
133130
;; the contract needs to check.
134131
;; - 'positive : values exported by the server module
@@ -176,10 +173,10 @@
176173
;; update-side : sc? weak-side? -> weak-side?
177174
;; Change the current side to something safe & strong-as-possible
178175
;; for optimizing the sub-contracts of the given `sc`.
179-
(define (update-side sc side)
176+
(define (update-side sc side flat-sc?)
180177
(match sc
181178
[(or/sc: scs ...)
182-
#:when (not (andmap flat-terminal-kind? scs))
179+
#:when (not (andmap flat-sc? scs))
183180
(weaken-side side)]
184181
[_
185182
#:when (guarded-sc? sc)
@@ -195,8 +192,7 @@
195192
;; type constructor. E.g. list/sc is "real" and or/sc is not.
196193
(define (guarded-sc? sc)
197194
(match sc
198-
[(or (? flat-terminal-kind?)
199-
(->/sc: _ _ _ _ _ _)
195+
[(or (->/sc: _ _ _ _ _ _)
200196
(arr/sc: _ _ _)
201197
(async-channel/sc: _)
202198
(box/sc: _)
@@ -295,7 +291,23 @@
295291

296292

297293
;; If we trust a specific side then we drop all contracts protecting that side.
298-
(define (optimize sc #:trusted-positive [trusted-positive #f] #:trusted-negative [trusted-negative #f])
294+
(define (optimize sc #:trusted-positive [trusted-positive #f] #:trusted-negative [trusted-negative #f] #:recursive-kinds [recursive-kinds #f])
295+
(define sc->kind
296+
(if (not recursive-kinds)
297+
sc-terminal-kind
298+
(λ (sc)
299+
(let loop ([sc sc])
300+
(match sc
301+
[(recursive-sc _ _ body)
302+
(loop body)]
303+
[(or (recursive-sc-use id)
304+
(name/sc: id))
305+
(hash-ref recursive-kinds id #f)]
306+
[_
307+
(sc-terminal-kind sc)])))))
308+
(define (flat-sc? sc)
309+
(eq? 'flat (sc->kind sc)))
310+
299311
;; single-step: reduce and trusted-side-reduce if appropriate
300312
(define (single-step sc maybe-weak-side)
301313
(define trusted
@@ -308,14 +320,14 @@
308320

309321
(reduce
310322
(if trusted
311-
(trusted-side-reduce sc)
323+
(trusted-side-reduce sc flat-sc?)
312324
sc)))
313325

314326
;; full-pass: single-step at every static contract subpart
315327
(define (full-pass sc)
316328
(define ((recur side) sc variance)
317329
(define curr-side (combine-variance side variance))
318-
(define next-side (update-side sc curr-side))
330+
(define next-side (update-side sc curr-side flat-sc?))
319331
(single-step (sc-map sc (recur next-side)) curr-side))
320332
((recur 'positive) sc 'covariant))
321333

0 commit comments

Comments
 (0)