struct*: fix incorrect struct-info extraction
Also add tests for `struct-copy` and `struct*` for cases where struct-field-info is not available Fixes #3662
This commit is contained in:
parent
c9861931ad
commit
0101f584fb
|
@ -1196,6 +1196,29 @@
|
|||
(struct a-b a (d) #:transparent)
|
||||
(syntax-test #'(struct-copy a-b (a-b 1 2) [c 10])))
|
||||
|
||||
(module test-struct-copy-no-struct-field-info racket/base
|
||||
(provide bar)
|
||||
(require (for-syntax racket/struct-info
|
||||
racket/base))
|
||||
(define (bar-car x) (car x))
|
||||
(define (bar-cdr x) (cdr x))
|
||||
(define (bar? x) (pair? x))
|
||||
|
||||
(struct foo ())
|
||||
|
||||
(define-syntax bar
|
||||
(make-struct-info
|
||||
(λ () (list #f
|
||||
#'cons
|
||||
#'bar?
|
||||
(list #'bar-cdr #'bar-car)
|
||||
(list #f #f)
|
||||
#'foo)))))
|
||||
|
||||
(let ()
|
||||
(local-require 'test-struct-copy-no-struct-field-info)
|
||||
(test (cons 3 2) 'struct-copy1 (struct-copy bar (cons 1 2) [car 3])))
|
||||
|
||||
(test #t prefab-key? 'apple)
|
||||
(test #f prefab-key? '#(apple))
|
||||
(test #t prefab-key? '(apple 4))
|
||||
|
|
|
@ -305,6 +305,25 @@
|
|||
(struct foo (a))
|
||||
(provide (rename-out [foo bar])))
|
||||
|
||||
(module test-struct*-no-struct-field-info racket/base
|
||||
(provide bar)
|
||||
(require (for-syntax racket/struct-info
|
||||
racket/base))
|
||||
(define (bar-car x) (car x))
|
||||
(define (bar-cdr x) (cdr x))
|
||||
(define (bar? x) (pair? x))
|
||||
|
||||
(struct foo ())
|
||||
|
||||
(define-syntax bar
|
||||
(make-struct-info
|
||||
(λ () (list #f
|
||||
#'cons
|
||||
#'bar?
|
||||
(list #'bar-cdr #'bar-car)
|
||||
(list #f #f)
|
||||
#'foo)))))
|
||||
|
||||
(define struct*-tests
|
||||
(test-suite
|
||||
"Tests of struct*"
|
||||
|
@ -403,7 +422,13 @@
|
|||
(match-define
|
||||
(struct* bar ([a x]))
|
||||
(bar 1))
|
||||
(check = x 1)))))
|
||||
(check = x 1)))
|
||||
|
||||
(test-case "without struct-field-info"
|
||||
(let ()
|
||||
(local-require 'test-struct*-no-struct-field-info)
|
||||
(match-define (struct* bar ([car x])) (list 1 2 3))
|
||||
(check = x 1)))))
|
||||
|
||||
(define plt-match-tests
|
||||
(test-suite "Tests for plt-match.rkt"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
(define num-fields (length accessors))
|
||||
(define num-super-fields
|
||||
(if (identifier? parent)
|
||||
(length (cadddr (syntax-local-value parent)))
|
||||
(length (cadddr (id->struct-info parent orig-stx)))
|
||||
0))
|
||||
(define num-own-fields (- num-fields num-super-fields))
|
||||
(define own-accessors (take accessors num-own-fields))
|
||||
|
@ -21,6 +21,12 @@
|
|||
(string->symbol (substring (symbol->string (syntax-e accessor))
|
||||
(add1 (string-length struct-name))))))
|
||||
|
||||
(define-for-syntax (id->struct-info id stx)
|
||||
(define compile-time-info (syntax-local-value id (lambda () #f)))
|
||||
(unless (struct-info? compile-time-info)
|
||||
(raise-syntax-error #f "identifier is not bound to a structure type" stx id))
|
||||
(extract-struct-info compile-time-info))
|
||||
|
||||
(define-match-expander
|
||||
struct*
|
||||
(lambda (stx)
|
||||
|
|
Loading…
Reference in New Issue
Block a user