Bug during redefinition of `Base.getproperty` for abstract type

why does this bug occur?

if you run this code, the console will give a lot of “name” and close with an error, but I didn’t even run the function

abstract type AbstractNewType end

function Base.getproperty(x::Type{A}, key::Symbol) where {A<:AbstractNewType}
    println(key)
    println(x)
end

I can run this without problem in Julia 1.9 on Linux. What does versioninfo() say?

Julia Version 1.8.5
Commit 17cfb8e65ea (2023-01-08 06:45 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin21.5.0)
  CPU: 8 × Apple M1 Pro
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, apple-m1)
  Threads: 1 on 6 virtual cores
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 

Also no problem on Julia 1.8.5, Windows 10.

I can reproduce with

abstract type MyType end
function Base.getproperty(x::Type{A}, key::Symbol) where {A<:MyType}
    println(key)
    println(x)
end

[foo() for i in 1:2 for j in 1:2]

I think this code is comitting type piracy, because the user owns MyType but not Type{<:MyType}.

1 Like

It’s technically piracy, but just becaues A <: MyType can be A = Union{}. But even without straight piracy, redefining any aspects for Type{MyType} may easily mess with Julia internals expectation. Better not to do that (: At best, maybe you can add properties, but surely should keep existing ones.

1 Like

Are you sure you need to define this for ::Type{<:AbstractNewType} (for the subtypes) and not just ::AbstractNewType (an instance of the abstract type)?

I’ve never felt the need to define properties for types themselves (and, for that matter, I seldom define a non-default getproperty for any object). If you find this necessary, an alternative is to instead define some accessor functions and use those rather than getproperty. E.g., flavor(::Type{<:AbstractNewType}) = :chocolate.

This is type piracy. There are many points in the compiler where SomeType.field is used and it expects that the field of the type is returned.