ronantakizawa/codereview-bench huggingface dataset:
Repository: JetBrains/kotlin
File: compiler/testData/codegen/box/reflection/call/inlineClasses/simpleConstructorWithInlineClassParameter.kt (Kotlin)

Code before:
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE, WASM

// WITH_REFLECT

@JvmInline
value class Value(val value: String)

class A(val result: Value)

fun box(): String {
    val args: Array<Value> = arrayOf(Value("OK"))

    val a = (::A).call(*args)
    return a.result.value
}


Review comment (suggestion):
I added a test case in reference to `testData/codegen/box/reflection/call/simpleConstructor.kt`, but I couldn't come up with a good name.
Also, I am not sure about the `IGNORE` setting.

Code after:
// TARGET_BACKEND: JVM

// WITH_REFLECT

@JvmInline
value class Value(val value: String)

class A(val result: Value)

fun box(): String {
    val args: Array<Value> = arrayOf(Value("OK"))

    val a = (::A).call(*args)
    return a.result.value
}
Repository: JetBrains/kotlin
File: plugins/kotlinx-serialization/testData/boxIr/delegatedProperty.kt (Kotlin)

Code before:
// TARGET_BACKEND: JVM_IR

// WITH_STDLIB

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.json.*
import kotlin.reflect.KProperty
import kotlin.properties.*

@Serializable
data class SimpleDTO(
    val realProp: Int,
) {
    @Transient
    private val additionalProperties: Map<String, Int> = mapOf("delegatedProp" to 123)
    @Transient
    val delegatedProp: Int? by additionalProperties
}

