Handle complicated parametric types in TR contract generation.
Closes PR 14270. original commit: f394d3d26069467e8e6d023e5202b3b37e59ea0e
This commit is contained in:
parent
efe4dc50ba
commit
041577d7bb
|
@ -55,4 +55,4 @@
|
|||
values))
|
||||
|
||||
(define (variable-ref v)
|
||||
(hash-ref (current-variable-values) v))
|
||||
(hash-ref (current-variable-values) v (lambda () (error 'variable-ref "No value available."))))
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
#lang racket/base
|
||||
|
||||
;; Implements a check that to determine if a part of a static contract has two (or more) parametric
|
||||
;; contracts as direct descendents.
|
||||
|
||||
(require
|
||||
racket/match
|
||||
racket/contract
|
||||
(except-in "structures.rkt" recursive-contract)
|
||||
|
||||
[except-in racket/contract recursive-contract]
|
||||
racket/dict
|
||||
syntax/id-table
|
||||
"structures.rkt"
|
||||
"equations.rkt"
|
||||
"combinators/parametric.rkt"
|
||||
"combinators/structural.rkt")
|
||||
|
||||
|
@ -11,16 +18,38 @@
|
|||
(contract-out
|
||||
[parametric-check (static-contract? . -> . boolean?)]))
|
||||
|
||||
|
||||
(define (parametric-check sc)
|
||||
(let/ec exit
|
||||
(define (recur sc variance)
|
||||
(match sc
|
||||
[(or/sc: elems ...) (=> continue)
|
||||
(match elems
|
||||
[(list-no-order (parametric-var/sc: _) (parametric-var/sc: _) others ...)
|
||||
(exit #t)]
|
||||
[else (continue)])]
|
||||
[else
|
||||
(sc-traverse sc recur)]))
|
||||
(recur sc 'covariant)
|
||||
#f))
|
||||
|
||||
(define eqs (make-equation-set))
|
||||
(define vars (make-hash))
|
||||
(define rec-vars (make-free-id-table))
|
||||
|
||||
(define (get-var sc)
|
||||
(hash-ref! vars sc (lambda () (add-variable! eqs 0))))
|
||||
(define (get-rec-var id)
|
||||
(dict-ref! rec-vars id (lambda () (add-variable! eqs 0))))
|
||||
|
||||
(define (recur sc variance)
|
||||
(match sc
|
||||
[(or (or/sc: elems ...) (and/sc: elems ...))
|
||||
(add-equation! eqs (get-var sc)
|
||||
(lambda () (for/sum ((e elems))
|
||||
(variable-ref (get-var e)))))]
|
||||
[(parametric-var/sc: id)
|
||||
(add-equation! eqs (get-var sc) (lambda () 1))]
|
||||
[(recursive-contract names values body)
|
||||
(for ([name names] [value values])
|
||||
(add-equation! eqs (get-rec-var name) (lambda () (variable-ref (get-var value)))))
|
||||
(add-equation! eqs (get-var sc) (lambda () (variable-ref (get-var body))))]
|
||||
[(recursive-contract-use id)
|
||||
(add-equation! eqs (get-var sc) (lambda () (variable-ref (get-rec-var id))))]
|
||||
[else
|
||||
(get-var sc)])
|
||||
(sc-traverse sc recur))
|
||||
|
||||
(recur sc 'covariant)
|
||||
|
||||
(for/or ([(k v) (in-hash (resolve-equations eqs))]
|
||||
#:when (>= v 2))
|
||||
#t))
|
||||
|
|
|
@ -68,11 +68,17 @@
|
|||
(t (-poly (a) (-set -Number)))
|
||||
(t (-poly (a) (-lst a)))
|
||||
(t (-poly (a) (-vec a)))
|
||||
(t (-> (-poly (A B) (-> (Un A (-mu X (Un A (-lst X)))) (Un A (-mu X (Un A (-lst X))))))
|
||||
(-> -Symbol (-mu X (Un -Symbol (-lst X))))))
|
||||
|
||||
(t/fail ((-poly (a) (-vec a)) . -> . -Symbol)
|
||||
"cannot generate contract for non-function polymorphic type")
|
||||
(t/fail (-> (-poly (a b) (-> (Un a b) (Un a b))) Univ)
|
||||
"multiple parametric contracts are not supported")
|
||||
(t/fail
|
||||
(-> (-poly (A B) (-> (Un B (-mu X (Un A (-lst X)))) (Un B (-mu X (Un A (-lst X))))))
|
||||
(-> -Symbol (-mu X (Un -Symbol (-lst X)))))
|
||||
"multiple parametric contracts are not supported")
|
||||
|
||||
|
||||
(t/fail
|
||||
|
|
Loading…
Reference in New Issue
Block a user