Skip to content

Instantly share code, notes, and snippets.

@phipsgabler
Created August 25, 2021 14:38
Show Gist options
  • Save phipsgabler/29052ce618965627300562d4298d6d1c to your computer and use it in GitHub Desktop.
Save phipsgabler/29052ce618965627300562d4298d6d1c to your computer and use it in GitHub Desktop.
Type stable trait for checking field types
julia> HasFields(::Type{T}) where {T} = Val{true}()
HasFields (generic function with 1 method)
julia> HasFields(::Type{T}, ::Type{U}, name) where {T, U} = Val{fieldtype(T, name) <: U}()
HasFields (generic function with 2 methods)
julia> HasFields(Some, Any, :value)
Val{true}()
julia> HasFields(::Type{T}, ::Type{U}, name, names...) where {T, U} = Val{fieldtype(T, name) <: U && HasFields(T, U, names...) isa Val{true}}()
HasFields (generic function with 3 methods)
julia> HasFields(Pair{Int, Int}, Int, :first, :second)
Val{true}()
julia> @code_warntype HasFields(Pair{Int, Int}, Int, :first, :second)
Variables
#self#::Core.Const(HasFields)
#unused#@_2::Core.Const(Pair{Int64, Int64})
#unused#@_3::Core.Const(Int64)
name::Symbol
names::Tuple{Symbol}
@_6::Bool
Body::Val{true}
1 ─ %1 = Main.fieldtype($(Expr(:static_parameter, 1)), name)::Core.Const(Int64)
│ %2 = (%1 <: $(Expr(:static_parameter, 2)))::Core.Const(true)
│ %2
│ %4 = Core.tuple($(Expr(:static_parameter, 1)), $(Expr(:static_parameter, 2)))::Core.Const((Pair{Int64, Int64}, Int64))
│ %5 = Core._apply_iterate(Base.iterate, Main.HasFields, %4, names)::Core.Const(Val{true}())
│ %6 = Core.apply_type(Main.Val, true)::Core.Const(Val{true})
│ (@_6 = %5 isa %6)
└── goto #3
2 ─ Core.Const(:(@_6 = false))
3 ┄ %10 = @_6::Core.Const(true)::Core.Const(true)
│ %11 = Core.apply_type(Main.Val, %10)::Core.Const(Val{true})
│ %12 = (%11)()::Core.Const(Val{true}())
└── return %12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment