From 999dde7339787a0efac5b874b6ccf14b7dace8e8 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 8 May 2024 09:40:46 +0530 Subject: [PATCH] Unicode: assume foldable ccall in category_code (#54394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following on from https://github.com/JuliaLang/julia/pull/54346, this marks the `ccall` in `category_code` as foldable. This lets us compute the results of several functions at compile time, such as: ```julia julia> @code_typed (() -> isletter('C'))() CodeInfo( 1 ─ return true ) => Bool julia> @code_typed (() -> isnumeric('C'))() CodeInfo( 1 ─ return false ) => Bool julia> @code_typed (() -> ispunct('C'))() CodeInfo( 1 ─ return false ) => Bool ``` --- base/strings/unicode.jl | 2 +- test/char.jl | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index b659ec080680b..9a44912946205 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -350,7 +350,7 @@ function category_code(c::AbstractChar) end function category_code(x::Integer) - x ≤ 0x10ffff ? ccall(:utf8proc_category, Cint, (UInt32,), x) : Cint(30) + x ≤ 0x10ffff ? (@assume_effects :foldable @ccall utf8proc_category(UInt32(x)::UInt32)::Cint) : Cint(30) end # more human-readable representations of the category code diff --git a/test/char.jl b/test/char.jl index 5a522dfd1c743..5da92121b1630 100644 --- a/test/char.jl +++ b/test/char.jl @@ -361,12 +361,17 @@ end @test convert(ASCIIChar, 1) == Char(1) end -@testset "foldable isuppercase/islowercase" begin +@testset "foldable functions" begin v = @inferred (() -> Val(isuppercase('C')))() @test v isa Val{true} v = @inferred (() -> Val(islowercase('C')))() @test v isa Val{false} + v = @inferred (() -> Val(isletter('C')))() + @test v isa Val{true} + v = @inferred (() -> Val(isnumeric('C')))() + @test v isa Val{false} + struct MyChar <: AbstractChar x :: Char end @@ -377,4 +382,9 @@ end @test v isa Val{true} v = @inferred (() -> Val(islowercase(MyChar('C'))))() @test v isa Val{false} + + v = @inferred (() -> Val(isletter(MyChar('C'))))() + @test v isa Val{true} + v = @inferred (() -> Val(isnumeric(MyChar('C'))))() + @test v isa Val{false} end