// optimized properties must also work
// https://kotlinlang.org/docs/whatsnew1720.html#more-optimized-cases-of-delegated-properties
// A named object:
object NamedObject {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
data class DelegatedByObjectProperty(
    val realProp: Int
) {
    val delegatedProp: String by NamedObject
}

// A final val property with a backing field and a default getter in the same module:
val impl: ReadOnlyProperty<Any?, String> = object : ReadOnlyProperty<Any?, String> {
    override operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
class DelegatedByFinalVal(
    val realProp: Int

Review comment (suggestion):
I think `@Transient` shouldn't be here, as delegated property is transient automatically? At least it works without it.

Code after:
// TARGET_BACKEND: JVM_IR

// WITH_STDLIB

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.json.*
import kotlin.reflect.KProperty
import kotlin.properties.*

@Serializable
data class SimpleDTO(
    val realProp: Int,
) {
    @Transient
    private val additionalProperties: Map<String, Int> = mapOf("delegatedProp" to 123)
    val delegatedProp: Int? by additionalProperties
}

// optimized properties must also work
// https://kotlinlang.org/docs/whatsnew1720.html#more-optimized-cases-of-delegated-properties
// A named object:
object NamedObject {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
data class DelegatedByObjectProperty(
    val realProp: Int
) {
    val delegatedProp: String by NamedObject
}

// A final val property with a backing field and a default getter in the same module:
val impl: ReadOnlyProperty<Any?, String> = object : ReadOnlyProperty<Any?, String> {
    override operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
class DelegatedByFinalVal(
    val realProp: Int
) {
Repository: JetBrains/kotlin
File: libraries/stdlib/js/src/kotlin/collections/ArrayList.kt (Kotlin)

Code before:

        if (array.size > size) {
            array[size] = null as T // null-terminate
        }

        return array
    }

    override fun toArray(): Array<Any?> {
        return dummy.slice.call(array)
    }


    internal override fun checkIsMutable() {
        if (isReadOnly) throw UnsupportedOperationException()
    }

    private fun rangeCheck(index: Int) = index.apply {
        AbstractList.checkElementIndex(index, size)
    }

    private fun insertionRangeCheck(index: Int) = index.apply {
        AbstractList.checkPositionIndex(index, size)
    }
    
    private val dummy = js("[]")
}


Review comment (suggestion):
Not a very descriptive name, perhaps would be better `jsArrayPrototype` or something like that.

Code after:
    actual override fun indexOf(element: E): Int = array.indexOf(element)

    actual override fun lastIndexOf(element: E): Int = array.lastIndexOf(element)

    override fun toString() = arrayToString(array)

    @Suppress("UNCHECKED_CAST")
    override fun <T> toArray(array: Array<T>): Array<T> {
        if (array.size < size) {
            return toArray() as Array<T>
        }

        (this.array as Array<T>).copyInto(array)

        if (array.size > size) {
            array[size] = null as T // null-terminate
        }

        return array
    }

    override fun toArray(): Array<Any?> {
        return js("[]").slice.call(array)
    }


    internal override fun checkIsMutable() {
        if (isReadOnly) throw UnsupportedOperationException()
    }

    private fun rangeCheck(index: Int) = index.apply {
        AbstractList.checkElementIndex(index, size)
    }

    private fun insertionRangeCheck(index: Int) = index.apply {
        AbstractList.checkPositionIndex(index, size)
    }
}
Repository: JetBrains/kotlin
File: libraries/stdlib/js/src/kotlin/collections/ArrayList.kt (Kotlin)

Code before:
    }


    actual override fun indexOf(element: E): Int = array.indexOf(element)

    actual override fun lastIndexOf(element: E): Int = array.lastIndexOf(element)

    override fun toString() = arrayToString(array)

    @Suppress("UNCHECKED_CAST")
    override fun <T> toArray(array: Array<T>): Array<T> {
        if (array.size < size) {
            return toArray() as Array<T>
        }

        (this.array as Array<T>).copyInto(array)

        if (array.size > size) {
            array[size] = null as T // null-terminate
        }

        return array
    }

    override fun toArray(): Array<Any?> {
        return jsArrayPrototype.slice.call(array)
    }


    internal override fun checkIsMutable() {
        if (isReadOnly) throw UnsupportedOperationException()
    }

    private fun rangeCheck(index: Int) = index.apply {
        AbstractList.checkElementIndex(index, size)
    }

    private fun insertionRangeCheck(index: Int) = index.apply {
        AbstractList.checkPositionIndex(index, size)
    }

    private val jsArrayPrototype = js("[]")
}


Review comment (refactor):
It doesn't seem that jsArrayPrototype is now used anywhere except this function. Does it make sense to extract it then to a variable?

Code after:
    override fun removeRange(fromIndex: Int, toIndex: Int) {
        checkIsMutable()
        modCount++
        array.asDynamic().splice(fromIndex, toIndex - fromIndex)
    }

    actual override fun clear() {
        checkIsMutable()
        array = emptyArray()
        modCount++
    }


    actual override fun indexOf(element: E): Int = array.indexOf(element)

    actual override fun lastIndexOf(element: E): Int = array.lastIndexOf(element)

    override fun toString() = arrayToString(array)

    @Suppress("UNCHECKED_CAST")
    override fun <T> toArray(array: Array<T>): Array<T> {
        if (array.size < size) {
            return toArray() as Array<T>
        }

        (this.array as Array<T>).copyInto(array)

        if (array.size > size) {
            array[size] = null as T // null-terminate
        }

        return array
    }

    override fun toArray(): Array<Any?> {
        return js("[]").slice.call(array)
    }


    internal override fun checkIsMutable() {
        if (isReadOnly) throw UnsupportedOperationException()
    }

    private fun rangeCheck(index: Int) = index.apply {
        AbstractList.checkElementIndex(index, size)
    }

    private fun insertionRangeCheck(index: Int) = index.apply {
        AbstractList.checkPositionIndex(index, size)
    }
}
Repository: JuliaLang/julia
File: base/complex.jl (Julia)

Code before:
end

float(z::Complex{<:AbstractFloat}) = z
float(z::Complex) = Complex(float(real(z)), float(imag(z)))

big(::Type{Complex{T}}) where {T<:Real} = Complex{big(T)}
big(z::Complex{T}) where {T<:Real} = Complex{big(T)}(z)

## Array operations on complex numbers ##

