@@ -19,35 +19,39 @@ showerror(io::IO, ex::MissingException) =
19
19
print (io, " MissingException: " , ex. msg)
20
20
21
21
nonmissingtype (:: Type{T} ) where {T} = Core. Compiler. typesubtract (T, Missing)
22
+ function nonmissingtype_checked (T:: Type )
23
+ R = nonmissingtype (T)
24
+ R >: T && throw (MissingException (" could not compute non-missing type" ))
25
+ return R
26
+ end
22
27
23
- for U in (:Nothing , :Missing )
24
- @eval begin
25
- promote_rule (:: Type{$U} , :: Type{T} ) where {T} = Union{T, $ U}
26
- promote_rule (:: Type{Union{S,$U}} , :: Type{Any} ) where {S} = Any
27
- promote_rule (:: Type{Union{S,$U}} , :: Type{T} ) where {T,S} = Union{promote_type (T, S), $ U}
28
- promote_rule (:: Type{Any} , :: Type{$U} ) = Any
29
- promote_rule (:: Type{$U} , :: Type{Any} ) = Any
30
- # This definition is never actually used, but disambiguates the above definitions
31
- promote_rule (:: Type{$U} , :: Type{$U} ) = $ U
32
- end
28
+ promote_rule (T:: Type{Missing} , S:: Type ) = Union{S, Missing}
29
+ promote_rule (T:: Type{Missing} , S:: Type{Any} ) = Any
30
+ promote_rule (T:: Type{Union{Nothing, Missing}} , S:: Type{Any} ) = Any
31
+ promote_rule (T:: Type{Union{Nothing, Missing}} , S:: Type ) = Union{S, Nothing, Missing}
32
+ promote_rule (T:: Type{>:Union{Nothing, Missing}} , S:: Type{Any} ) = Any
33
+ function promote_rule (T:: Type{>:Union{Nothing, Missing}} , S:: Type )
34
+ R = nonnothingtype (T)
35
+ R >: T && return Any
36
+ T = R
37
+ R = nonmissingtype (T)
38
+ R >: T && return Any
39
+ T = R
40
+ R = promote_type (T, S)
41
+ return Union{R, Nothing, Missing}
33
42
end
34
- promote_rule (:: Type{Union{Nothing, Missing}} , :: Type{Any} ) = Any
35
- promote_rule (:: Type{Union{Nothing, Missing}} , :: Type{T} ) where {T} =
36
- Union{Nothing, Missing, T}
37
- promote_rule (:: Type{Union{Nothing, Missing, S}} , :: Type{Any} ) where {S} = Any
38
- promote_rule (:: Type{Union{Nothing, Missing, S}} , :: Type{T} ) where {T,S} =
39
- Union{Nothing, Missing, promote_type (T, S)}
40
-
41
- convert (:: Type{Union{T, Missing}} , x:: Union{T, Missing} ) where {T} = x
42
- convert (:: Type{Union{T, Missing}} , x) where {T} = convert (T, x)
43
- # To fix ambiguities
44
- convert (:: Type{Missing} , :: Missing ) = missing
45
- convert (:: Type{Union{Nothing, Missing}} , x:: Union{Nothing, Missing} ) = x
46
- convert (:: Type{Union{Nothing, Missing, T}} , x:: Union{Nothing, Missing, T} ) where {T} = x
47
- convert (:: Type{Union{Nothing, Missing}} , x) =
48
- throw (MethodError (convert, (Union{Nothing, Missing}, x)))
49
- # To print more appropriate message than "T not defined"
50
- convert (:: Type{Missing} , x) = throw (MethodError (convert, (Missing, x)))
43
+ promote_rule (T:: Type{>:Missing} , S:: Type{Any} ) = Any
44
+ function promote_rule (T:: Type{>:Missing} , S:: Type )
45
+ R = nonmissingtype (T)
46
+ R >: T && return Any
47
+ T = R
48
+ R = promote_type (T, S)
49
+ return Union{R, Missing}
50
+ end
51
+
52
+ convert (T:: Type{>:Union{Missing, Nothing}} , x) = convert (nonmissingtype_checked (nonnothingtype_checked (T)), x)
53
+ convert (T:: Type{>:Missing} , x) = convert (nonmissingtype_checked (T), x)
54
+
51
55
52
56
# Comparison operators
53
57
== (:: Missing , :: Missing ) = missing
@@ -108,10 +112,10 @@ round(::Missing, ::RoundingMode=RoundNearest; sigdigits::Integer=0, digits::Inte
108
112
round (:: Type{>:Missing} , :: Missing , :: RoundingMode = RoundNearest) = missing
109
113
round (:: Type{T} , :: Missing , :: RoundingMode = RoundNearest) where {T} =
110
114
throw (MissingException (" cannot convert a missing value to type $T : use Union{$T , Missing} instead" ))
111
- round (:: Type{T} , x:: Any , r:: RoundingMode = RoundNearest) where {T>: Missing } = round (nonmissingtype (T), x, r)
115
+ round (:: Type{T} , x:: Any , r:: RoundingMode = RoundNearest) where {T>: Missing } = round (nonmissingtype_checked (T), x, r)
112
116
# to fix ambiguities
113
- round (:: Type{T} , x:: Rational , r:: RoundingMode = RoundNearest) where {T>: Missing } = round (nonmissingtype (T), x, r)
114
- round (:: Type{T} , x:: Rational{Bool} , r:: RoundingMode = RoundNearest) where {T>: Missing } = round (nonmissingtype (T), x, r)
117
+ round (:: Type{T} , x:: Rational , r:: RoundingMode = RoundNearest) where {T>: Missing } = round (nonmissingtype_checked (T), x, r)
118
+ round (:: Type{T} , x:: Rational{Bool} , r:: RoundingMode = RoundNearest) where {T>: Missing } = round (nonmissingtype_checked (T), x, r)
115
119
116
120
# Handle ceil, floor, and trunc separately as they have no RoundingMode argument
117
121
for f in (:(ceil), :(floor), :(trunc))
@@ -120,9 +124,9 @@ for f in (:(ceil), :(floor), :(trunc))
120
124
($ f)(:: Type{>:Missing} , :: Missing ) = missing
121
125
($ f)(:: Type{T} , :: Missing ) where {T} =
122
126
throw (MissingException (" cannot convert a missing value to type $T : use Union{$T , Missing} instead" ))
123
- ($ f)(:: Type{T} , x:: Any ) where {T>: Missing } = $ f (nonmissingtype (T), x)
127
+ ($ f)(:: Type{T} , x:: Any ) where {T>: Missing } = $ f (nonmissingtype_checked (T), x)
124
128
# to fix ambiguities
125
- ($ f)(:: Type{T} , x:: Rational ) where {T>: Missing } = $ f (nonmissingtype (T), x)
129
+ ($ f)(:: Type{T} , x:: Rational ) where {T>: Missing } = $ f (nonmissingtype_checked (T), x)
126
130
end
127
131
end
128
132
0 commit comments