Skip to content

Commit 05d6167

Browse files
authored
Merge pull request #21928 from JuliaLang/jb/fix21923
fix #21923, regressions in circular type definitions
2 parents 5375620 + 49d130c commit 05d6167

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

src/jltypes.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,10 +1343,7 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_t
13431343
}
13441344
jl_typeenv_t newenv = { ua->var, (jl_value_t*)((jl_unionall_t*)res)->var, env };
13451345
jl_value_t *newbody = inst_type_w_(ua->body, &newenv, &top, check);
1346-
if (newbody == ua->body) {
1347-
res = t;
1348-
}
1349-
else if (newbody == (jl_value_t*)jl_emptytuple_type) {
1346+
if (newbody == (jl_value_t*)jl_emptytuple_type) {
13501347
// NTuple{0} => Tuple{} can make a typevar disappear
13511348
res = (jl_value_t*)jl_emptytuple_type;
13521349
}

src/julia-syntax.scm

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,7 +3315,7 @@ f(x) = yt(x)
33153315
(set-car! (lam:vinfo lam) (append (car (lam:vinfo lam)) `((,g Any 2))))
33163316
g))
33173317
;; evaluate the arguments of a call, creating temporary locations as needed
3318-
(define (compile-args lst break-labels)
3318+
(define (compile-args lst break-labels (linearize #t))
33193319
(if (null? lst) '()
33203320
(let ((temps? (or *very-linear-mode*
33213321
(any (lambda (e)
@@ -3332,9 +3332,9 @@ f(x) = yt(x)
33323332
(if (null? lst)
33333333
(reverse! vals)
33343334
(let* ((arg (car lst))
3335-
(aval (compile arg break-labels #t #f)))
3335+
(aval (compile arg break-labels #t #f linearize)))
33363336
(loop (cdr lst)
3337-
(cons (if (and temps? (not simple?)
3337+
(cons (if (and temps? linearize (not simple?)
33383338
(not (simple-atom? arg)) (not (ssavalue? arg))
33393339
(not (simple-atom? aval)) (not (ssavalue? aval))
33403340
(not (and (pair? arg)
@@ -3361,7 +3361,7 @@ f(x) = yt(x)
33613361
;; value must be returned.
33623362
;; `tail` means we are in tail position, where a value needs to be `return`ed
33633363
;; from the current function.
3364-
(define (compile e break-labels value tail)
3364+
(define (compile e break-labels value tail (linearize-args #t))
33653365
(if (or (not (pair? e)) (memq (car e) '(null ssavalue quote inert top core copyast the_exception $
33663366
globalref outerref cdecl stdcall fastcall thiscall llvmcall)))
33673367
(let ((e1 (if (and arg-map (symbol? e))
@@ -3386,11 +3386,11 @@ f(x) = yt(x)
33863386
;; NOTE: 2nd and 3rd arguments of ccall must be left in place
33873387
;; the 1st should be compiled if an atom.
33883388
(append (list)
3389-
(cond (atom? (cadr e) (compile-args (list (cadr e)) break-labels))
3389+
(cond (atom? (cadr e) (compile-args (list (cadr e)) break-labels linearize-args))
33903390
(else (cadr e)))
33913391
(list-head (cddr e) 2)
3392-
(compile-args (list-tail e 4) break-labels))
3393-
(compile-args (cdr e) break-labels)))
3392+
(compile-args (list-tail e 4) break-labels linearize-args))
3393+
(compile-args (cdr e) break-labels linearize-args)))
33943394
(callex (cons (car e) args)))
33953395
(cond (tail (emit-return callex))
33963396
(value callex)
@@ -3602,7 +3602,11 @@ f(x) = yt(x)
36023602
((composite_type)
36033603
(let* ((para (compile (caddr e) break-labels #t #f))
36043604
(supe (compile (list-ref e 4) break-labels #t #f))
3605-
(ftys (compile (list-ref e 5) break-labels #t #f)))
3605+
;; composite_type has an unconventional evaluation rule that
3606+
;; needs to do work around the evaluation of the field types,
3607+
;; so the field type expressions need to be kept in place as
3608+
;; much as possible. (part of issue #21923)
3609+
(ftys (compile (list-ref e 5) break-labels #t #f #f)))
36063610
(emit `(composite_type ,(cadr e) ,para ,(cadddr e) ,supe ,ftys ,@(list-tail e 6)))))
36073611
(else
36083612
(emit e)))

test/core.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,16 @@ abstract type Sup2a_ end
245245
abstract type Sup2b_{A <: Sup2a_, B} <: Sup2a_ end
246246
@test_throws ErrorException @eval abstract type Qux2_{T} <: Sup2b_{Qux2_{Int}, T} end # wrapped in eval to avoid #16793
247247

248+
# issue #21923
249+
struct A21923{T,N}; v::Vector{A21923{T}}; end
250+
@test fieldtype(A21923,1) == Vector{A21923{T}} where T
251+
struct B21923{T,N}; v::Vector{B21923{T,M} where M}; end
252+
@test fieldtype(B21923, 1) == Vector{B21923{T,M} where M} where T
253+
struct C21923{T,N}; v::C21923{T,M} where M; end
254+
@test fieldtype(C21923, 1) == C21923
255+
struct D21923{T,N}; v::D21923{T}; end
256+
@test fieldtype(D21923, 1) == D21923
257+
248258
# issue #3890
249259
mutable struct A3890{T1}
250260
x::Matrix{Complex{T1}}

0 commit comments

Comments
 (0)