complex(A::AbstractArray{<:Complex}) = A

function complex(A::AbstractArray{T}) where T
    if !isleaftype(T)
        error("`complex` not defined on abstractly-typed arrays; please convert to a more specific type")
    end
    convert(AbstractArray{typeof(complex(zero(T)))}, A)
end

## Promotion to complex ##

_default_type(T::Type{Complex}) = Complex{Int}

## Machine epsilon for complex ##

eps(z::Complex{T}) where {T<:AbstractFloat} = hypot(eps(real(z)), eps(imag(z)))


Review comment (refactor):
`hypot` is not defined till later in the system image load

So I think this should just be

```julia
function eps(z::Complex{T}) where {T<:AbstractFloat}
    x, y = eps(real(z)), eps(imag(z))
    if x < y
       x, y = y, x
    end
    r = y/x
    x * sqrt(one(T) + r * r)
end

```


Code after:
    return Complex{P}(z) ^ P(p)
end
function ^(z::T, p::Complex{S}) where {T<:Real,S<:Real}
    P = promote_type(T,S)
    return P(z) ^ Complex{P}(p)
end

function sin(z::Complex{T}) where T
    F = float(T)
    zr, zi = reim(z)
    if zr == 0
        Complex(F(zr), sinh(zi))
    elseif !isfinite(zr)
        if zi == 0 || isinf(zi)
            Complex(F(NaN), F(zi))
        else
            Complex(F(NaN), F(NaN))
        end
    else
        s, c = sincos(zr)
        Complex(s * cosh(zi), c * sinh(zi))
    end
end


function cos(z::Complex{T}) where T
    F = float(T)
    zr, zi = reim(z)
    if zr == 0
        Complex(cosh(zi), isnan(zi) ? F(zr) : -flipsign(F(zr),zi))
    elseif !isfinite(zr)
        if zi == 0
            Complex(F(NaN), isnan(zr) ? zero(F) : -flipsign(F(zi),zr))
        elseif isinf(zi)
            Complex(F(Inf), F(NaN))
        else
            Complex(F(NaN), F(NaN))
        end
    else
        s, c = sincos(zr)
        Complex(c * cosh(zi), -s * sinh(zi))
    end
end


function tan(z::Complex)
    zr, zi = reim(z)
    w = tanh(Complex(-zi, zr))
    Complex(imag(w), -real(w))
end
Repository: JuliaLang/julia
File: base/complex.jl (Julia)

Code before:
julia> complex([1, 2, 3])
3-element Vector{Complex{Int64}}:
 1 + 0im
 2 + 0im
 3 + 0im
```
"""
complex(A::AbstractArray{<:Complex}) = A

function complex(A::AbstractArray{T}) where T
    if !isconcretetype(T)
        error("`complex` not defined on abstractly-typed arrays; please convert to a more specific type")
    end
    convert(AbstractArray{typeof(complex(zero(T)))}, A)
end

## Promotion to complex ##

_default_type(T::Type{Complex}) = Complex{Int}

## Machine epsilon for complex ##

function eps(z::Complex{T}) where {T<:AbstractFloat}
    x, y = eps(real(z)), eps(imag(z))
    hypot(x, y)
end

eps(::Type{Complex{T}}) where {T<:AbstractFloat} = sqrt(2*one(T))*eps(T)


Review comment (refactor):
Can be shortened to:
```suggestion
eps(z::Complex{<:AbstractFloat}) = hypot(eps(real(z)), eps(imag(z)))
```

Code after:
julia> complex([1, 2, 3])
3-element Vector{Complex{Int64}}:
 1 + 0im
 2 + 0im
 3 + 0im
```
"""
complex(A::AbstractArray{<:Complex}) = A

function complex(A::AbstractArray{T}) where T
    if !isconcretetype(T)
        error("`complex` not defined on abstractly-typed arrays; please convert to a more specific type")
    end
    convert(AbstractArray{typeof(complex(zero(T)))}, A)
end

## Promotion to complex ##

_default_type(T::Type{Complex}) = Complex{Int}

## Machine epsilon for complex ##

eps(z::Complex{<:AbstractFloat}) = hypot(eps(real(z)), eps(imag(z)))

eps(::Type{Complex{T}}) where {T<:AbstractFloat} = sqrt(2*one(T))*eps(T)
Repository: JuliaLang/julia
File: stdlib/LinearAlgebra/src/symmetric.jl (Julia)

Code before:
!!! compat "Julia 1.3"
    This function requires Julia 1.3 or later.
"""
function symmetrize!(X::AbstractMatrix{<:AbstractFloat})
    require_one_based_indexing(X)
    n = checksquare(X)
    @inbounds for j = 2:n, i = 1:j-1
        X[i,j] = (X[i,j] + X[j,i]) / 2
        X[j,i] = X[i,j]
    end
    X
