diff --git a/base/exports.jl b/base/exports.jl index 702c1bf485c3b..440b28fb155b2 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -656,6 +656,7 @@ export isbits, isequal, ismutable, + ismutabletype, isless, isunordered, ifelse, diff --git a/base/reflection.jl b/base/reflection.jl index 9558731a277d1..d13601ff6d16a 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -460,6 +460,23 @@ true """ ismutable(@nospecialize(x)) = (@_pure_meta; typeof(x).mutable) + +""" + ismutabletype(T) -> Bool + +Determine whether type `T` was declared as a mutable type +(i.e. using `mutable struct` keyword). + +!!! compat "Julia 1.7" + This function requires at least Julia 1.7. +""" +function ismutabletype(@nospecialize(t::Type)) + t = unwrap_unionall(t) + # TODO: what to do for `Union`? + return isa(t, DataType) && t.mutable +end + + """ isstructtype(T) -> Bool diff --git a/test/reflection.jl b/test/reflection.jl index ea54b833aeef0..63101796804bb 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -113,6 +113,9 @@ not_const = 1 @test ismutable(1) == false @test ismutable([]) == true +@test ismutabletype(Int) == false +@test ismutabletype(Vector{Any}) == true +@test ismutabletype(Union{Int, Vector{Any}}) == false ## find bindings tests @test ccall(:jl_get_module_of_binding, Any, (Any, Any), Base, :sin)==Base