At first I thought it was because @nospecialize was specified in Base.unwrap_unionall, but that doesn’t seem to be the case. Of course, the body field of UnionAll is boxed, so it should require special handling.

julia> Base.@aggressive_constprop constprop_unwrap(::Type{T}) where {T} = nameof(T)
constprop_unwrap (generic function with 1 method)
julia> @code_typed constprop_unwrap(Complex{Float32})
CodeInfo(
1 ─ return :Complex
) => Symbol

I’d do something like

@static if VERSION >= v"1.7.0-DEV.421"
Base.@aggressive_constprop constprop_unwrap(::Type{T}) where {T} = nameof(T)
else
@generated constprop_unwrap(::Type{T}) where {T} = QuoteNode(nameof(T))
end

@generated function is a powerful tool, but it is a little too powerful. In the use case I’m envisioning, the output of nameof is used for conditional branching and not for the final output. In other words, once the compilation is done, there is no need to remember it anymore.

I don’t follow. What do you mean by “remember”?
You want a function to compile, but not be “saved”? I don’t think that is possible for ordinary functions either. Methods and a lot of metadata (e.g. inference results) will be cached.

If you’re only using the results once, then that implies latency is more important than compile times, so spending more time on inference/const prop isn’t worth it?