end

"""
    symmetrize(X::AbstractMatrix)

Construct a symmetric matrix based on `X` using the formula `(X + X') / 2`.
This function is a no-op for [`Symmetric`](@ref)-wrapped matrices.

See also: [`symmetrize!`](@ref)

!!! compat "Julia 1.3"
    This function requires Julia 1.3 or later.
"""
symmetrize(X::AbstractMatrix{<:AbstractFloat}) = symmetrize!(copy(X))
symmetrize(X::AbstractMatrix{<:Real}) = symmetrize!(float(X))
symmetrize(X::Symmetric) = X


Review comment (refactor):
If we allow for more element types than `AbstractFloat` then the promotion here should be adjusted.

Code after:

"""
    hermitianpart!(A, uplo=:U) -> Hermitian

Overwrite the square matrix `A` in-place with its Hermitian part `(A + A') / 2`, and return
[`Hermitian(A, uplo)`](@ref). For real matrices `A`, this is also known as the symmetric
part of `A`.

See also [`hermitianpart`](@ref) for the corresponding out-of-place operation.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart!(A), uplo)

_hermitianpart(A::AbstractMatrix) = _hermitianpart!(copy_similar(A, Base.promote_op(/, eltype(A), Int)))
_hermitianpart(a::Number) = real(a)

function _hermitianpart!(A::AbstractMatrix)
    require_one_based_indexing(A)
    n = checksquare(A)
    @inbounds for j in 1:n
        A[j, j] = _hermitianpart(A[j, j])
        for i in 1:j-1
            A[i, j] = val = (A[i, j] + adjoint(A[j, i])) / 2
            A[j, i] = adjoint(val)
        end
    end
    return A
end
Repository: JuliaLang/julia
File: stdlib/LinearAlgebra/src/symmetric.jl (Julia)

Code before:

See also: [`symmetrize`](@ref)

!!! compat "Julia 1.3"
    This function requires Julia 1.3 or later.
"""
symmetrize!(X::AbstractMatrix; conjugate::Bool=true) =
    conjugate ? _symmetrize!(conj, real, X) : _symmetrize!(identity, identity, X)

function _symmetrize!(f::Function, g::Function, X::AbstractMatrix)
    inds = axes(X, 1)
    inds == axes(X, 2) || throw(DimensionMismatch("matrix is not square"))
    r = first(inds)
    s = step(inds)
    @inbounds for j in inds
        X[j,j] = g(X[j,j])
        for i in r:s:j-s
            X[i,j] = (X[i,j] + f(X[j,i])) / 2
            X[j,i] = f(X[i,j])
        end
    end
    X
end

const ClosedUnderDivision = Union{AbstractFloat, Complex{<:AbstractFloat},
                                  Rational, Complex{<:Rational}}

"""
    symmetrize(X::AbstractMatrix; conjugate::Bool=true)

Construct a symmetric matrix based on `X` using the formula `(X + X') / 2`.
If `conjugate` is `true`, the result is Hermitian rather than symmetric.

See also: [`symmetrize!`](@ref)

!!! compat "Julia 1.3"
    This function requires Julia 1.3 or later.
"""
symmetrize(X::AbstractMatrix{<:ClosedUnderDivision}; conjugate::Bool=true) =
    symmetrize!(copy(X), conjugate=conjugate)
