Skip to content

Commit

Permalink
fix #21923, regressions in circular type definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed May 17, 2017
1 parent a0ada1d commit 49d130c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
5 changes: 1 addition & 4 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1343,10 +1343,7 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_t
}
jl_typeenv_t newenv = { ua->var, (jl_value_t*)((jl_unionall_t*)res)->var, env };
jl_value_t *newbody = inst_type_w_(ua->body, &newenv, &top, check);
if (newbody == ua->body) {
res = t;
}
else if (newbody == (jl_value_t*)jl_emptytuple_type) {
if (newbody == (jl_value_t*)jl_emptytuple_type) {
// NTuple{0} => Tuple{} can make a typevar disappear
res = (jl_value_t*)jl_emptytuple_type;
}
Expand Down
20 changes: 12 additions & 8 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3315,7 +3315,7 @@ f(x) = yt(x)
(set-car! (lam:vinfo lam) (append (car (lam:vinfo lam)) `((,g Any 2))))
g))
;; evaluate the arguments of a call, creating temporary locations as needed
(define (compile-args lst break-labels)
(define (compile-args lst break-labels (linearize #t))
(if (null? lst) '()
(let ((temps? (or *very-linear-mode*
(any (lambda (e)
Expand All @@ -3332,9 +3332,9 @@ f(x) = yt(x)
(if (null? lst)
(reverse! vals)
(let* ((arg (car lst))
(aval (compile arg break-labels #t #f)))
(aval (compile arg break-labels #t #f linearize)))
(loop (cdr lst)
(cons (if (and temps? (not simple?)
(cons (if (and temps? linearize (not simple?)
(not (simple-atom? arg)) (not (ssavalue? arg))
(not (simple-atom? aval)) (not (ssavalue? aval))
(not (and (pair? arg)
Expand All @@ -3361,7 +3361,7 @@ f(x) = yt(x)
;; value must be returned.
;; `tail` means we are in tail position, where a value needs to be `return`ed
;; from the current function.
(define (compile e break-labels value tail)
(define (compile e break-labels value tail (linearize-args #t))
(if (or (not (pair? e)) (memq (car e) '(null ssavalue quote inert top core copyast the_exception $
globalref outerref cdecl stdcall fastcall thiscall llvmcall)))
(let ((e1 (if (and arg-map (symbol? e))
Expand All @@ -3386,11 +3386,11 @@ f(x) = yt(x)
;; NOTE: 2nd and 3rd arguments of ccall must be left in place
;; the 1st should be compiled if an atom.
(append (list)
(cond (atom? (cadr e) (compile-args (list (cadr e)) break-labels))
(cond (atom? (cadr e) (compile-args (list (cadr e)) break-labels linearize-args))
(else (cadr e)))
(list-head (cddr e) 2)
(compile-args (list-tail e 4) break-labels))
(compile-args (cdr e) break-labels)))
(compile-args (list-tail e 4) break-labels linearize-args))
(compile-args (cdr e) break-labels linearize-args)))
(callex (cons (car e) args)))
(cond (tail (emit-return callex))
(value callex)
Expand Down Expand Up @@ -3602,7 +3602,11 @@ f(x) = yt(x)
((composite_type)
(let* ((para (compile (caddr e) break-labels #t #f))
(supe (compile (list-ref e 4) break-labels #t #f))
(ftys (compile (list-ref e 5) break-labels #t #f)))
;; composite_type has an unconventional evaluation rule that
;; needs to do work around the evaluation of the field types,
;; so the field type expressions need to be kept in place as
;; much as possible. (part of issue #21923)
(ftys (compile (list-ref e 5) break-labels #t #f #f)))
(emit `(composite_type ,(cadr e) ,para ,(cadddr e) ,supe ,ftys ,@(list-tail e 6)))))
(else
(emit e)))
Expand Down
10 changes: 10 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,16 @@ abstract type Sup2a_ end
abstract type Sup2b_{A <: Sup2a_, B} <: Sup2a_ end
@test_throws ErrorException @eval abstract type Qux2_{T} <: Sup2b_{Qux2_{Int}, T} end # wrapped in eval to avoid #16793

# issue #21923
struct A21923{T,N}; v::Vector{A21923{T}}; end
@test fieldtype(A21923,1) == Vector{A21923{T}} where T
struct B21923{T,N}; v::Vector{B21923{T,M} where M}; end
@test fieldtype(B21923, 1) == Vector{B21923{T,M} where M} where T
struct C21923{T,N}; v::C21923{T,M} where M; end
@test fieldtype(C21923, 1) == C21923
struct D21923{T,N}; v::D21923{T}; end
@test fieldtype(D21923, 1) == D21923

# issue #3890
mutable struct A3890{T1}
x::Matrix{Complex{T1}}
Expand Down

0 comments on commit 49d130c

Please sign in to comment.