From c8e5423e557cf5976bdb0050b72979b9fb9c76a4 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 22 Aug 2013 12:12:36 -0400 Subject: [PATCH] Make subtyping checks on objects faster --- .../typed-racket/rep/type-rep.rkt | 35 ++++++++-- .../typed-racket/types/subtype.rkt | 66 ++++++++++--------- 2 files changed, 62 insertions(+), 39 deletions(-) diff --git a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/rep/type-rep.rkt b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/rep/type-rep.rkt index ab1584300f..95b24ae34e 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/rep/type-rep.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/rep/type-rep.rkt @@ -26,13 +26,14 @@ Values/c SomeValues/c Poly-n PolyDots-n - Class? + Class? Row? Row: free-vars* type-compare type - (lambda (spec) (subtype* A (cadr spec) m))] - [else #f])))) - (and ;; Note that augment/public doesn't matter for object - ;; subtyping, so these mappings can be merged - (subtype-clause? (append method-map augment-map) - (append method-map* augment-map*)) + ;; invariant: map and map* are sorted by key + (let loop ([A A0] [map map] [map* map*]) + (cond [(or (empty? map) (empty? map*)) #t] + [else + (match-define (list name type) (car map)) + (match-define (list name* type*) (car map*)) + (cond [;; quit if 2nd obj lacks a name in 1st obj + (symbolstring car))) - (let ([clause (sort-clause clause)] - [clause* (sort-clause clause*)]) - (cond - [(not inits?) - (match-define (list (list names types) ...) clause) - (match-define (list (list names* types*) ...) clause*) - (and (= (length names) (length names*)) - (andmap equal? names names*) - (andmap sub types types*))] - [else - (match-define (list (list names types opt?) ...) - clause) - (match-define (list (list names* types* opt?*) ...) - clause*) - (and (= (length names) (length names*)) - (andmap equal? names names*) - (andmap sub types types*) - (andmap equal? opt? opt?*))]))) + (cond + [(not inits?) + (match-define (list (list names types) ...) clause) + (match-define (list (list names* types*) ...) clause*) + (and (= (length names) (length names*)) + (andmap equal? names names*) + (andmap sub types types*))] + [else + (match-define (list (list names types opt?) ...) + clause) + (match-define (list (list names* types* opt?*) ...) + clause*) + (and (= (length names) (length names*)) + (andmap equal? names names*) + (andmap sub types types*) + (andmap equal? opt? opt?*))])) ;; There is no non-trivial width subtyping on class types, but it's ;; possible for two "equal" class types to look different ;; in the representation. We deal with that here. @@ -627,7 +630,6 @@ (equal? row row*)) (equal-clause? inits inits* #t) (equal-clause? fields fields*) - ;; augment/public distinction is important here (equal-clause? methods methods*) (equal-clause? augments augments*))] ;; otherwise, not a subtype