symmetrize(X::AbstractMatrix; conjugate::Bool=true) =
    symmetrize!(float(X), conjugate=conjugate)
symmetrize(X::Symmetric{<:Real}; conjugate::Bool=true) = X
symmetrize(X::Symmetric{<:Complex}; conjugate::Bool=true) = conjugate ? Hermitian(X) : X
symmetrize(X::Hermitian; conjugate::Bool=true) = X


Review comment (refactor):
This doesn't seem very general.

Why not use
```
hermitian(X::AbstractMatrix) = hermitian!(copyto!(similar, X, typeof((isempty(X) ? zero(eltype(X)) : first(X))/2)), X))
```
instead?  (Not sure if we really care about the `empty(X)` case, but I guess it doesn't hurt.)

Code after:
"""
hermitianpart(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart(A), uplo)

"""
    hermitianpart!(A, uplo=:U) -> Hermitian

Overwrite the square matrix `A` in-place with its Hermitian part `(A + A') / 2`, and return
[`Hermitian(A, uplo)`](@ref). For real matrices `A`, this is also known as the symmetric
part of `A`.

See also [`hermitianpart`](@ref) for the corresponding out-of-place operation.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart!(A), uplo)

_hermitianpart(A::AbstractMatrix) = _hermitianpart!(copy_similar(A, Base.promote_op(/, eltype(A), Int)))
_hermitianpart(a::Number) = real(a)

function _hermitianpart!(A::AbstractMatrix)
    require_one_based_indexing(A)
    n = checksquare(A)
    @inbounds for j in 1:n
        A[j, j] = _hermitianpart(A[j, j])
        for i in 1:j-1
            A[i, j] = val = (A[i, j] + adjoint(A[j, i])) / 2
            A[j, i] = adjoint(val)
        end
    end
    return A
end
Repository: JuliaLang/julia
File: stdlib/LinearAlgebra/src/symmetric.jl (Julia)

Code before:
symmetricpart!(A::AbstractMatrix, uplo::Symbol=:U) =
    Symmetric(_hermorsympart!(identity, identity, A, char_uplo(uplo)), uplo)

"""
    hermitianpart(A, uplo=:U)

Return the Hermitian part of the square matrix `A`, defined as `(A + A') / 2`,
as a [`Hermitian`](@ref) matrix.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart(A::AbstractMatrix{T}, uplo=:U) where {T} =
    hermitianpart!(copyto!(similar(A, typeof(one(T) / 2)), A), uplo)

"""
    hermitianpart!(A, uplo=:U)

Overwrite the square matrix `A` with its Hermitian part, `(A + A') / 2`,
and return `Hermitian(A, uplo)`.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) =
    Hermitian(_hermorsympart!(real, conj, A, char_uplo(uplo)), uplo)

function _hermorsympart!(real::Function, conj::Function, A::AbstractMatrix, uplo::Char)
    require_one_based_indexing(A)
    n = checksquare(A)
    triangle = uplo === 'U' ? (j -> 1:(j - 1)) : (j -> (j + 1):n)
    @inbounds for j in 1:n
        A[j, j] = real(A[j, j])
        for i in triangle(j)
            A[i, j] = (A[i, j] + conj(A[j, i])) / 2
        end
    end
    return A
end


Review comment (suggestion):
```suggestion
    Hermitian(_hermorsympart!(hermitianpart, adjoint, A, char_uplo(uplo)), uplo)
```

Code after:
            end
        end
    end
end

"""
    hermitianpart(A, uplo=:U) -> Hermitian

Return the Hermitian part of the square matrix `A`, defined as `(A + A') / 2`, as a
[`Hermitian`](@ref) matrix. For real matrices `A`, this is also known as the symmetric part
of `A`; it is also sometimes called the "operator real part". The optional argument `uplo` controls the corresponding argument of the
[`Hermitian`](@ref) view. For real matrices, the latter is equivalent to a
[`Symmetric`](@ref) view.

See also [`hermitianpart!`](@ref) for the corresponding in-place operation.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart(A), uplo)

"""
    hermitianpart!(A, uplo=:U) -> Hermitian

