@@ -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
@@ -554,7 +555,7 @@ function make_typealias(@nospecialize(x::Type))
554
555
for name in names (mod)
555
556
if isdefined (mod, name) && ! isdeprecated (mod, name) && isconst (mod, name)
556
557
alias = getfield (mod, name)
557
- if alias isa Type && ! has_free_typevars (alias) && ! isvarargtype (alias) && ! print_without_params (alias) && x <: alias
558
+ if alias isa Type && ! has_free_typevars (alias) && ! print_without_params (alias) && x <: alias
558
559
if alias isa UnionAll
559
560
(ti, env) = ccall (:jl_type_intersection_with_env , Any, (Any, Any), x, alias):: SimpleVector
560
561
# ti === Union{} && continue # impossible, since we already checked that x <: alias
@@ -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 = TypeVar[]
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
@@ -661,7 +698,7 @@ function make_typealiases(@nospecialize(x::Type))
661
698
for name in names (mod)
662
699
if isdefined (mod, name) && ! isdeprecated (mod, name) && isconst (mod, name)
663
700
alias = getfield (mod, name)
664
- if alias isa Type && ! has_free_typevars (alias) && ! isvarargtype (alias) && ! print_without_params (alias) && ! (alias <: Tuple )
701
+ if alias isa Type && ! has_free_typevars (alias) && ! print_without_params (alias) && ! (alias <: Tuple )
665
702
(ti, env) = ccall (:jl_type_intersection_with_env , Any, (Any, Any), x, alias):: SimpleVector
666
703
ti === Union{} && continue
667
704
mod in modulesof! (Set {Module} (), alias) || continue # make sure this alias wasn't from an unrelated part of the Union
@@ -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
@@ -751,7 +792,7 @@ function show(io::IO, ::MIME"text/plain", @nospecialize(x::Type))
751
792
show (io, x)
752
793
if ! print_without_params (x) && get (io, :compact , true )
753
794
properx = makeproper (io, x)
754
- if make_typealias (properx) != = nothing || x <: make_typealiases (properx)[2 ]
795
+ if make_typealias (properx) != = nothing || ( unwrap_unionall (x) isa Union && x <: make_typealiases (properx)[2 ])
755
796
print (io, " (alias for " )
756
797
show (IOContext (io, :compact => false ), x)
757
798
print (io, " )" )
@@ -786,22 +827,30 @@ function show(io::IO, @nospecialize(x::Type))
786
827
end
787
828
788
829
x = x:: UnionAll
789
- if x. var. name === :_ || io_has_tvar_name (io, x. var. name, x)
790
- counter = 1
791
- while true
792
- newname = Symbol (x. var. name, counter)
793
- if ! io_has_tvar_name (io, newname, x)
794
- newtv = TypeVar (newname, x. var. lb, x. var. ub)
795
- x = UnionAll (newtv, x{newtv})
796
- break
830
+ wheres = TypeVar[]
831
+ let io = IOContext (io)
832
+ while x isa UnionAll
833
+ var = x. var
834
+ if var. name === :_ || io_has_tvar_name (io, var. name, x)
835
+ counter = 1
836
+ while true
837
+ newname = Symbol (var. name, counter)
838
+ if ! io_has_tvar_name (io, newname, x)
839
+ var = TypeVar (newname, var. lb, var. ub)
840
+ x = x{var}
841
+ break
842
+ end
843
+ counter += 1
844
+ end
845
+ else
846
+ x = x. body
797
847
end
798
- counter += 1
848
+ push! (wheres, var)
849
+ io = IOContext (io, :unionall_env => var)
799
850
end
851
+ show (io, x)
800
852
end
801
-
802
- show (IOContext (io, :unionall_env => x. var), x. body)
803
- print (io, " where " )
804
- show (io, x. var)
853
+ show_wheres (io, wheres)
805
854
end
806
855
807
856
# Check whether 'sym' (defined in module 'parent') is visible from module 'from'
0 commit comments