@@ -851,10 +851,45 @@ end
851
851
"""
852
852
isdispatchtuple(T)
853
853
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
+
857
871
If `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
+ ```
858
893
"""
859
894
isdispatchtuple (@nospecialize (t)) = (@_total_meta ; isa (t, DataType) && (t. flags & 0x0004 ) == 0x0004 )
860
895
@@ -900,7 +935,40 @@ function isidentityfree(@nospecialize(t))
900
935
return false
901
936
end
902
937
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
+ """
903
947
iskindtype (@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
+ """
904
972
isconcretedispatch (@nospecialize t) = isconcretetype (t) && ! iskindtype (t)
905
973
906
974
using Core: has_free_typevars
@@ -923,6 +991,16 @@ Determine whether type `T` is a concrete type, meaning it could have direct inst
923
991
Note that this is not the negation of `isabstracttype(T)`.
924
992
If `T` is not a type, then return `false`.
925
993
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
+
926
1004
See also: [`isbits`](@ref), [`isabstracttype`](@ref), [`issingletontype`](@ref).
927
1005
928
1006
# Examples
@@ -933,6 +1011,9 @@ false
933
1011
julia> isconcretetype(Complex{Float32})
934
1012
true
935
1013
1014
+ julia> isconcretetype(Vector)
1015
+ false
1016
+
936
1017
julia> isconcretetype(Vector{Complex})
937
1018
true
938
1019
@@ -944,6 +1025,9 @@ false
944
1025
945
1026
julia> isconcretetype(Union{Int,String})
946
1027
false
1028
+
1029
+ julia> isconcretetype(Tuple{T} where T<:Int)
1030
+ false
947
1031
```
948
1032
"""
949
1033
isconcretetype (@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 &
953
1037
954
1038
Determine whether type `T` was declared as an abstract type
955
1039
(i.e. using the `abstract type` syntax).
956
- Note that this is not the negation of `isconcretetype(T)`.
957
1040
If `T` is not a type, then return `false`.
958
1041
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
+
959
1049
# Examples
960
1050
```jldoctest
961
1051
julia> isabstracttype(AbstractArray)
0 commit comments