Overwrite the square matrix `A` in-place with its Hermitian part `(A + A') / 2`, and return
[`Hermitian(A, uplo)`](@ref). For real matrices `A`, this is also known as the symmetric
part of `A`.

See also [`hermitianpart`](@ref) for the corresponding out-of-place operation.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart!(A), uplo)

_hermitianpart(A::AbstractMatrix) = _hermitianpart!(copy_similar(A, Base.promote_op(/, eltype(A), Int)))
_hermitianpart(a::Number) = real(a)

function _hermitianpart!(A::AbstractMatrix)
    require_one_based_indexing(A)
    n = checksquare(A)
    @inbounds for j in 1:n
        A[j, j] = _hermitianpart(A[j, j])
        for i in 1:j-1
            A[i, j] = val = (A[i, j] + adjoint(A[j, i])) / 2
            A[j, i] = adjoint(val)
        end
    end
    return A
end
Repository: JuliaLang/julia
File: stdlib/LinearAlgebra/src/symmetric.jl (Julia)

Code before:
!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart(A::AbstractMatrix{T}, uplo=:U) where {T} =
    hermitianpart!(copyto!(similar(A, typeof(one(T) / 2)), A), uplo)
hermitianpart(x::Number) = real(x)

"""
    hermitianpart!(A, uplo=:U)

Overwrite the square matrix `A` with its Hermitian part, `(A + A') / 2`,
and return `Hermitian(A, uplo)`.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) =
    Hermitian(_hermorsympart!(hermitianpart, adjoint, A, char_uplo(uplo)), uplo)

function _hermorsympart!(real::Function, conj::Function, A::AbstractMatrix, uplo::Char)
    require_one_based_indexing(A)
    n = checksquare(A)
    triangle = uplo === 'U' ? (j -> 1:(j - 1)) : (j -> (j + 1):n)
    @inbounds for j in 1:n
        A[j, j] = real(A[j, j])
        for i in triangle(j)
            A[i, j] = (A[i, j] + conj(A[j, i])) / 2
        end
    end
    return A
end


Review comment (suggestion):
Maybe just
```
for i in (uplo === 'U' ? (1:(j - 1)) : ((j + 1):n))
```
?  I'm skeptical that a function call is faster than a conditional here, since the compiler presumably won't be able to inline `triangle(j)`.

Code after:
of `A`; it is also sometimes called the "operator real part". The optional argument `uplo` controls the corresponding argument of the
[`Hermitian`](@ref) view. For real matrices, the latter is equivalent to a
[`Symmetric`](@ref) view.

See also [`hermitianpart!`](@ref) for the corresponding in-place operation.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart(A), uplo)

"""
    hermitianpart!(A, uplo=:U) -> Hermitian

Overwrite the square matrix `A` in-place with its Hermitian part `(A + A') / 2`, and return
[`Hermitian(A, uplo)`](@ref). For real matrices `A`, this is also known as the symmetric
part of `A`.

See also [`hermitianpart`](@ref) for the corresponding out-of-place operation.

!!! compat "Julia 1.10"
    This function requires Julia 1.10 or later.
"""
hermitianpart!(A::AbstractMatrix, uplo::Symbol=:U) = Hermitian(_hermitianpart!(A), uplo)

_hermitianpart(A::AbstractMatrix) = _hermitianpart!(copy_similar(A, Base.promote_op(/, eltype(A), Int)))
_hermitianpart(a::Number) = real(a)

function _hermitianpart!(A::AbstractMatrix)
    require_one_based_indexing(A)
    n = checksquare(A)
    @inbounds for j in 1:n
        A[j, j] = _hermitianpart(A[j, j])
        for i in 1:j-1
            A[i, j] = val = (A[i, j] + adjoint(A[j, i])) / 2
            A[j, i] = adjoint(val)
        end
    end
    return A
end