fall back to the slow path when application expression looks wrong
closes PR 14279
This commit is contained in:
parent
04628e3516
commit
4d123bb26d
|
@ -1,6 +1,11 @@
|
|||
#lang racket
|
||||
(require rackunit
|
||||
racket/contract/private/arrow)
|
||||
racket/contract/private/arrow
|
||||
|
||||
(for-template racket/contract/private/arrow-val-first)
|
||||
racket/contract/private/application-arity-checking
|
||||
racket/contract/private/arr-i-parse)
|
||||
|
||||
(check-equal? (matches-arity-exactly? (λ () 1) 0 0 '() '()) #t)
|
||||
(check-equal? (matches-arity-exactly? (λ () 1) 1 1 '() '()) #f)
|
||||
(check-equal? (matches-arity-exactly? (λ () 1) 0 1 '() '()) #f)
|
||||
|
@ -65,3 +70,41 @@
|
|||
(check-equal? (matches-arity-exactly? (lambda (x #:y y #:z [z 1]) y)
|
||||
1 1 '() '(#:y #:z))
|
||||
#f)
|
||||
|
||||
|
||||
(check-equal? (->-valid-app-shapes #'(-> integer? integer?))
|
||||
(valid-app-shapes '(1) '() '()))
|
||||
(check-equal? (->-valid-app-shapes #'(-> integer? boolean? integer?))
|
||||
(valid-app-shapes '(2) '() '()))
|
||||
(check-equal? (->-valid-app-shapes #'(-> integer? #:x any/c integer?))
|
||||
(valid-app-shapes '(1) '(#:x) '()))
|
||||
(check-equal? (->-valid-app-shapes #'(-> integer? #:x any/c #:y any/c integer?))
|
||||
(valid-app-shapes '(1) '(#:x #:y) '()))
|
||||
|
||||
(check-equal? (->*-valid-app-shapes #'(->* (integer? #:x any/c #:y any/c) integer?))
|
||||
(valid-app-shapes '(1) '(#:x #:y) '()))
|
||||
(check-equal? (->*-valid-app-shapes #'(->* () (integer? #:x any/c #:y any/c) integer?))
|
||||
(valid-app-shapes '(0 1) '() '(#:x #:y)))
|
||||
(check-equal? (->*-valid-app-shapes #'(->* (any/c) (any/c) #:rest any/c integer?))
|
||||
(valid-app-shapes '(1 2 . 3) '() '()))
|
||||
|
||||
(check-equal? (->i-valid-app-shapes #'(->i () () [r any/c]))
|
||||
(valid-app-shapes '(0) '() '()))
|
||||
(check-equal? (->*-valid-app-shapes #'(->i ([p integer?] #:x [x any/c] #:y [y any/c]) [r any/c]))
|
||||
(valid-app-shapes '(1) '(#:x #:y) '()))
|
||||
(check-equal? (->*-valid-app-shapes #'(->i () ([p integer?] #:x [x any/c] #:y [y any/c]) [r any/c]))
|
||||
(valid-app-shapes '(0 1) '() '(#:x #:y)))
|
||||
(check-equal? (->*-valid-app-shapes #'(->i ([m any/c]) ([o any/c]) #:rest [r any/c] [r any/c]))
|
||||
(valid-app-shapes '(1 2 . 3) '() '()))
|
||||
|
||||
|
||||
(check-true (valid-argument-list? #'(f x) (valid-app-shapes '(1 2 . 3) '() '())))
|
||||
(check-true (valid-argument-list? #'(f x y) (valid-app-shapes '(1 2 . 3) '() '())))
|
||||
(check-true (valid-argument-list? #'(f x y a b c d) (valid-app-shapes '(1 2 . 3) '() '())))
|
||||
(check-false (valid-argument-list? #'(f) (valid-app-shapes '(1 2 . 3) '() '()) #f))
|
||||
(check-true (valid-argument-list? #'(f #:x x) (valid-app-shapes '(0) '(#:x) '())))
|
||||
(check-true (valid-argument-list? #'(f #:x x) (valid-app-shapes '(0) '() '(#:x))))
|
||||
(check-true (valid-argument-list? #'(f) (valid-app-shapes '(0) '() '(#:x))))
|
||||
(check-false (valid-argument-list? #'(f) (valid-app-shapes '(0) '(#:x) '()) #f))
|
||||
(check-false (valid-argument-list? #'(f #:y y) (valid-app-shapes '(0) '(#:x) '()) #f))
|
||||
(check-false (valid-argument-list? #'(f #:x) (valid-app-shapes '(0) '(#:x) '()) #f))
|
||||
|
|
|
@ -938,6 +938,27 @@
|
|||
(eval '(require 'provide/contract48-m1)))
|
||||
"provide/contract48-m1")
|
||||
|
||||
;; test to make sure that arity errors have the
|
||||
;; right name at the beginning of the message
|
||||
(test/spec-passed/result
|
||||
'provide/contract49
|
||||
'(let ()
|
||||
(eval '(module provide/contract49-m1 racket/base
|
||||
(require racket/contract/base)
|
||||
(define (f x) x)
|
||||
(provide (contract-out [f (-> any/c any)]))))
|
||||
(eval '(module provide/contract49-m2 racket/base
|
||||
(require 'provide/contract48-m1)
|
||||
(f 1 2)))
|
||||
(with-handlers ([exn:fail? (λ (x)
|
||||
(define m (regexp-match #rx"([^:]*:)" (exn-message x)))
|
||||
(if m
|
||||
(cadr m)
|
||||
(list "regexp failed to match"
|
||||
(exn-message x))))])
|
||||
(eval '(require 'provide/contract49-m2))))
|
||||
"f:")
|
||||
|
||||
(contract-error-test
|
||||
'contract-error-test8
|
||||
#'(begin
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#lang racket/base
|
||||
|
||||
#|
|
||||
|
||||
Used to check an application site of a well-known
|
||||
contract function to see if the shape is okay.
|
||||
|
||||
That is, each contract builds a valid-app-shapes struct
|
||||
describing what application expression shapes are okay
|
||||
and valid-argument-list? checks an application against
|
||||
a valid-app-shape.
|
||||
|
||||
|#
|
||||
|
||||
(provide (struct-out valid-app-shapes)
|
||||
valid-argument-list?)
|
||||
|
||||
;; valid-arities : (or/c (listof nat) (improper-listof nat))
|
||||
;; -- if improper, then the last nat indicates that any number
|
||||
;; of args equal to or later than that last nat are okay
|
||||
;; mandatory-kwds : (listof keyword?)
|
||||
;; optional-kwds : (or/c (listof keyword?) 'any)
|
||||
;; 'any indicates that any keyword is allowed
|
||||
(struct valid-app-shapes (valid-arities mandatory-kwds optional-kwds)
|
||||
#:prefab)
|
||||
|
||||
(define (valid-argument-list? app-stx the-valid-app-shape [log-problems? #t])
|
||||
(cond
|
||||
[the-valid-app-shape
|
||||
(define-values (kwds arg-count)
|
||||
(let loop ([stx (syntax-case app-stx ()
|
||||
[(function . args) #'args])]
|
||||
[kwds '()]
|
||||
[arg-count 0])
|
||||
(syntax-case stx ()
|
||||
[(kwd kwd-arg . rest)
|
||||
(keyword? (syntax-e #'kwd))
|
||||
(loop #'rest (cons (syntax-e #'kwd) kwds) arg-count)]
|
||||
[(arg . rest)
|
||||
(loop #'rest kwds (+ arg-count 1))]
|
||||
[()
|
||||
(values kwds arg-count)])))
|
||||
|
||||
(define good-arg-count?
|
||||
(let loop ([allowed-counts (valid-app-shapes-valid-arities the-valid-app-shape)])
|
||||
(cond
|
||||
[(null? allowed-counts) #f]
|
||||
[(number? allowed-counts) (arg-count . >= . allowed-counts)]
|
||||
[else (or (= arg-count (car allowed-counts))
|
||||
(loop (cdr allowed-counts)))])))
|
||||
|
||||
(define ans?
|
||||
(and good-arg-count?
|
||||
(for/and ([kwd (in-list (valid-app-shapes-mandatory-kwds the-valid-app-shape))])
|
||||
(member kwd kwds))
|
||||
(for/and ([kwd (in-list kwds)])
|
||||
(or (member kwd (valid-app-shapes-mandatory-kwds the-valid-app-shape))
|
||||
(member kwd (valid-app-shapes-optional-kwds the-valid-app-shape))))
|
||||
#t))
|
||||
(when log-problems?
|
||||
(unless ans?
|
||||
(log-problem app-stx)))
|
||||
ans?]
|
||||
[else #t]))
|
||||
|
||||
(define-logger optimizer)
|
||||
(define (log-problem stx)
|
||||
(log-optimizer-warning
|
||||
"warning in ~a:~a:~a: contract system detects procedure incorrectly applied"
|
||||
(syntax-source stx)
|
||||
(syntax-line stx)
|
||||
(syntax-column stx)))
|
|
@ -6,6 +6,8 @@
|
|||
[make-module-identifier-mapping make-free-identifier-mapping]
|
||||
[module-identifier-mapping-get free-identifier-mapping-get]
|
||||
[module-identifier-mapping-put! free-identifier-mapping-put!])
|
||||
"application-arity-checking.rkt"
|
||||
"arr-util.rkt"
|
||||
(for-template racket/base
|
||||
"misc.rkt"))
|
||||
|
||||
|
@ -498,8 +500,33 @@ code does the parsing and validation of the syntax.
|
|||
[_
|
||||
(raise-syntax-error #f "bad syntax" stx)])))
|
||||
|
||||
(define (->i-valid-app-shapes stx)
|
||||
(define an-istx (parse-->i stx))
|
||||
(define mans 0)
|
||||
(define opts 0)
|
||||
(define man-kwds '())
|
||||
(define opt-kwds '())
|
||||
(for ([arg (in-list (istx-args an-istx))])
|
||||
(define kwd (arg-kwd arg))
|
||||
(define opt? (arg-optional? arg))
|
||||
(cond
|
||||
[(and kwd opt?)
|
||||
(set! opt-kwds (cons kwd opt-kwds))]
|
||||
[(and kwd (not opt?))
|
||||
(set! man-kwds (cons kwd man-kwds))]
|
||||
[(and (not kwd) opt?)
|
||||
(set! opts (+ opts 1))]
|
||||
[(and (not kwd) (not opt?))
|
||||
(set! mans (+ mans 1))]))
|
||||
(valid-app-shapes-from-man/opts mans
|
||||
opts
|
||||
(istx-rst an-istx)
|
||||
man-kwds
|
||||
opt-kwds))
|
||||
|
||||
(provide
|
||||
parse-->i
|
||||
->i-valid-app-shapes
|
||||
(struct-out istx)
|
||||
(struct-out arg/res)
|
||||
(struct-out arg)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "application-arity-checking.rkt")
|
||||
(provide split-doms
|
||||
sort-keywords)
|
||||
sort-keywords
|
||||
valid-app-shapes-from-man/opts)
|
||||
|
||||
;; split-doms : syntax identifier syntax -> syntax
|
||||
;; given a sequence of keywords interpersed with other
|
||||
|
@ -59,3 +61,19 @@
|
|||
(cond
|
||||
[(null? pairs) null]
|
||||
[else (insert (car pairs) (loop (cdr pairs)))])))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(define (valid-app-shapes-from-man/opts min-arg-length num-of-opts rest? man-kwds opt-kwds)
|
||||
(define opt+man-dom-lengths
|
||||
(for/list ([i (in-range (+ num-of-opts 1))])
|
||||
(+ i min-arg-length)))
|
||||
(valid-app-shapes (if rest?
|
||||
(append opt+man-dom-lengths
|
||||
(+ min-arg-length num-of-opts 1))
|
||||
opt+man-dom-lengths)
|
||||
man-kwds
|
||||
opt-kwds))
|
|
@ -1,5 +1,6 @@
|
|||
#lang racket/base
|
||||
(require (for-syntax racket/base
|
||||
"application-arity-checking.rkt"
|
||||
"arr-util.rkt")
|
||||
"kwd-info-struct.rkt"
|
||||
"arity-checking.rkt"
|
||||
|
@ -14,7 +15,9 @@
|
|||
|
||||
(provide ->2 ->*2
|
||||
(for-syntax ->2-handled?
|
||||
->*2-handled?))
|
||||
->*2-handled?
|
||||
->-valid-app-shapes
|
||||
->*-valid-app-shapes))
|
||||
|
||||
(define-for-syntax (->2-handled? stx)
|
||||
(syntax-case stx (any values any/c)
|
||||
|
@ -444,6 +447,17 @@
|
|||
this->)]
|
||||
let-bindings))]))])))
|
||||
|
||||
(define-for-syntax (->-valid-app-shapes stx)
|
||||
(syntax-case stx ()
|
||||
[(_ args ...)
|
||||
(let ()
|
||||
(define this-> (gensym 'this->))
|
||||
(define-values (regular-args kwds kwd-args let-bindings)
|
||||
(parse-arrow-args stx (syntax->list #'(args ...)) this->))
|
||||
(valid-app-shapes (list (- (length regular-args) 1))
|
||||
(map syntax->datum kwds)
|
||||
'()))]))
|
||||
|
||||
(define-syntax (->2 stx)
|
||||
(syntax-case stx ()
|
||||
[(_ args ...)
|
||||
|
@ -521,61 +535,94 @@
|
|||
kwd-doms
|
||||
(cons #`[t x] let-bindings)))])))
|
||||
|
||||
(define-for-syntax (parse->*2 stx)
|
||||
(syntax-case stx ()
|
||||
[(_ (raw-mandatory-dom ...) . other)
|
||||
(let ()
|
||||
(define-values (raw-optional-doms rest-ctc pre rng-ctcs post)
|
||||
(arrow:parse-leftover->* stx #'other))
|
||||
(with-syntax ([(man-dom
|
||||
man-dom-kwds
|
||||
man-lets)
|
||||
(:split-doms stx '->* #'(raw-mandatory-dom ...))]
|
||||
[(opt-dom
|
||||
opt-dom-kwds
|
||||
opt-lets)
|
||||
(:split-doms stx '->* raw-optional-doms)])
|
||||
(values
|
||||
#'man-dom
|
||||
#'man-dom-kwds
|
||||
#'man-lets
|
||||
#'opt-dom
|
||||
#'opt-dom-kwds
|
||||
#'opt-lets
|
||||
rest-ctc pre rng-ctcs post)))]))
|
||||
|
||||
(define-for-syntax (->*-valid-app-shapes stx)
|
||||
(define-values (man-dom man-dom-kwds man-lets
|
||||
opt-dom opt-dom-kwds opt-lets
|
||||
rest-ctc pre rng-ctcs post)
|
||||
(parse->*2 stx))
|
||||
(with-syntax ([((mandatory-dom-kwd mandatory-dom-kwd-ctc) ...) man-dom-kwds]
|
||||
[((optional-dom-kwd optional-dom-kwd-ctc) ...) opt-dom-kwds])
|
||||
(valid-app-shapes-from-man/opts (length (syntax->list man-dom))
|
||||
(length (syntax->list opt-dom))
|
||||
rest-ctc
|
||||
(syntax->datum #'(mandatory-dom-kwd ...))
|
||||
(syntax->datum #'(optional-dom-kwd ...)))))
|
||||
|
||||
(define-syntax (->*2 stx)
|
||||
(cond
|
||||
[(->*2-handled? stx)
|
||||
(syntax-case stx ()
|
||||
[(_ (raw-mandatory-dom ...) . other)
|
||||
(let ()
|
||||
(define-values (raw-optional-doms rest-ctc pre rng-ctcs post)
|
||||
(arrow:parse-leftover->* stx #'other))
|
||||
(with-syntax ([((mandatory-dom ...)
|
||||
((mandatory-dom-kwd mandatory-dom-kwd-ctc) ...)
|
||||
(mandatory-let-bindings ...))
|
||||
(:split-doms stx '->* #'(raw-mandatory-dom ...))]
|
||||
[((optional-dom ...)
|
||||
((optional-dom-kwd optional-dom-kwd-ctc) ...)
|
||||
(optional-let-bindings ...))
|
||||
(:split-doms stx '->* raw-optional-doms)]
|
||||
[(pre-x post-x) (generate-temporaries '(pre-cond post-cond))])
|
||||
(with-syntax ([((kwd dom opt?) ...) #'((mandatory-dom-kwd mandatory-dom-kwd-ctc #f) ...
|
||||
(optional-dom-kwd optional-dom-kwd-ctc #t) ...)]
|
||||
[(pre-let-binding ...) (if pre
|
||||
(list #`[pre-x (λ () #,pre)])
|
||||
(list))]
|
||||
[(post-let-binding ...) (if post
|
||||
(list #`[post-x (λ () #,post)])
|
||||
(list))])
|
||||
(define-values (plus-one-arity-function chaperone-constructor)
|
||||
(build-plus-one-arity-function+chaperone-constructor
|
||||
stx
|
||||
(syntax->list #'(mandatory-dom ...))
|
||||
(syntax->list #'(optional-dom ...))
|
||||
(syntax->list #'(mandatory-dom-kwd ...))
|
||||
(syntax->list #'(optional-dom-kwd ...))
|
||||
(and pre #'pre-x)
|
||||
rest-ctc
|
||||
rng-ctcs
|
||||
(and post #'post-x)))
|
||||
#`(let (mandatory-let-bindings ...
|
||||
optional-let-bindings ...
|
||||
pre-let-binding ...
|
||||
post-let-binding ...)
|
||||
(build--> '->*
|
||||
(list mandatory-dom ...)
|
||||
(list optional-dom ...)
|
||||
'(mandatory-dom-kwd ...)
|
||||
(list mandatory-dom-kwd-ctc ...)
|
||||
'(optional-dom-kwd ...)
|
||||
(list optional-dom-kwd-ctc ...)
|
||||
#,rest-ctc
|
||||
#,(and pre #t)
|
||||
#,(if rng-ctcs
|
||||
#`(list #,@rng-ctcs)
|
||||
#'#f)
|
||||
#,(and post #t)
|
||||
#,plus-one-arity-function
|
||||
#,chaperone-constructor)))))])]
|
||||
(define-values (man-dom man-dom-kwds man-lets
|
||||
opt-dom opt-dom-kwds opt-lets
|
||||
rest-ctc pre rng-ctcs post)
|
||||
(parse->*2 stx))
|
||||
(with-syntax ([(mandatory-dom ...) man-dom]
|
||||
[((mandatory-dom-kwd mandatory-dom-kwd-ctc) ...) man-dom-kwds]
|
||||
[(mandatory-let-bindings ...) man-lets]
|
||||
[(optional-dom ...) opt-dom]
|
||||
[((optional-dom-kwd optional-dom-kwd-ctc) ...) opt-dom-kwds]
|
||||
[(optional-let-bindings ...) opt-lets]
|
||||
[(pre-x post-x) (generate-temporaries '(pre-cond post-cond))])
|
||||
(with-syntax ([((kwd dom opt?) ...) #'((mandatory-dom-kwd mandatory-dom-kwd-ctc #f) ...
|
||||
(optional-dom-kwd optional-dom-kwd-ctc #t) ...)]
|
||||
[(pre-let-binding ...) (if pre
|
||||
(list #`[pre-x (λ () #,pre)])
|
||||
(list))]
|
||||
[(post-let-binding ...) (if post
|
||||
(list #`[post-x (λ () #,post)])
|
||||
(list))])
|
||||
(define-values (plus-one-arity-function chaperone-constructor)
|
||||
(build-plus-one-arity-function+chaperone-constructor
|
||||
stx
|
||||
(syntax->list #'(mandatory-dom ...))
|
||||
(syntax->list #'(optional-dom ...))
|
||||
(syntax->list #'(mandatory-dom-kwd ...))
|
||||
(syntax->list #'(optional-dom-kwd ...))
|
||||
(and pre #'pre-x)
|
||||
rest-ctc
|
||||
rng-ctcs
|
||||
(and post #'post-x)))
|
||||
#`(let (mandatory-let-bindings ...
|
||||
optional-let-bindings ...
|
||||
pre-let-binding ...
|
||||
post-let-binding ...)
|
||||
(build--> '->*
|
||||
(list mandatory-dom ...)
|
||||
(list optional-dom ...)
|
||||
'(mandatory-dom-kwd ...)
|
||||
(list mandatory-dom-kwd-ctc ...)
|
||||
'(optional-dom-kwd ...)
|
||||
(list optional-dom-kwd-ctc ...)
|
||||
#,rest-ctc
|
||||
#,(and pre #t)
|
||||
#,(if rng-ctcs
|
||||
#`(list #,@rng-ctcs)
|
||||
#'#f)
|
||||
#,(and post #t)
|
||||
#,plus-one-arity-function
|
||||
#,chaperone-constructor))))]
|
||||
[else
|
||||
(syntax-case stx ()
|
||||
[(_ args ...)
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
racket/list
|
||||
racket/struct-info
|
||||
setup/path-to-relative
|
||||
"application-arity-checking.rkt"
|
||||
"arr-i-parse.rkt"
|
||||
(prefix-in a: "helpers.rkt")
|
||||
(rename-in syntax/private/boundmap
|
||||
;; the private version of the library
|
||||
|
@ -56,11 +58,13 @@
|
|||
|
||||
(struct provide/contract-info (contract-id original-id))
|
||||
|
||||
|
||||
(struct provide/contract-arrow-transformer provide/contract-info
|
||||
(saved-id-table
|
||||
saved-ho-id-table
|
||||
partially-applied-id
|
||||
extra-neg-party-argument-fn)
|
||||
extra-neg-party-argument-fn
|
||||
valid-argument-lists)
|
||||
#:property
|
||||
prop:set!-transformer
|
||||
(λ (self stx)
|
||||
|
@ -68,7 +72,8 @@
|
|||
[saved-id-table (provide/contract-arrow-transformer-saved-id-table self)]
|
||||
[saved-ho-id-table (provide/contract-arrow-transformer-saved-ho-id-table self)]
|
||||
[extra-neg-party-argument-fn
|
||||
(provide/contract-arrow-transformer-extra-neg-party-argument-fn self)])
|
||||
(provide/contract-arrow-transformer-extra-neg-party-argument-fn self)]
|
||||
[valid-arg-lists (provide/contract-arrow-transformer-valid-argument-lists self)])
|
||||
(with-syntax ([partially-applied-id partially-applied-id]
|
||||
[extra-neg-party-argument-fn extra-neg-party-argument-fn])
|
||||
(if (eq? 'expression (syntax-local-context))
|
||||
|
@ -85,34 +90,40 @@
|
|||
;; Expand to a use of the lifted expression:
|
||||
(define (adjust-location new-stx)
|
||||
(datum->syntax new-stx (syntax-e new-stx) stx new-stx))
|
||||
(with-syntax ([lifted-neg-party (syntax-local-introduce lifted-neg-party)])
|
||||
(syntax-case stx (set!)
|
||||
[name
|
||||
(identifier? #'name)
|
||||
(let ([lifted-ctc-val
|
||||
(or (hash-ref saved-ho-id-table key #f)
|
||||
;; No: lift the neg name creation
|
||||
(syntax-local-introduce
|
||||
(syntax-local-lift-expression
|
||||
#'(partially-applied-id lifted-neg-party))))])
|
||||
(when key (hash-set! saved-ho-id-table key lifted-ctc-val))
|
||||
(adjust-location (syntax-local-introduce lifted-ctc-val)))]
|
||||
[(set! id arg)
|
||||
(raise-syntax-error
|
||||
'contract/out
|
||||
"cannot set! a contract/out variable"
|
||||
stx #'id)]
|
||||
[(name more ...)
|
||||
(with-syntax ([app (datum->syntax stx '#%app)])
|
||||
(adjust-location
|
||||
#'(app extra-neg-party-argument-fn
|
||||
lifted-neg-party
|
||||
more ...)))])))
|
||||
(define (gen-slow-path-code)
|
||||
(define lifted-ctc-val
|
||||
(or (hash-ref saved-ho-id-table key #f)
|
||||
;; No: lift the neg name creation
|
||||
(with-syntax ([lifted-neg-party (syntax-local-introduce lifted-neg-party)])
|
||||
(syntax-local-introduce
|
||||
(syntax-local-lift-expression
|
||||
#'(partially-applied-id lifted-neg-party))))))
|
||||
(when key (hash-set! saved-ho-id-table key lifted-ctc-val))
|
||||
(adjust-location (syntax-local-introduce lifted-ctc-val)))
|
||||
(syntax-case stx (set!)
|
||||
[name
|
||||
(identifier? #'name)
|
||||
(gen-slow-path-code)]
|
||||
[(set! id arg)
|
||||
(raise-syntax-error
|
||||
'contract/out
|
||||
"cannot set! a contract/out variable"
|
||||
stx #'id)]
|
||||
[(name more ...)
|
||||
(with-syntax ([app (datum->syntax stx '#%app)])
|
||||
(if (valid-argument-list? stx valid-arg-lists)
|
||||
(with-syntax ([lifted-neg-party (syntax-local-introduce lifted-neg-party)])
|
||||
(adjust-location
|
||||
#'(app extra-neg-party-argument-fn
|
||||
lifted-neg-party
|
||||
more ...)))
|
||||
#`(app #,(gen-slow-path-code) more ...)))]))
|
||||
;; In case of partial expansion for module-level and internal-defn
|
||||
;; contexts, delay expansion until it's a good time to lift
|
||||
;; expressions:
|
||||
(quasisyntax/loc stx (#%expression #,stx)))))))
|
||||
|
||||
|
||||
(struct provide/contract-transformer provide/contract-info (saved-id-table partially-applied-id)
|
||||
#:property
|
||||
prop:set!-transformer
|
||||
|
@ -167,10 +178,10 @@
|
|||
#`(app #,id args ...))]
|
||||
[x (identifier? #'x) id])))))
|
||||
|
||||
(define (make-provide/contract-arrow-transformer contract-id id pai enpfn)
|
||||
(define (make-provide/contract-arrow-transformer contract-id id pai enpfn val)
|
||||
(provide/contract-arrow-transformer contract-id id
|
||||
(make-hasheq) (make-hasheq)
|
||||
pai enpfn)))
|
||||
pai enpfn val)))
|
||||
|
||||
|
||||
;; tl-code-for-one-id/new-name : syntax syntax syntax (union syntax #f) -> (values syntax syntax)
|
||||
|
@ -234,12 +245,16 @@
|
|||
srcloc-expr
|
||||
contract-error-name
|
||||
pos-module-source)
|
||||
(define arrow?
|
||||
(define-values (arrow? the-valid-app-shapes)
|
||||
(syntax-case ctrct (->2 ->*2 ->i)
|
||||
[(->2 . _) (->2-handled? ctrct)]
|
||||
[(->*2 . _) (->*2-handled? ctrct)]
|
||||
[(->i . _) #t]
|
||||
[_ #f]))
|
||||
[(->2 . _)
|
||||
(->2-handled? ctrct)
|
||||
(values #t (->-valid-app-shapes ctrct))]
|
||||
[(->*2 . _)
|
||||
(values (->*2-handled? ctrct)
|
||||
(->*-valid-app-shapes ctrct))]
|
||||
[(->i . _) (values #t (->i-valid-app-shapes ctrct))]
|
||||
[_ (values #f #f)]))
|
||||
(with-syntax ([id id]
|
||||
[(partially-applied-id extra-neg-party-argument-fn contract-id)
|
||||
(generate-temporaries (list 'idX 'idY 'idZ))]
|
||||
|
@ -267,10 +282,11 @@
|
|||
|
||||
(define-syntax #,id-rename
|
||||
#,(if arrow?
|
||||
#'(make-provide/contract-arrow-transformer
|
||||
#`(make-provide/contract-arrow-transformer
|
||||
(quote-syntax contract-id) (quote-syntax id)
|
||||
(quote-syntax partially-applied-id)
|
||||
(quote-syntax extra-neg-party-argument-fn))
|
||||
(quote-syntax extra-neg-party-argument-fn)
|
||||
#,the-valid-app-shapes)
|
||||
#'(make-provide/contract-transformer
|
||||
(quote-syntax contract-id) (quote-syntax id)
|
||||
#f #f
|
||||
|
|
Loading…
Reference in New Issue
Block a user