diff --git a/base/boot.jl b/base/boot.jl index ef0bc5e5074cb..2fdfc2e8cacb9 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -432,11 +432,12 @@ Array{T}(A::AbstractArray{S,N}) where {T,N,S} = Array{T,N}(A) AbstractArray{T}(A::AbstractArray{S,N}) where {T,S,N} = AbstractArray{T,N}(A) # primitive Symbol constructors -function Symbol(s::String) +eval(Core, :(function Symbol(s::String) + $(Expr(:meta, :pure)) return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int), ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s), sizeof(s)) -end +end)) function Symbol(a::Array{UInt8,1}) return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int), ccall(:jl_array_ptr, Ptr{UInt8}, (Any,), a), diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index b53030f71614c..dcb91ac1f952f 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -73,7 +73,9 @@ function quoted(@nospecialize(x)) end function is_inlineable_constant(@nospecialize(x)) - x isa Type && return true + if x isa Type || x isa Symbol + return true + end return isbits(x) && Core.sizeof(x) <= MAX_INLINE_CONST_SIZE end diff --git a/base/strings/string.jl b/base/strings/string.jl index a65e02f7653bc..56b603f0cce35 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -66,7 +66,7 @@ Convert a string to a contiguous byte array representation encoded as UTF-8 byte This representation is often appropriate for passing strings to C. """ String(s::AbstractString) = print_to_string(s) -String(s::Symbol) = unsafe_string(unsafe_convert(Ptr{UInt8}, s)) +@pure String(s::Symbol) = unsafe_string(unsafe_convert(Ptr{UInt8}, s)) unsafe_wrap(::Type{Vector{UInt8}}, s::String) = ccall(:jl_string_to_array, Ref{Vector{UInt8}}, (Any,), s) @@ -81,8 +81,8 @@ String(s::CodeUnits{UInt8,String}) = s.s pointer(s::String) = unsafe_convert(Ptr{UInt8}, s) pointer(s::String, i::Integer) = pointer(s)+(i-1) -ncodeunits(s::String) = Core.sizeof(s) -sizeof(s::String) = Core.sizeof(s) +@pure ncodeunits(s::String) = Core.sizeof(s) +@pure sizeof(s::String) = Core.sizeof(s) codeunit(s::String) = UInt8 @inline function codeunit(s::String, i::Integer) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index a69d7c776608b..5f78cf7c97269 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -1711,20 +1711,19 @@ g26826(x) = getfield26826(x, :a, :b) # If this test is broken (especially if inference is getting a correct, but loose result, # like a Union) then it's potentially an indication that the optimizer isn't hitting the # InferenceResult cache properly for varargs methods. -typed_code = Core.Compiler.code_typed(f26826, (Float64,))[1].first -found_well_typed_getfield_call = false -let i +let ct = Core.Compiler.code_typed(f26826, (Float64,))[1] + typed_code, retty = ct.first, ct.second + found_poorly_typed_getfield_call = false for i = 1:length(typed_code.code) stmt = typed_code.code[i] rhs = Meta.isexpr(stmt, :(=)) ? stmt.args[2] : stmt - if Meta.isexpr(rhs, :call) && rhs.args[1] == GlobalRef(Base, :getfield) && typed_code.ssavaluetypes[i] === Float64 - global found_well_typed_getfield_call = true + if Meta.isexpr(rhs, :call) && rhs.args[1] == GlobalRef(Base, :getfield) && typed_code.ssavaluetypes[i] !== Float64 + found_poorly_typed_getfield_call = true end end + @test !found_poorly_typed_getfield_call && retty === Float64 end -@test found_well_typed_getfield_call - # 27059 fix fieldtype vararg and union handling f27059(::Type{T}) where T = i -> fieldtype(T, i) @@ -2482,3 +2481,7 @@ end @test Base.return_types(g33768, ()) == Any[Any] @test_throws ArgumentError h33768() @test Base.return_types(h33768, ()) == Any[Union{}] + +# constant prop of `Symbol("")` +f_getf_computed_symbol(p) = getfield(p, Symbol("first")) +@test Base.return_types(f_getf_computed_symbol, Tuple{Pair{Int8,String}}) == [Int8]