From b338fc6b6465079e2dccadd2687a8798b9d91c67 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 1 Jun 2016 14:22:08 -0400 Subject: [PATCH] Be less conservative about struct overlap Fixes issue #366 --- .../typed-racket/types/overlap.rkt | 23 ++++++++++++++++--- typed-racket-test/succeed/gh-issue-366.rkt | 15 ++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 typed-racket-test/succeed/gh-issue-366.rkt diff --git a/typed-racket-lib/typed-racket/types/overlap.rkt b/typed-racket-lib/typed-racket/types/overlap.rkt index e9127a22..fa308e71 100644 --- a/typed-racket-lib/typed-racket/types/overlap.rkt +++ b/typed-racket-lib/typed-racket/types/overlap.rkt @@ -101,7 +101,24 @@ [((Struct: n #f flds _ _ _) (StructTop: (Struct: n* #f flds* _ _ _))) #f] - [((and t1 (Struct: _ _ _ _ #f _)) - (and t2 (Struct: _ _ _ _ #f _))) - (or (subtype t1 t2) (subtype t2 t1))] + [((and t1 (Struct: _ _ _ _ _ _)) + (and t2 (Struct: _ _ _ _ _ _))) + (or (subtype t1 t2) (subtype t2 t1) + (parent-of? t1 t2) (parent-of? t2 t1))] [(_ _) #t])])) + +;; Type Type -> Boolean +;; Given two struct types, check if the second is a parent struct +;; type of the other (though possibly at different type instantiations +;; if they are polymorphic) +(define (parent-of? t1 t2) + (match* (t1 t2) + [((Struct: _ (Struct: pname _ _ _ _ _) _ _ _ _) + (Struct: pname _ _ _ _ _)) + #t] + [((Struct: _ #f _ _ _ _) + other) + #f] + [((Struct: _ parent _ _ _ _) + other) + (parent-of? parent other)])) diff --git a/typed-racket-test/succeed/gh-issue-366.rkt b/typed-racket-test/succeed/gh-issue-366.rkt new file mode 100644 index 00000000..d7803dec --- /dev/null +++ b/typed-racket-test/succeed/gh-issue-366.rkt @@ -0,0 +1,15 @@ +#lang typed/racket + +;; Test for Github issue #366 + +(struct Parent () #:transparent) +(struct (A B) S0 Parent ([a : A] [b : B]) #:transparent) +(struct (B C) S1 Parent ([b : B] [c : C]) #:transparent) + +(define v : (S1 'x Integer) (S1 'x 2)) +(ann (if (S0? v) + (S0-b v) ;; ERROR HERE + (if (S1? v) + (S1-b v) + (void))) + 'x)