Skip to content

Commit 76f4cc5

Browse files
authored
fix a bug where re-exported struct names via require/typed/provide don't have struct infomation (#1078)
* struct: repair reexported struct info via require/typed/provide
1 parent 4a9cbf7 commit 76f4cc5

File tree

8 files changed

+100
-45
lines changed

8 files changed

+100
-45
lines changed

typed-racket-lib/typed-racket/base-env/prims-contract.rkt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@
3939
#'(begin (provide (rename-out [names id] ...))
4040
(define-syntax (names stx) (id stx)) ...))]))
4141
(def require/opaque-type
42-
require-typed-signature
43-
require-typed-struct-legacy
44-
require-typed-struct
45-
require/typed-legacy require/typed require/typed/provide
46-
require-typed-struct/provide make-predicate define-predicate)
42+
require-typed-signature
43+
require-typed-struct-legacy
44+
require-typed-struct
45+
require/typed-legacy require/typed require/typed/provide
46+
require-typed-struct/provide make-predicate define-predicate)
4747

4848
;; Expand `cast` to a `core-cast` with an extra `#%expression` in order
4949
;; to prevent the contract generation pass from executing too early
@@ -448,7 +448,7 @@
448448
;The actual identifier bound to the constructor
449449
[real-maker (if (syntax-e #'id-is-ctor?) #'internal-maker #'maker-name)]
450450
[extra-maker (and (attribute input-maker.extra)
451-
(not (bound-identifier=? #'make-name #'nm))
451+
(not (bound-identifier=? #'maker-name #'nm))
452452
#'maker-name)]
453453
[type (if (stx-null? #'(tvar ...))
454454
#'type
@@ -524,7 +524,7 @@
524524
(make-struct-info-wrapper* #'internal-maker si #'type)
525525
si))
526526

527-
(dtsi* (tvar ...) spec type (body ...) #:maker maker-name #:type-only)
527+
(dtsi* (tvar ...) spec type (body ...) #:maker maker-name)
528528
#,(ignore #'(require/contract pred hidden (or/c struct-predicate-procedure?/c (c-> any-wrap/c boolean?)) lib))
529529
#,(internal #`(require/typed-internal hidden (Any -> Boolean :
530530
#,(if (stx-null? #'(tvar ...))

typed-racket-lib/typed-racket/typecheck/def-binding.rkt

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,25 @@
4242
identifier? identifier?
4343
(values syntax? syntax? identifier? (listof (list/c identifier? identifier?))))
4444
(match-define (def-binding internal-id ty) me)
45-
(with-syntax* ([id internal-id]
46-
[untyped-id (freshen-id #'id)]
47-
[local-untyped-id (freshen-id #'id)]
48-
[export-id new-id])
49-
(define/with-syntax ctc (generate-temporary 'generated-contract))
50-
;; Create the definitions of the contract and the contracted export.
51-
(define/with-syntax definitions
52-
(contract-def/provide-property
53-
#'(define-values (ctc) #f)
54-
(list ty #'untyped-id #'id pos-blame-id)))
55-
(values
56-
;; For the submodule
57-
#`(begin definitions (provide untyped-id))
58-
;; For the main module
59-
#`(begin (define-syntax local-untyped-id (#,mk-redirect-id (quote-syntax untyped-id)))
60-
(define-syntax export-id
61-
(make-typed-renaming #'id #'local-untyped-id)))
62-
new-id
63-
null)))])
45+
(with-syntax* ([id internal-id]
46+
[untyped-id (freshen-id #'id)]
47+
[local-untyped-id (freshen-id #'id)]
48+
[export-id new-id])
49+
(define/with-syntax ctc (generate-temporary 'generated-contract))
50+
;; Create the definitions of the contract and the contracted export.
51+
(define/with-syntax definitions
52+
(contract-def/provide-property
53+
#'(define-values (ctc) #f)
54+
(list ty #'untyped-id #'id pos-blame-id)))
55+
(values
56+
;; For the submodule
57+
#`(begin definitions (provide untyped-id))
58+
;; For the main module
59+
#`(begin (define-syntax local-untyped-id (#,mk-redirect-id (quote-syntax untyped-id)))
60+
(define-syntax export-id
61+
(make-typed-renaming #'id #'local-untyped-id)))
62+
new-id
63+
null)))])
6464

6565
(define-struct (def-stx-binding binding) () #:transparent
6666
#:methods gen:providable
@@ -107,8 +107,9 @@
107107
(mk-ignored-quad e))))
108108

109109
(define sname-is-constructor? (and (or extra-constr-name (free-identifier=? sname constructor-name)) #t))
110-
(define constr (or extra-constr-name constr^))
110+
(define constr (or extra-constr-name constructor-name))
111111
(define type-is-sname? (free-identifier=? tname internal-id))
112+
112113
;; Here, we recursively handle all of the identifiers referenced
113114
;; in this static struct info.
114115
(define-values (constr-defn constr-export-defn constr-new-id constr-aliases)
@@ -118,7 +119,9 @@
118119
;; avoid generating the quad for constr twice.
119120
;; skip it when the binding is for the type name
120121
[(and (free-identifier=? internal-id sname) (free-identifier=? constr internal-id))
121-
(super-mk-quad (make-def-binding constr constr-type) (freshen-id constr) def-tbl pos-blame-id mk-redirect-id)]
122+
(super-mk-quad (make-def-binding constr constr-type)
123+
(freshen-id constr) def-tbl pos-blame-id
124+
mk-redirect-id)]
122125
[else
123126
(make-quad constr def-tbl pos-blame-id mk-redirect-id)]))
124127

@@ -181,7 +184,7 @@
181184
;; def-tbl, pos-blame-id, and mk-redirect-id
182185
(define/cond-contract (make-quad internal-id def-tbl pos-blame-id mk-redirect-id)
183186
(-> identifier? (free-id-table/c identifier? binding? #:immutable #t) identifier? identifier?
184-
(values syntax? syntax? identifier? (listof (list/c identifier? identifier?))))
187+
(values syntax? syntax? identifier? (listof (list/c identifier? identifier?))))
185188
(define new-id (freshen-id internal-id))
186189
(cond
187190
;; if it's already done, do nothing

typed-racket-lib/typed-racket/typecheck/internal-forms.rkt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,11 @@
7373
;;; Helpers
7474

7575
(define-splicing-syntax-class dtsi-fields
76-
#:attributes (mutable prefab type-only maker extra-maker [proc-ty 1] [prop 1])
77-
(pattern
78-
(~seq
76+
#:attributes (mutable prefab maker extra-maker [proc-ty 1] [prop 1])
77+
(pattern
78+
(~seq
7979
(~or (~optional (~and #:mutable (~bind (mutable #t))))
8080
(~optional (~and #:prefab (~bind (prefab #t))))
81-
(~optional (~and #:type-only (~bind (type-only #t))))
8281
(~optional (~seq #:extra-maker extra-maker))
8382
(~optional (~seq #:maker maker))
8483
(~optional (~seq #:proc-ty (proc-ty ...)))
@@ -91,14 +90,13 @@
9190

9291

9392
(define-syntax-class define-typed-struct-body
94-
#:attributes (name type-name mutable prefab type-only maker extra-maker nm
93+
#:attributes (name type-name mutable prefab maker extra-maker nm
9594
(tvars 1) (fields 1) (types 1) proc-ty properties)
9695
(pattern ((~optional (tvars:id ...) #:defaults (((tvars 1) null)))
9796
nm:struct-name type-name:id ([fields:id : types:expr] ...) options:dtsi-fields)
9897
#:attr name #'nm.nm
9998
#:attr mutable (attribute options.mutable)
10099
#:attr prefab (attribute options.prefab)
101-
#:attr type-only (attribute options.type-only)
102100
#:with maker^ (or (attribute options.maker) #'nm.nm)
103101
#:attr maker #'maker^
104102
#:attr proc-ty (attribute options.proc-ty)

typed-racket-lib/typed-racket/typecheck/tc-structs.rkt

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
;; desc : struct-desc
6060
;; struct-info : struct-info?
6161
;; type-only : Boolean
62-
(struct parsed-struct (sty names desc struct-info type-only) #:transparent)
62+
(struct parsed-struct (sty names desc struct-info) #:transparent)
6363

6464
;; struct-name : Id (the identifier for the static struct info,
6565
;; usually the same as the type-name)
@@ -443,15 +443,13 @@
443443

444444
(define (register-parsed-struct-sty! ps)
445445
(match ps
446-
((parsed-struct sty names desc si type-only)
446+
((parsed-struct sty names desc si)
447447
(register-sty! sty names desc))))
448448

449449
(define (register-parsed-struct-bindings! ps)
450450
(match ps
451-
((parsed-struct sty names desc si type-only)
452-
(if type-only
453-
null
454-
(register-struct-bindings! sty names desc si)))))
451+
((parsed-struct sty names desc si)
452+
(register-struct-bindings! sty names desc si))))
455453

456454
;; Listof<Parsed-Struct> -> Void
457455
;; Refines the variance of struct types in the name environment
@@ -550,7 +548,6 @@
550548
#:maker [maker #f]
551549
#:extra-maker [extra-maker #f]
552550
#:mutable [mutable #f]
553-
#:type-only [type-only #f]
554551
#:prefab? [prefab? #f]
555552
#:proc-ty-stx [proc-ty-stx #f]
556553
#:properties [properties empty])
@@ -616,7 +613,7 @@
616613
(define desc
617614
(struct-desc parent-fields types tvars mutable parent-mutable))
618615
(parsed-struct (make-Prefab key (append parent-fields types))
619-
names desc (struct-info-property nm/par) #f)]
616+
names desc (struct-info-property nm/par))]
620617
[else
621618
(define parent-mutable
622619
;; Only valid as long as typed structs must be
@@ -634,7 +631,7 @@
634631
(extend-tvars tvars
635632
(extract-proc-ty proc-ty-stx desc fld-names type-name)))))
636633

637-
(parsed-struct sty names desc (struct-info-property nm/par) type-only)]))
634+
(parsed-struct sty names desc (struct-info-property nm/par))]))
638635

639636
;; register a struct type
640637
;; convenience function for built-in structs

typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
#:mutable (attribute t.mutable)
7373
#:maker (attribute t.maker)
7474
#:extra-maker (attribute t.extra-maker)
75-
#:type-only (attribute t.type-only)
7675
#:prefab? (attribute t.prefab)
7776
#:proc-ty-stx (attribute t.proc-ty)
7877
#:properties (attribute t.properties))])))
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#;
2+
(exn-pred "3 contract violation")
3+
#lang racket/base
4+
5+
(module u racket/base
6+
(struct apple (a))
7+
(struct pear (a) #:constructor-name make-pear)
8+
(provide (struct-out apple)
9+
(struct-out pear)))
10+
11+
(module t typed/racket
12+
(require/typed/provide (submod ".." u)
13+
(#:struct apple ((a : Symbol)))
14+
(#:struct pear ((a : Number)) #:constructor-name make-pear)))
15+
16+
(define counter 0)
17+
(require 't)
18+
19+
(define-syntax-rule (verify-contract expr ...)
20+
(begin (with-handlers ([exn:fail:contract? (lambda _
21+
(set! counter (add1 counter)))])
22+
expr)
23+
...
24+
(error (format "~a contract violation(s)" counter))))
25+
26+
(verify-contract (apple 42)
27+
(apple-a 20)
28+
(make-pear 'xxx))
29+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#lang racket/base
2+
(module a racket/base
3+
(struct foo ())
4+
(provide (struct-out foo)))
5+
6+
(module b typed/racket/base
7+
(require/typed (submod ".." a) [#:struct foo ()])
8+
(provide (struct-out foo)))
9+
10+
(module c racket/base
11+
(require (submod ".." b))
12+
(provide (struct-out foo)))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#lang racket/base
2+
3+
(module u racket/base
4+
(struct foo (a))
5+
(provide (struct-out foo)))
6+
7+
(module t typed/racket
8+
(require/typed/provide (submod ".." u)
9+
(#:struct foo ((a : Symbol))))
10+
(define ins : foo (foo 'hello))
11+
(if (foo? ins)
12+
(foo-a ins)
13+
(error 'test "not going to happen")))
14+
15+
(require 't racket/match)
16+
(match (foo 'a)
17+
[(foo a) a])

0 commit comments

Comments
 (0)