@@ -851,10 +851,45 @@ end
851851""" 
852852    isdispatchtuple(T) 
853853
854- Determine whether type `T` is a tuple of concrete types, 
855- meaning it could appear as a type signature in dispatch 
856- and has no subtypes (or supertypes) which could appear in a call. 
854+ Determine whether type `T` is a [`Tuple`](@ref) that could appear as a type 
855+ signature in dispatch.  For this to be true, every element of the tuple type 
856+ must be either: 
857+ - [concrete](@ref isconcretetype) but not a [kind type](@ref Base.iskindtype) 
858+ - a [`Type{U}`](@ref Type) with no free type variables in `U` 
859+ 
860+ !!! note 
861+     A dispatch tuple is relevant for method dispatch because it has no inhabited 
862+     subtypes. 
863+ 
864+     For example, `Tuple{Int, DataType}` is concrete, but is not a dispatch tuple 
865+     because `Tuple{Int, Type{Bool}}` is an inhabited subtype. 
866+ 
867+     `Tuple{Tuple{DataType}}` *is* a dispatch tuple because `Tuple{DataType}` is 
868+     concrete and not a kind; the subtype `Tuple{Tuple{Type{Int}}}` is not 
869+     inhabited. 
870+ 
857871If `T` is not a type, then return `false`. 
872+ 
873+ # Examples 
874+ ```jldoctest 
875+ julia> isdispatchtuple(Int) 
876+ false 
877+ 
878+ julia> isdispatchtuple(Tuple{Int}) 
879+ true 
880+ 
881+ julia> isdispatchtuple(Tuple{Number}) 
882+ false 
883+ 
884+ julia> isdispatchtuple(Tuple{DataType}) 
885+ false 
886+ 
887+ julia> isdispatchtuple(Tuple{Type{Int}}) 
888+ true 
889+ 
890+ julia> isdispatchtuple(Tuple{Type}) 
891+ false 
892+ ``` 
858893""" 
859894isdispatchtuple (@nospecialize (t)) =  (@_total_meta ; isa (t, DataType) &&  (t. flags &  0x0004 ) ==  0x0004 )
860895
@@ -900,7 +935,40 @@ function isidentityfree(@nospecialize(t))
900935    return  false 
901936end 
902937
938+ """ 
939+     Base.iskindtype(T) 
940+ 
941+ Determine whether `T` is a kind, that is, the type of a Julia type: 
942+ a [`DataType`](@ref), [`Union`](@ref), [`UnionAll`](@ref), 
943+ or [`Core.TypeofBottom`](@ref). 
944+ 
945+ All kinds are [concrete](@ref isconcretetype) because types are Julia values. 
946+ """ 
903947iskindtype (@nospecialize  t) =  (t ===  DataType ||  t ===  UnionAll ||  t ===  Union ||  t ===  typeof (Bottom))
948+ 
949+ """ 
950+     Base.isconcretedispatch(T) 
951+ 
952+ Returns true if `T` is a [concrete type](@ref isconcretetype) that could appear 
953+ as an element of a [dispatch tuple](@ref isdispatchtuple). 
954+ 
955+ See also: [`isdispatchtuple`](@ref). 
956+ 
957+ # Examples 
958+ ```jldoctest 
959+ julia> Base.isconcretedispatch(Int) 
960+ true 
961+ 
962+ julia> Base.isconcretedispatch(Number) 
963+ false 
964+ 
965+ julia> Base.isconcretedispatch(DataType) 
966+ false 
967+ 
968+ julia> Base.isconcretedispatch(Type{Int}) 
969+ false 
970+ ``` 
971+ """ 
904972isconcretedispatch (@nospecialize  t) =  isconcretetype (t) &&  ! iskindtype (t)
905973
906974using  Core:  has_free_typevars
@@ -923,6 +991,16 @@ Determine whether type `T` is a concrete type, meaning it could have direct inst
923991Note that this is not the negation of `isabstracttype(T)`. 
924992If `T` is not a type, then return `false`. 
925993
994+ !!! note 
995+     While concrete types are not [abstract](@ref isabstracttype) and 
996+     vice versa, types can be neither concrete nor abstract (for example, 
997+     `Vector` (a [`UnionAll`](@ref))). 
998+ 
999+ !!! note 
1000+     `T` must be the exact type that would be returned from `typeof`.  It is 
1001+     possible for a type `U` to exist such that `T == U`, `isconcretetype(T)`, 
1002+     but `!isconcretetype(U)`. 
1003+ 
9261004See also: [`isbits`](@ref), [`isabstracttype`](@ref), [`issingletontype`](@ref). 
9271005
9281006# Examples 
@@ -933,6 +1011,9 @@ false
9331011julia> isconcretetype(Complex{Float32}) 
9341012true 
9351013
1014+ julia> isconcretetype(Vector) 
1015+ false 
1016+ 
9361017julia> isconcretetype(Vector{Complex}) 
9371018true 
9381019
@@ -944,6 +1025,9 @@ false
9441025
9451026julia> isconcretetype(Union{Int,String}) 
9461027false 
1028+ 
1029+ julia> isconcretetype(Tuple{T} where T<:Int) 
1030+ false 
9471031``` 
9481032""" 
9491033isconcretetype (@nospecialize (t)) =  (@_total_meta ; isa (t, DataType) &&  (t. flags &  0x0002 ) ==  0x0002 )
@@ -953,9 +1037,15 @@ isconcretetype(@nospecialize(t)) = (@_total_meta; isa(t, DataType) && (t.flags &
9531037
9541038Determine whether type `T` was declared as an abstract type 
9551039(i.e. using the `abstract type` syntax). 
956- Note that this is not the negation of `isconcretetype(T)`. 
9571040If `T` is not a type, then return `false`. 
9581041
1042+ !!! note 
1043+     While abstract types are not [concrete](@ref isconcretetype) and 
1044+     vice versa, types can be neither concrete nor abstract (for example, 
1045+     `Vector` (a [`UnionAll`](@ref))). 
1046+ 
1047+ See also: [`isconcretetype`](@ref). 
1048+ 
9591049# Examples 
9601050```jldoctest 
9611051julia> isabstracttype(AbstractArray) 
0 commit comments