diff --git a/base/strings/io.jl b/base/strings/io.jl index 9204310129729..46353ff6f7c29 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -354,12 +354,20 @@ function join(io::IO, iterator, delim="") end function _join_preserve_annotations(iterator, args...) - if _isannotated(eltype(iterator)) || any(_isannotated, args) + if isconcretetype(eltype(iterator)) && !_isannotated(eltype(iterator)) && !any(_isannotated, args) + sprint(join, iterator, args...) + else io = AnnotatedIOBuffer() join(io, iterator, args...) - read(seekstart(io), AnnotatedString{String}) - else - sprint(join, iterator, args...) + # If we know (from compile time information, or dynamically in the case + # of iterators with a non-concrete eltype), that the result is annotated + # in nature, we extract an `AnnotatedString`, otherwise we just extract + # a plain `String` from `io`. + if isconcretetype(eltype(iterator)) || !isempty(io.annotations) + read(seekstart(io), AnnotatedString{String}) + else + String(take!(io.io)) + end end end diff --git a/test/strings/annotated.jl b/test/strings/annotated.jl index da76f0f020531..8eab0567221e6 100644 --- a/test/strings/annotated.jl +++ b/test/strings/annotated.jl @@ -101,6 +101,8 @@ end [(1:4, :label => 5), (5:5, :label => 2), (6:9, :label => 5)]) + @test join((String(str1), str1), ' ') == + Base.AnnotatedString("test test", [(6:9, :label => 5)]) @test repeat(str1, 2) == Base.AnnotatedString("testtest", [(1:8, :label => 5)]) @test repeat(str2, 2) == Base.AnnotatedString("casecase", [(2:3, :label => "oomph"), (6:7, :label => "oomph")])