Make row inference slightly smarter
Now it works as long as one of the arguments is, in all cases, a row polymorphic class type original commit: 30c49028cb124bf252d518b60bb4db94a48943c4
This commit is contained in:
parent
5cbc1369d4
commit
08fa6df119
|
@ -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))))]
|
||||
|
|
|
@ -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")]))
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue
Block a user