Use the correct field numbers in substructs.
Maintain table of struct accessors/mutators. original commit: 3c8952d63d2cd28a3b5a588c0367b53dc963308b
This commit is contained in:
parent
68ba63ce4d
commit
7f6da53efa
10
collects/tests/typed-scheme/succeed/test-child-field.rkt
Normal file
10
collects/tests/typed-scheme/succeed/test-child-field.rkt
Normal file
|
@ -0,0 +1,10 @@
|
|||
#lang typed/racket
|
||||
|
||||
(define-struct: x ([a : Any]))
|
||||
(define-struct: (A) (y x) ([b : A]))
|
||||
|
||||
(: f : (y Any) -> String)
|
||||
(define (f v)
|
||||
(if (string? (y-b v))
|
||||
(y-b v)
|
||||
"foo"))
|
|
@ -18,8 +18,7 @@
|
|||
(not (ValuesDots? e))
|
||||
(not (Result? e)))))
|
||||
|
||||
(define Type/c
|
||||
(flat-named-contract 'Type Type/c?))
|
||||
(define Type/c (flat-named-contract 'Type Type/c?))
|
||||
|
||||
;; Name = Symbol
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
(require "../utils/utils.rkt"
|
||||
(except-in (rep type-rep free-variance) Dotted)
|
||||
(private parse-type)
|
||||
(types convenience utils union resolve abbrev substitute)
|
||||
(types convenience utils union resolve abbrev substitute type-table)
|
||||
(env global-env type-env-structs type-name-env tvar-env)
|
||||
(utils tc-utils)
|
||||
"def-binding.rkt"
|
||||
|
@ -142,26 +142,31 @@
|
|||
(or (eq? variance Constant)
|
||||
(eq? variance Covariant))))
|
||||
#t)))
|
||||
(define parent-count (- (length external-fld-types) (length external-fld-types/no-parent)))
|
||||
;; the list of names w/ types
|
||||
(define bindings
|
||||
(append
|
||||
(list
|
||||
(cons struct-type-id
|
||||
(make-StructType sty))
|
||||
(cons (or maker* maker)
|
||||
(wrapper (->* external-fld-types (if cret cret name))))
|
||||
(cons (or pred* pred)
|
||||
(make-pred-ty (if (not covariant?)
|
||||
(make-StructTop sty)
|
||||
(pred-wrapper name)))))
|
||||
(for/list ([g (in-list getters)] [t (in-list external-fld-types/no-parent)] [i (in-naturals)])
|
||||
(let ([func (if setters?
|
||||
(->* (list name) t)
|
||||
(->acc (list name) t (list (make-StructPE name i))))])
|
||||
(cons g (wrapper func))))
|
||||
(if setters?
|
||||
(map (lambda (g t) (cons g (wrapper (->* (list name t) -Void)))) setters external-fld-types/no-parent)
|
||||
null)))
|
||||
(list*
|
||||
(cons struct-type-id
|
||||
(make-StructType sty))
|
||||
(cons (or maker* maker)
|
||||
(wrapper (->* external-fld-types (if cret cret name))))
|
||||
(cons (or pred* pred)
|
||||
(make-pred-ty (if (not covariant?)
|
||||
(make-StructTop sty)
|
||||
(pred-wrapper name))))
|
||||
(append
|
||||
(for/list ([g (in-list getters)] [t (in-list external-fld-types/no-parent)] [i (in-naturals parent-count)])
|
||||
(let* ([path (make-StructPE name i)]
|
||||
[func (if setters?
|
||||
(->* (list name) t)
|
||||
(->acc (list name) t (list path)))])
|
||||
(add-struct-fn! g path #f)
|
||||
(cons g (wrapper func))))
|
||||
(if setters?
|
||||
(for/list ([g (in-list setters)] [t (in-list external-fld-types/no-parent)] [i (in-naturals parent-count)])
|
||||
(add-struct-fn! g (make-StructPE name i) #t)
|
||||
(cons g (wrapper (->* (list name t) -Void))))
|
||||
null))))
|
||||
(register-type-name nm (wrapper sty))
|
||||
(cons
|
||||
(make-def-struct-stx-binding nm si)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#lang scheme/base
|
||||
|
||||
(require unstable/debug "../utils/utils.rkt" (rep type-rep) (only-in (types abbrev utils) tc-results?) (utils tc-utils) scheme/contract)
|
||||
(require unstable/debug scheme/contract "../utils/utils.rkt" syntax/id-table racket/dict racket/match
|
||||
(rep type-rep object-rep) (only-in (types abbrev utils) tc-results?) (utils tc-utils))
|
||||
|
||||
(define table (make-hasheq))
|
||||
|
||||
|
@ -12,6 +13,21 @@
|
|||
|
||||
(define (type-of e) (hash-ref table e (lambda () (int-err (format "no type for ~a" (syntax->datum e))))))
|
||||
|
||||
(define struct-fn-table (make-free-id-table))
|
||||
|
||||
(define (add-struct-fn! id pe mut?) (dict-set! struct-fn-table id (list pe mut?)))
|
||||
|
||||
(define-values (struct-accessor? struct-mutator?)
|
||||
(let ()
|
||||
(define ((mk mut?) id)
|
||||
(cond [(dict-ref struct-fn-table id #f)
|
||||
=> (match-lambda [(list pe #f) pe] [_ #f])]
|
||||
[else #f]))
|
||||
(values (mk #f) (mk #t))))
|
||||
|
||||
(p/c [add-typeof-expr (syntax? tc-results? . -> . any/c)]
|
||||
[type-of (syntax? . -> . tc-results?)]
|
||||
[reset-type-table (-> any/c)])
|
||||
[reset-type-table (-> any/c)]
|
||||
[add-struct-fn! (identifier? StructPE? boolean? . -> . any/c)]
|
||||
[struct-accessor? (identifier? . -> . (or/c #f StructPE?))]
|
||||
[struct-mutator? (identifier? . -> . (or/c #f StructPE?))])
|
Loading…
Reference in New Issue
Block a user