One more thing. You can define your own “catch-all” method and do what you want with everything that is not an Integer (I think is better to do this instead of deleting methods):
@kwdef struct A
x::Integer = 0
end
A(x) = error("I really don't want to convert stuff.")
A(x) = error("I really don't want to convert stuff (overriding).")
A('a')
# ERROR: I really don't want to convert stuff (overriding).
# Stacktrace:
# [1] error(s::String)
# @ Base ./error.jl:35
# [2] A(x::Char)
# @ Main ~/code/playtest/innerconstr.jl:23
# [3] top-level scope
# @ ~/code/playtest/innerconstr.jl:25
A(1) # works
Regardless of what was generated by @kwdef as A(x) method, the most recent one is in effect (you can see that I also generated two of them - but only the last one counts).
@Benny, I think we (or at least, I) need someone with internals knowledge.
After some more digging, I reached this stage - and, well, that is a pretty large code base to be able to derive any non-speculative conclusions (also, my C knowledge ends at a now forgotten page number from K&R book - no real-world project whatsoever).
However, this becomes time-consuming with no real progress for me (unless the permalink above can be considered progress), and I am not even sure I am on the right path. Should we tag somebody? Or open an issue?
If you’re referring to the new mystery, maybe a new discourse thread tagged Internals and Design since this has gone beyond the specific use case here. As for an issue I wouldn’t even know what it should be, maybe some people on that thread could help narrow that down.
I see 4 issues. All of these seem concerning enough to me to escalate, but I am not qualified enough to be certain. And I don’t know who to raise these with.
convert has strange behavior here:
instance = (a=NaN,)
type1 = NamedTuple{(:a,), Tuple{A}} where A<:Real # abstract type
instance::type1 # confirms that instance is of type1
convert(type1, instance) # ERROR: UndefVarError: `T` not defined
internal type constructor tries to apply convert even when the type assertion already holds:
struct F
x::type1
F(x::type1=instance) = new(x)
end
F() # UndefVarError: `T` not defined
The default struct constructor has a method that accepts arguments without type restrictions, even though the struct field is type-annotated:
julia> struct A
a::Int64
end
julia> methods(A)
# 2 methods for type constructor:
[1] A(a::Int64)
@ REPL[7]:2
[2] A(a)
@ REPL[7]:2
function definitions allow default values of improper types:
f(x::Integer="Not Integer") = "Why is this allowed?" # does not throw error
f() # throws an error