fix struct-info related bug in provide/contract
that John Clements pointed out on the Racket mailing list
This commit is contained in:
parent
ca9e8d742f
commit
4eba0862cf
|
@ -321,19 +321,20 @@
|
||||||
#f
|
#f
|
||||||
(car (car pp)))))]
|
(car (car pp)))))]
|
||||||
|
|
||||||
[struct-info (a:lookup-struct-info struct-name-position provide-stx)]
|
[the-struct-info (a:lookup-struct-info struct-name-position provide-stx)]
|
||||||
[constructor-id (list-ref struct-info 1)]
|
[constructor-id (list-ref the-struct-info 1)]
|
||||||
[predicate-id (list-ref struct-info 2)]
|
[predicate-id (list-ref the-struct-info 2)]
|
||||||
[selector-ids (reverse (list-ref struct-info 3))]
|
[selector-ids (reverse (list-ref the-struct-info 3))]
|
||||||
[type-is-only-constructor? (free-identifier=? constructor-id struct-name)]
|
[type-is-only-constructor? (free-identifier=? constructor-id struct-name)]
|
||||||
[type-is-constructor? #t] ; I think there's no way to detect when the struct-name binding isn't a constructor
|
[type-is-constructor? #t] ; I think there's no way to detect when the struct-name binding isn't a constructor
|
||||||
|
[chaperone-constructor-id (and constructor-id (car (generate-temporaries (list constructor-id))))]
|
||||||
[is-id-ok?
|
[is-id-ok?
|
||||||
(λ (id i)
|
(λ (id i)
|
||||||
(if (or (not parent-struct-count)
|
(if (or (not parent-struct-count)
|
||||||
(parent-struct-count . <= . i))
|
(parent-struct-count . <= . i))
|
||||||
id
|
id
|
||||||
#t))]
|
#t))]
|
||||||
[mutator-ids (reverse (list-ref struct-info 4))] ;; (listof (union #f identifier))
|
[mutator-ids (reverse (list-ref the-struct-info 4))] ;; (listof (union #f identifier))
|
||||||
[field-contract-ids (map (λ (field-name field-contract)
|
[field-contract-ids (map (λ (field-name field-contract)
|
||||||
(if (a:known-good-contract? field-contract)
|
(if (a:known-good-contract? field-contract)
|
||||||
field-contract
|
field-contract
|
||||||
|
@ -483,11 +484,11 @@
|
||||||
[(constructor-code constructor-new-name)
|
[(constructor-code constructor-new-name)
|
||||||
(code-for-one-id/new-name
|
(code-for-one-id/new-name
|
||||||
stx
|
stx
|
||||||
constructor-id struct-name
|
chaperone-constructor-id struct-name
|
||||||
(build-constructor-contract stx
|
(build-constructor-contract stx
|
||||||
field-contract-ids
|
field-contract-ids
|
||||||
predicate-id)
|
predicate-id)
|
||||||
#f
|
constructor-id
|
||||||
#t
|
#t
|
||||||
(not type-is-only-constructor?))]
|
(not type-is-only-constructor?))]
|
||||||
|
|
||||||
|
@ -550,14 +551,20 @@
|
||||||
[struct:struct-name struct:struct-name]
|
[struct:struct-name struct:struct-name]
|
||||||
[-struct:struct-name -struct:struct-name]
|
[-struct:struct-name -struct:struct-name]
|
||||||
[struct-name struct-name]
|
[struct-name struct-name]
|
||||||
[(selector-ids ...) selector-ids])
|
[(selector-ids ...) selector-ids]
|
||||||
(syntax/loc stx
|
[(constructor-args ...) (generate-temporaries selector-ids)])
|
||||||
|
(quasisyntax/loc stx
|
||||||
(begin
|
(begin
|
||||||
struct-code
|
struct-code
|
||||||
field-contract-id-definitions ...
|
field-contract-id-definitions ...
|
||||||
selector-codes ...
|
selector-codes ...
|
||||||
mutator-codes ...
|
mutator-codes ...
|
||||||
predicate-code
|
predicate-code
|
||||||
|
(define (#,chaperone-constructor-id constructor-args ...)
|
||||||
|
(chaperone-struct (#,constructor-id constructor-args ...)
|
||||||
|
struct-info
|
||||||
|
(λ (struct-type skipped?)
|
||||||
|
(values -struct:struct-name skipped?))))
|
||||||
constructor-code
|
constructor-code
|
||||||
|
|
||||||
;; expanding out the body of the `make-pc-struct-type' function
|
;; expanding out the body of the `make-pc-struct-type' function
|
||||||
|
@ -695,8 +702,7 @@
|
||||||
[ex-id ex-id]
|
[ex-id ex-id]
|
||||||
[ctrct (syntax-property ctrct 'inferred-name ex-id)]
|
[ctrct (syntax-property ctrct 'inferred-name ex-id)]
|
||||||
[external-name (or user-rename-id id)]
|
[external-name (or user-rename-id id)]
|
||||||
[reflect-external-name (or user-rename-id ex-id)]
|
[reflect-external-name (or user-rename-id ex-id)])
|
||||||
[where-stx stx])
|
|
||||||
(with-syntax ([extra-test
|
(with-syntax ([extra-test
|
||||||
(syntax-case #'ctrct (->)
|
(syntax-case #'ctrct (->)
|
||||||
[(-> dom ... arg)
|
[(-> dom ... arg)
|
||||||
|
@ -807,6 +813,28 @@
|
||||||
stx)]))
|
stx)]))
|
||||||
|
|
||||||
(define (make-pc-struct-type struct-name struct:struct-name . ctcs)
|
(define (make-pc-struct-type struct-name struct:struct-name . ctcs)
|
||||||
|
(chaperone-struct-type
|
||||||
|
struct:struct-name
|
||||||
|
(λ (a b c d e f g h) (values a b c d e f g h))
|
||||||
|
(λ (x) x)
|
||||||
|
(λ args
|
||||||
|
(let ([vals (let loop ([args args])
|
||||||
|
(cond
|
||||||
|
[(null? args) null]
|
||||||
|
[(null? (cdr args)) null]
|
||||||
|
[else (cons (car args) (loop (cdr args)))]))])
|
||||||
|
(apply values
|
||||||
|
(map (λ (ctc val)
|
||||||
|
(contract ctc
|
||||||
|
val
|
||||||
|
'not-enough-info-for-blame
|
||||||
|
'not-enough-info-for-blame
|
||||||
|
'#f
|
||||||
|
(build-source-location #f)))
|
||||||
|
ctcs
|
||||||
|
vals)))))
|
||||||
|
|
||||||
|
#;
|
||||||
(let-values ([(struct:struct-name _make _pred _get _set)
|
(let-values ([(struct:struct-name _make _pred _get _set)
|
||||||
(make-struct-type struct-name
|
(make-struct-type struct-name
|
||||||
struct:struct-name
|
struct:struct-name
|
||||||
|
@ -833,4 +861,4 @@
|
||||||
(build-source-location #f)))
|
(build-source-location #f)))
|
||||||
ctcs
|
ctcs
|
||||||
vals)))))])
|
vals)))))])
|
||||||
struct:struct-name))
|
(values struct:struct-name _make)))
|
||||||
|
|
|
@ -11712,6 +11712,24 @@ so that propagation occurs.
|
||||||
(eval '(require 'provide/contract37-n)))
|
(eval '(require 'provide/contract37-n)))
|
||||||
"provide/contract37-n")
|
"provide/contract37-n")
|
||||||
|
|
||||||
|
(test/spec-passed/result
|
||||||
|
'provide/contract38
|
||||||
|
'(begin
|
||||||
|
(eval
|
||||||
|
'(module provide/contract38-a racket
|
||||||
|
(define-struct s () #:transparent)
|
||||||
|
(provide/contract [struct s ()])))
|
||||||
|
|
||||||
|
(eval
|
||||||
|
'(module provide/contract38-b racket
|
||||||
|
(require 'provide/contract38-a)
|
||||||
|
(define a-struct (make-s))
|
||||||
|
(define-values (type _) (struct-info a-struct))
|
||||||
|
(provide the-answer)
|
||||||
|
(define the-answer (eq? type struct:s))))
|
||||||
|
|
||||||
|
(dynamic-require ''provide/contract38-b 'the-answer))
|
||||||
|
#t)
|
||||||
|
|
||||||
(contract-error-test
|
(contract-error-test
|
||||||
'contract-error-test8
|
'contract-error-test8
|
||||||
|
|
Loading…
Reference in New Issue
Block a user