@@ -532,8 +532,9 @@ function makeproper(io::IO, x::Type)
532
532
push! (y, typ)
533
533
end
534
534
end
535
- normal || (x = Union{y... })
536
- properx = rewrap_unionall (x, properx)
535
+ if ! normal
536
+ properx = rewrap_unionall (Union{y... }, properx)
537
+ end
537
538
end
538
539
has_free_typevars (properx) && return Any
539
540
return properx
@@ -580,8 +581,8 @@ function make_typealias(@nospecialize(x::Type))
580
581
applied = rewrap_unionall (applied, p)
581
582
end
582
583
has_free_typevars (applied) && continue
583
- applied == x || continue # it couldn't figure out the parameter matching
584
- elseif alias <: x
584
+ applied === x || continue # it couldn't figure out the parameter matching
585
+ elseif alias === x
585
586
env = Core. svec ()
586
587
else
587
588
continue # not a complete match
@@ -596,7 +597,7 @@ function make_typealias(@nospecialize(x::Type))
596
597
end
597
598
end
598
599
599
- function show_typealias (io:: IO , name:: GlobalRef , x:: Type , env:: SimpleVector )
600
+ function show_typealias (io:: IO , name:: GlobalRef , x:: Type , env:: SimpleVector , wheres :: Vector )
600
601
if ! (get (io, :compact , false ):: Bool )
601
602
# Print module prefix unless alias is visible from module passed to
602
603
# IOContext. If :module is not set, default to Main. nothing can be used
@@ -612,34 +613,70 @@ function show_typealias(io::IO, name::GlobalRef, x::Type, env::SimpleVector)
612
613
n == 0 && return
613
614
614
615
print (io, " {" )
615
- let io = IOContext (io)
616
- for i = n: - 1 : 1
617
- p = env[i]
618
- if p isa TypeVar
619
- io = IOContext (io, :unionall_env => p)
616
+ param_io = IOContext (io)
617
+ for i = 1 : length (wheres)
618
+ p = wheres[i]:: TypeVar
619
+ param_io = IOContext (param_io, :unionall_env => p)
620
+ end
621
+ for i = 1 : n
622
+ p = env[i]
623
+ show (param_io, p)
624
+ i < n && print (io, " , " )
625
+ end
626
+ print (io, " }" )
627
+ end
628
+
629
+ function make_wheres (io:: IO , env:: SimpleVector , @nospecialize (x:: Type ))
630
+ seen = IdSet ()
631
+ wheres = []
632
+ # record things printed by the context
633
+ if io isa IOContext
634
+ for (key, val) in io. dict
635
+ if key === :unionall_env && val isa TypeVar && has_typevar (x, val)
636
+ push! (seen, val)
620
637
end
621
638
end
622
- for i = 1 : n
623
- p = env[i]
624
- show (io, p)
625
- i < n && print (io, " , " )
639
+ end
640
+ # record things in x to print outermost
641
+ while x isa UnionAll
642
+ if ! (x. var in seen)
643
+ push! (seen, x. var)
644
+ push! (wheres, x. var)
626
645
end
646
+ x = x. body
627
647
end
628
- print (io, " } " )
629
- for i = n : - 1 : 1
648
+ # record remaining things in env to print innermost
649
+ for i = length (env) : - 1 : 1
630
650
p = env[i]
631
- if p isa TypeVar && ! io_has_tvar_name (io, p . name, x )
632
- print (io, " where " )
633
- show (io , p)
651
+ if p isa TypeVar && ! (p in seen )
652
+ push! (seen, p )
653
+ pushfirst! (wheres , p)
634
654
end
635
655
end
656
+ return wheres
657
+ end
658
+
659
+ function show_wheres (io:: IO , env:: Vector )
660
+ isempty (env) && return
661
+ io = IOContext (io)
662
+ n = length (env)
663
+ for i = 1 : n
664
+ p = env[i]:: TypeVar
665
+ print (io, n == 1 ? " where " : i == 1 ? " where {" : " , " )
666
+ show (io, p)
667
+ io = IOContext (io, :unionall_env => p)
668
+ end
669
+ n > 1 && print (io, " }" )
670
+ nothing
636
671
end
637
672
638
673
function show_typealias (io:: IO , x:: Type )
639
674
properx = makeproper (io, x)
640
675
alias = make_typealias (properx)
641
676
alias === nothing && return false
642
- show_typealias (io, alias[1 ], x, alias[2 ])
677
+ wheres = make_wheres (io, alias[2 ], x)
678
+ show_typealias (io, alias[1 ], x, alias[2 ], wheres)
679
+ show_wheres (io, wheres)
643
680
return true
644
681
end
645
682
@@ -735,13 +772,17 @@ function show_unionaliases(io::IO, x::Union)
735
772
end
736
773
if first && length (aliases) == 1
737
774
alias = aliases[1 ]
738
- show_typealias (io, alias[1 ], x, alias[2 ])
775
+ wheres = make_wheres (io, alias[2 ], x)
776
+ show_typealias (io, alias[1 ], x, alias[2 ], wheres)
777
+ show_wheres (io, wheres)
739
778
else
740
779
for alias in aliases
741
780
print (io, first ? " Union{" : " , " )
742
781
first = false
743
782
env = alias[2 ]
744
- show_typealias (io, alias[1 ], x, alias[2 ])
783
+ wheres = make_wheres (io, alias[2 ], x)
784
+ show_typealias (io, alias[1 ], x, alias[2 ], wheres)
785
+ show_wheres (io, wheres)
745
786
end
746
787
print (io, " }" )
747
788
end
0 commit comments