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 0a232342..caeca650 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 @@ -633,6 +633,10 @@ (*ListDots (sb dty) (if (eq? dbound name) (+ count outer) dbound))] [#:Mu (Scope: body) (*Mu (*Scope (loop (add1 outer) body)))] + [#:PolyRow constraints body* + (let ([body (remove-scopes 1 body*)]) + (*PolyRow constraints + (add-scopes 1 (loop (+ 1 outer) body))))] [#:PolyDots n body* (let ([body (remove-scopes n body*)]) (*PolyDots n (add-scopes n (loop (+ n outer) body))))] @@ -681,6 +685,9 @@ (*ListDots (sb dty) (if (eqv? dbound (+ count outer)) (F-n image) dbound))] [#:Mu (Scope: body) (*Mu (*Scope (loop (add1 outer) body)))] + [#:PolyRow constraints body* + (let ([body (remove-scopes 1 body*)]) + (*PolyRow constraints (add-scopes 1 (loop (+ 1 outer) body))))] [#:PolyDots n body* (let ([body (remove-scopes n body*)]) (*PolyDots n (add-scopes n (loop (+ n outer) body))))] diff --git a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt index e40feb49..4a862ef8 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt @@ -1250,11 +1250,11 @@ (match-define (arr: doms rng rest drest kws) arr) (make-arr (cons self-type doms) rng rest drest kws))) (make-Function fixed-arrs)] - [(Poly: ns body) + [(Poly-names: ns body) (make-Poly ns (function->method body self-type))] - [(PolyDots: ns body) + [(PolyDots-names: ns body) (make-PolyDots ns (function->method body self-type))] - [(PolyRow: ns constraints body) + [(PolyRow-names: ns constraints body) (make-PolyRow ns constraints (function->method body self-type))] [_ (int-err "function->method: ~a" type)])) @@ -1268,11 +1268,11 @@ (match-define (arr: doms rng rest drest kws) arr) (make-arr (cdr doms) rng rest drest kws))) (make-Function fixed-arrs)] - [(Poly: ns body) + [(Poly-names: ns body) (make-Poly ns (method->function body))] - [(PolyDots: ns body) + [(PolyDots-names: ns body) (make-PolyDots ns (method->function type))] - [(PolyRow: ns constraints body) + [(PolyRow-names: ns constraints body) (make-PolyRow ns constraints (method->function type))] [_ (tc-error/expr "expected a function type for method")])) diff --git a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/tc-funapp.rkt b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/tc-funapp.rkt index 21ee97ff..ab15b4f7 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/tc-funapp.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/tc-funapp.rkt @@ -127,13 +127,28 @@ (poly-fail f-stx args-stx t argtys #:name (and (identifier? f-stx) f-stx) #:expected expected)) - ;; only infer if there's 1 argument - (for ([dom doms]) - (unless (and (= 1 (length argtys-t) (length dom))) - (fail))) - (cond [(Class? (car argtys-t)) + ;; there's only one row variable in a PolyRow (for now) + (define row-var (car vars)) + ;; only infer if there is only one argument type that has the relevant + ;; row type variable in its free variables in all cases + (define row-var-idxs + (for/list ([dom doms]) + (define num-occurs + (for/list ([dom-type dom] [idx (in-naturals)] + #:when (member row-var (fv dom-type))) + idx)) + (unless (<= (length num-occurs) 1) + (fail)) + (if (null? num-occurs) 0 (car num-occurs)))) + (unless (or (< (length row-var-idxs) 2) + (apply = row-var-idxs)) + ;; row var wasn't in the same position in some cases + (fail)) + (define idx (car row-var-idxs)) + (cond [(Class? (list-ref argtys-t idx)) (define substitution - (hash (car vars) (t-subst (infer-row constraints (car argtys-t))))) + (hash row-var + (t-subst (infer-row constraints (list-ref argtys-t idx))))) (or (for/or ([arr (in-list arrs)]) (tc/funapp1 f-stx args-stx (subst-all substitution arr) argtys expected #:check #f))