racket / typed-racket

Typed Racket
Other
520 stars 103 forks source link

Weird typed class typechecking behaviors #477

Open wargrey opened 7 years ago

wargrey commented 7 years ago

What version of Racket are you using?

Racket 6.7

What program did you run?

#lang typed/racket/gui

(define-type Separator separator)
(define-type StyleSheet stylesheet)
(define-type Subject subject)

(define-type Contract-Violation-Separator%
  (Class #:implements Canvas%
         (init-field [parent (Instance Area-Container<%>)]
                     [css StyleSheet]
                     [parents (Listof Subject)]
                     [inherits (Option HashTableTop)])))

(define-type Type-Blind-Separator%
  (Class #:implements Canvas%
         (init-field [parent (Instance Area-Container<%>)]
                     [css StyleSheet])))

(struct stylesheet () #:transparent)
(struct subject () #:transparent)
(struct separator ([width : Positive-Byte] [color : String]) #:transparent)

(define separator-filter : (-> Separator) (lambda [] (separator 4 "Snow")))
(define css-cascade : (-> (Listof StyleSheet) (Listof Subject) (-> Separator) (Option HashTableTop) (Values Separator HashTableTop))
  (lambda [stylesheets subjects filter inherits]
    (values (filter) (or inherits (make-hasheq)))))
(define hline% : Contract-Violation-Separator%
  (class canvas%
    (init-field parent css parents inherits)

    (: hs Separator)
    (define-values (hs _) (css-cascade (list css) (cons (subject) parents) separator-filter inherits))

    (super-new [parent parent]
               [style null] [paint-callback void] [label #false] [gl-config #false] [enabled #true]
               [vert-margin 0] [horiz-margin 0] [min-width #false] [stretchable-width #true]
               [min-height (separator-width hs)] [stretchable-height #false])

(send this set-canvas-background (make-object color% (separator-color hs)))))

The hline% should have been the main issue, however in this example it works well. But I met it before in a different situation in real world code

static-contracts/instantiate.rkt. car: contract violation.

I still not sure how to reproduce it consistently. During the process of trying to reproduce it, I found another issue fantastically:

(define vline% : Type-Blind-Separator%
  (class canvas%
    (init-field parent css)

    (: hs Separator)
    (define-values (hs _) (css-cascade (list css) (list (subject)) separator-filter #false))

    (super-new [parent parent]
               [style null] [paint-callback void] [label #false] [gl-config #false] [enabled #true]
               [vert-margin 0] [horiz-margin 0] [min-width #false] [stretchable-width #true]
               [min-height (separator-width hs)] [stretchable-height #false])

 (send this set-canvas-background (make-object color% (separator-color hs)))))

Type Checker: missing type for identifier; consider adding a type annotation with `:' identifier: self6196653 in: css


There also are other strange behaviors if the code exists in class body. Some are not reasonable; Some are easy to work around, some are heavily affected by context.

wargrey commented 7 years ago

@takikawa can you make exn:fail:object available as well? this one is not in the racket/base and the require/provide way will lead to conflict when be required by untyped code.

Thank you.

wargrey commented 7 years ago

Update: The original issue I posted to the mailing list can be solved by moving the definition into a fresh module. In this situation, no two classes that inheriting the same class can exist in one module(even though there is no other definitions), the failure always comes with the second one.