diff --git a/base/abstractarray.jl b/base/abstractarray.jl
index fbd2ff7547b8f..1e3ffb7c7bca0 100644
--- a/base/abstractarray.jl
+++ b/base/abstractarray.jl
@@ -1299,6 +1299,19 @@ julia> hcat(c...)
"""
hcat(X...) = cat(Val{2}, X...)
+"""
+ ++(X...)
+
+`++` is a generic concatenation operator. By default, it
+calls [`vcat`](@ref), concatenating arrays and elements thereof.
+For strings and characters, it performs string concatenation.
+Similarly, for other types it may perform an appropriate concatenation
+operation.
+"""
+++(X...) = concat(concat_typeof(X...), X...)
+concat(::Type{<:Any}, X...) = vcat(X...) # default
+concat_rule(::Type{<:AbstractArray}, S) = (@_inline_meta; Array) # arrays should concatenate to arrays
+
typed_vcat(T::Type, X...) = cat_t(Val{1}, T, X...)
typed_hcat(T::Type, X...) = cat_t(Val{2}, T, X...)
diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl
index 058170e3d5041..54555cb1bf97c 100644
--- a/base/abstractarraymath.jl
+++ b/base/abstractarraymath.jl
@@ -387,7 +387,7 @@ _rshps(shp, shp_i, sz, ::Tuple{}, o) =
(n = length(shp); N = n + length(sz); _reperr("inner", n, N))
_rshps(shp, shp_i, sz, i, ::Tuple{}) =
(n = length(shp); N = n + length(sz); _reperr("outer", n, N))
-_reperr(s, n, N) = throw(ArgumentError("number of " * s * " repetitions " *
+_reperr(s, n, N) = throw(ArgumentError("number of " ++ s ++ " repetitions " ++
"($n) cannot be less than number of dimensions of input ($N)"))
@propagate_inbounds function _repeat(A::AbstractArray, inner, outer)
diff --git a/base/atomics.jl b/base/atomics.jl
index f44edbeb75527..900c45ba2adef 100644
--- a/base/atomics.jl
+++ b/base/atomics.jl
@@ -421,7 +421,7 @@ for typ in atomictypes
fn = Symbol("atomic_", rmw, "!")
if (rmw == "max" || rmw == "min") && typ <: Unsigned
# LLVM distinguishes signedness in the operation, not the integer type.
- rmw = "u" * rmw
+ rmw = "u" ++ rmw
end
if typ <: Integer
@eval $fn(x::Atomic{$typ}, v::$typ) =
diff --git a/base/broadcast.jl b/base/broadcast.jl
index b4fd9126727c4..90d57c497fa02 100644
--- a/base/broadcast.jl
+++ b/base/broadcast.jl
@@ -420,7 +420,7 @@ julia> string.(("one","two","three","four"), ": ", 1:4)
"three: 3"
"four: 4"
-julia> Nullable("X") .* "Y"
+julia> Nullable("X") .++ "Y"
Nullable{String}("XY")
julia> broadcast(/, 1.0, Nullable(2.0))
diff --git a/base/client.jl b/base/client.jl
index 4013fcd42ceb1..016dd9ea918ef 100644
--- a/base/client.jl
+++ b/base/client.jl
@@ -219,7 +219,7 @@ parse_input_line(s::AbstractString) = parse_input_line(String(s))
function parse_input_line(io::IO)
s = ""
while !eof(io)
- s *= readline(io, chomp=false)
+ s = s ++ readline(io, chomp=false)
e = parse_input_line(s)
if !(isa(e,Expr) && e.head === :incomplete)
return e
diff --git a/base/dates/periods.jl b/base/dates/periods.jl
index 628e077b1aec8..817ededa8fc64 100644
--- a/base/dates/periods.jl
+++ b/base/dates/periods.jl
@@ -10,7 +10,7 @@ for period in (:Year, :Month, :Week, :Day, :Hour, :Minute, :Second, :Millisecond
period_str = string(period)
accessor_str = lowercase(period_str)
# Convenience method for show()
- @eval _units(x::$period) = " " * $accessor_str * (abs(value(x)) == 1 ? "" : "s")
+ @eval _units(x::$period) = " " ++ $accessor_str ++ (abs(value(x)) == 1 ? "" : "s")
# periodisless
@eval periodisless(x::$period, y::$period) = value(x) < value(y)
# AbstractString parsing (mainly for IO code)
@@ -334,7 +334,7 @@ function Base.string(x::CompoundPeriod)
else
s = ""
for p in x.periods
- s *= ", " * string(p)
+ s *= ", " ++ string(p)
end
return s[3:end]
end
diff --git a/base/deprecated.jl b/base/deprecated.jl
index c47894dce94f4..731b5660b97a1 100644
--- a/base/deprecated.jl
+++ b/base/deprecated.jl
@@ -395,8 +395,8 @@ export $
# promote_op method where the operator is also a type
function promote_op(op::Type, Ts::Type...)
- depwarn("promote_op(op::Type, ::Type...) is deprecated as it is no " *
- "longer needed in Base. If you need its functionality, consider " *
+ depwarn("promote_op(op::Type, ::Type...) is deprecated as it is no " ++
+ "longer needed in Base. If you need its functionality, consider " ++
"defining it locally.", :promote_op)
if isdefined(Core, :Inference)
return Core.Inference.return_type(op, Tuple{Ts...})
@@ -721,8 +721,8 @@ _promote_array_type(::typeof(\), ::Type{<:Integer}, ::Type{Bool}, T::Type) = T
_promote_array_type(F, ::Type{<:Integer}, ::Type{Bool}, T::Type) = T
_promote_array_type{T<:AbstractFloat}(F, ::Type{<:Union{Complex, Real}}, ::Type{Complex{T}}, ::Type) = Complex{T}
function promote_array_type(F, R, S, T)
- Base.depwarn("`promote_array_type` is deprecated as it is no longer needed " *
- "in Base. See https://github.com/JuliaLang/julia/issues/19669 " *
+ Base.depwarn("`promote_array_type` is deprecated as it is no longer needed " ++
+ "in Base. See https://github.com/JuliaLang/julia/issues/19669 " ++
"for more information.", :promote_array_type)
_promote_array_type(F, R, S, T)
end
@@ -1165,8 +1165,8 @@ end
return func
else
msg = "$f($sig; negate=$negate) is deprecated, use $f("
- negate && (msg *= "!")
- msg *= "$sig) instead."
+ negate && (msg = msg ++ "!")
+ msg = msg ++ "$sig) instead."
Base.depwarn(msg, f)
return negate ? !func : func
end
@@ -1434,6 +1434,10 @@ module Operators
end
export Operators
+# deprecate old string-concatenation ops in favor of ++
+@deprecate (*)(s1::AbstractString, ss::AbstractString...) (++)(s1, ss...)
+@deprecate (^)(s::AbstractString, r::Integer) repeat(s,r)
+
# PR #21956
# This mimics the structure as it was defined in Base to avoid directly breaking code
# that assumes this structure
diff --git a/base/distributed/cluster.jl b/base/distributed/cluster.jl
index 3fdb113989573..502ca9c321e4c 100644
--- a/base/distributed/cluster.jl
+++ b/base/distributed/cluster.jl
@@ -112,7 +112,7 @@ function check_worker_state(w::Worker)
wait(w.c_state)
w.state == W_CREATED && error("peer $(w.id) didn't connect to $(myid()) within $timeout seconds")
else
- error("peer $(w.id) is not connected to $(myid()). Topology : " * string(PGRP.topology))
+ error("peer $(w.id) is not connected to $(myid()). Topology : ", PGRP.topology)
end
end
end
diff --git a/base/exports.jl b/base/exports.jl
index 34e266a0ee002..1584d58d77c6b 100644
--- a/base/exports.jl
+++ b/base/exports.jl
@@ -236,6 +236,7 @@ export
:,
=>,
∘,
+ ++,
A_ldiv_B!,
A_ldiv_Bc,
A_ldiv_Bt,
diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl
index 32cfb81047023..7ec501fd97296 100644
--- a/base/interactiveutil.jl
+++ b/base/interactiveutil.jl
@@ -222,7 +222,7 @@ function _show_cpuinfo(io::IO, info::Sys.CPUinfo, header::Bool=true, prefix::Abs
tck = Sys.SC_CLK_TCK
if header
println(io, info.model, ": ")
- print(io, " "^length(prefix))
+ print(io, repeat(" ",length(prefix)))
if tck > 0
@printf(io, " %5s %9s %9s %9s %9s %9s\n",
"speed", "user", "nice", "sys", "idle", "irq")
@@ -419,8 +419,8 @@ function gen_call_with_extracted_types(__module__, fcn, ex0)
end
if (!is_macro && ex.head == :thunk) || exret.head == :none
exret = Expr(:call, :error, "expression is not a function call, "
- * "or is too complex for @$fcn to analyze; "
- * "break it down to simpler parts if possible")
+ ++ "or is too complex for @$fcn to analyze; "
+ ++ "break it down to simpler parts if possible")
end
exret
end
@@ -690,7 +690,7 @@ function runtests(tests = ["all"], numcores = ceil(Int, Sys.CPU_CORES / 2))
catch
buf = PipeBuffer()
versioninfo(buf)
- error("A test has failed. Please submit a bug report (https://github.com/JuliaLang/julia/issues)\n" *
+ error("A test has failed. Please submit a bug report (https://github.com/JuliaLang/julia/issues)\n" ++
"including error messages above and the output of versioninfo():\n$(readstring(buf))")
end
end
diff --git a/base/libgit2/callbacks.jl b/base/libgit2/callbacks.jl
index 0a78f48949f47..217f47658d005 100644
--- a/base/libgit2/callbacks.jl
+++ b/base/libgit2/callbacks.jl
@@ -205,7 +205,7 @@ function credentials_callback(libgit2credptr::Ptr{Ptr{Void}}, url_ptr::Cstring,
# parse url for schema and host
urlparts = match(URL_REGEX, url)
- schema = urlparts[:scheme] === nothing ? "" : urlparts[:scheme] * "://"
+ schema = urlparts[:scheme] === nothing ? "" : urlparts[:scheme] ++ "://"
urlusername = urlparts[:user] === nothing ? "" : urlparts[:user]
host = urlparts[:host]
@@ -241,7 +241,7 @@ function credentials_callback(libgit2credptr::Ptr{Ptr{Void}}, url_ptr::Cstring,
# with the remote host.
if err == 0
if explicit
- warn("The explicitly provided credentials were incompatible with " *
+ warn("The explicitly provided credentials were incompatible with ",
"the server's supported authentication methods")
end
err = Cint(Error.EAUTH)
diff --git a/base/libgit2/utils.jl b/base/libgit2/utils.jl
index 59b84bf905427..19e4e61b645f4 100644
--- a/base/libgit2/utils.jl
+++ b/base/libgit2/utils.jl
@@ -35,7 +35,7 @@ function prompt(msg::AbstractString; default::AbstractString="", password::Bool=
if is_windows() && password
error("Command line prompt not supported for password entry on windows. Use winprompt instead")
end
- msg = !isempty(default) ? msg*" [$default]:" : msg*":"
+ msg = !isempty(default) ? msg++" [$default]:" : msg++":"
uinput = if password
Base.getpass(msg)
else
diff --git a/base/libuv.jl b/base/libuv.jl
index 702fad7392081..d9ef8e4eb6cbf 100644
--- a/base/libuv.jl
+++ b/base/libuv.jl
@@ -66,7 +66,7 @@ uverrorname(err::UVError) = uverrorname(err.code)
uv_error(prefix::Symbol, c::Integer) = uv_error(string(prefix),c)
uv_error(prefix::AbstractString, c::Integer) = c < 0 ? throw(UVError(prefix,c)) : nothing
-show(io::IO, e::UVError) = print(io, e.prefix*": "*struverror(e)*" ("*uverrorname(e)*")")
+show(io::IO, e::UVError) = print(io, e.prefix,": ",struverror(e)," (",uverrorname(e),")")
## event loop ##
diff --git a/base/linalg/cholesky.jl b/base/linalg/cholesky.jl
index 434a7fdbe5a5c..ebeeef443a40c 100644
--- a/base/linalg/cholesky.jl
+++ b/base/linalg/cholesky.jl
@@ -126,8 +126,8 @@ end
chol!(x::Number, uplo) = ((C, info) = _chol!(x, uplo); @assertposdef C info)
-non_hermitian_error(f) = throw(ArgumentError("matrix is not symmetric/" *
- "Hermitian. This error can be avoided by calling $f(Hermitian(A)) " *
+non_hermitian_error(f) = throw(ArgumentError("matrix is not symmetric/" ++
+ "Hermitian. This error can be avoided by calling $f(Hermitian(A)) " ++
"which will ignore either the upper or lower triangle of the matrix."))
# chol!. Destructive methods for computing Cholesky factor of real symmetric or Hermitian
diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl
index 9a020b5a0dece..689ca68d3d98e 100644
--- a/base/linalg/generic.jl
+++ b/base/linalg/generic.jl
@@ -1058,7 +1058,7 @@ function linreg(x::AbstractVector, y::AbstractVector)
# b = cov(X, Y)/var(X)
# a = mean(Y) - b*mean(X)
if size(x) != size(y)
- throw(DimensionMismatch("x has size $(size(x)) and y has size $(size(y)), " *
+ throw(DimensionMismatch("x has size $(size(x)) and y has size $(size(y)), " ++
"but these must be the same size"))
end
mx = mean(x)
diff --git a/base/linalg/triangular.jl b/base/linalg/triangular.jl
index a9935851177cc..3a8ef0b4b322a 100644
--- a/base/linalg/triangular.jl
+++ b/base/linalg/triangular.jl
@@ -130,7 +130,7 @@ getindex(A::UpperTriangular, i::Integer, j::Integer) =
function setindex!(A::UpperTriangular, x, i::Integer, j::Integer)
if i > j
- x == 0 || throw(ArgumentError("cannot set index in the lower triangular part " *
+ x == 0 || throw(ArgumentError("cannot set index in the lower triangular part " ++
"($i, $j) of an UpperTriangular matrix to a nonzero value ($x)"))
else
A.data[i,j] = x
@@ -140,10 +140,10 @@ end
function setindex!(A::UnitUpperTriangular, x, i::Integer, j::Integer)
if i > j
- x == 0 || throw(ArgumentError("cannot set index in the lower triangular part " *
+ x == 0 || throw(ArgumentError("cannot set index in the lower triangular part " ++
"($i, $j) of a UnitUpperTriangular matrix to a nonzero value ($x)"))
elseif i == j
- x == 1 || throw(ArgumentError("cannot set index on the diagonal ($i, $j) " *
+ x == 1 || throw(ArgumentError("cannot set index on the diagonal ($i, $j) " ++
"of a UnitUpperTriangular matrix to a non-unit value ($x)"))
else
A.data[i,j] = x
@@ -153,7 +153,7 @@ end
function setindex!(A::LowerTriangular, x, i::Integer, j::Integer)
if i < j
- x == 0 || throw(ArgumentError("cannot set index in the upper triangular part " *
+ x == 0 || throw(ArgumentError("cannot set index in the upper triangular part " ++
"($i, $j) of a LowerTriangular matrix to a nonzero value ($x)"))
else
A.data[i,j] = x
@@ -163,10 +163,10 @@ end
function setindex!(A::UnitLowerTriangular, x, i::Integer, j::Integer)
if i < j
- x == 0 || throw(ArgumentError("cannot set index in the upper triangular part " *
+ x == 0 || throw(ArgumentError("cannot set index in the upper triangular part " ++
"($i, $j) of a UnitLowerTriangular matrix to a nonzero value ($x)"))
elseif i == j
- x == 1 || throw(ArgumentError("cannot set index on the diagonal ($i, $j) " *
+ x == 1 || throw(ArgumentError("cannot set index on the diagonal ($i, $j) " ++
"of a UnitLowerTriangular matrix to a non-unit value ($x)"))
else
A.data[i,j] = x
diff --git a/base/loading.jl b/base/loading.jl
index 1382f4f2a00ed..74a26eaf38cf5 100644
--- a/base/loading.jl
+++ b/base/loading.jl
@@ -140,7 +140,7 @@ function find_all_in_cache_path(mod::Symbol)
name = string(mod)
paths = String[]
for prefix in LOAD_CACHE_PATH
- path = joinpath(prefix, name*".ji")
+ path = joinpath(prefix, name++".ji")
if isfile_casesensitive(path)
push!(paths, path)
end
@@ -345,7 +345,7 @@ function require_modname(name::AbstractString)
if endswith(name, ".jl")
tmp = name[1:end-3]
for prefix in LOAD_CACHE_PATH
- path = joinpath(prefix, tmp*".ji")
+ path = joinpath(prefix, tmp++".ji")
if isfile(path)
return tmp
end
@@ -658,7 +658,7 @@ function compilecache(name::String)
if !isdir(cachepath)
mkpath(cachepath)
end
- cachefile::String = abspath(cachepath, name*".ji")
+ cachefile::String = abspath(cachepath, name++".ji")
# build up the list of modules that we want the precompile process to preserve
concrete_deps = copy(_concrete_dependencies)
for existing in names(Main)
diff --git a/base/markdown/Common/block.jl b/base/markdown/Common/block.jl
index a0c4a095d3bae..e4f92b4c615bc 100644
--- a/base/markdown/Common/block.jl
+++ b/base/markdown/Common/block.jl
@@ -303,7 +303,7 @@ function list(stream::IO, block::MD)
end
else
newline = false
- if startswith(stream, " "^indent)
+ if startswith(stream, repeat(" ",indent))
# Indented text that is part of the current list item.
print(buffer, readline(stream, chomp=false))
else
diff --git a/base/markdown/GitHub/table.jl b/base/markdown/GitHub/table.jl
index a8313e3fa6629..cd9b45924a2a1 100644
--- a/base/markdown/GitHub/table.jl
+++ b/base/markdown/GitHub/table.jl
@@ -91,15 +91,15 @@ function padcells!(rows, align; len = length, min = 0)
for i = 1:length(rows), j = indices(rows[1],1)
cell = rows[i][j]
lpad, rpad = padding(len(cell), widths[j], align[j])
- rows[i][j] = " "^lpad * cell * " "^rpad
+ rows[i][j] = repeat(" ",lpad) ++ cell ++ repeat(" ",rpad)
end
return rows
end
_dash(width, align) =
- align == :l ? ":" * "-"^width * " " :
- align == :r ? " " * "-"^width * ":" :
- align == :c ? ":" * "-"^width * ":" :
+ align == :l ? ":" ++ repeat("-",width) ++ " " :
+ align == :r ? " " ++ repeat("-",width) ++ ":" :
+ align == :c ? ":" ++ repeat("-",width) ++ ":" :
throw(ArgumentError("Invalid alignment $align"))
function plain(io::IO, md::Table)
diff --git a/base/markdown/render/latex.jl b/base/markdown/render/latex.jl
index fb0650c5d6603..9ef5ae0b3b4be 100644
--- a/base/markdown/render/latex.jl
+++ b/base/markdown/render/latex.jl
@@ -25,7 +25,7 @@ function latex(io::IO, content::Vector)
end
function latex(io::IO, header::Header{l}) where l
- tag = l < 4 ? "sub"^(l-1) * "section" : "sub"^(l-4) * "paragraph"
+ tag = l < 4 ? repeat("sub",l-1) ++ "section" : repeat("sub",l-4) ++ "paragraph"
wrapinline(io, tag) do
latexinline(io, header.text)
end
diff --git a/base/markdown/render/plain.jl b/base/markdown/render/plain.jl
index 5d50b5c2080f1..70027429d76a0 100644
--- a/base/markdown/render/plain.jl
+++ b/base/markdown/render/plain.jl
@@ -14,7 +14,7 @@ end
plain(io::IO, md::MD) = plain(io, md.content)
function plain(io::IO, header::Header{l}) where l
- print(io, "#"^l*" ")
+ print(io, repeat("#",l)++" ")
plaininline(io, header.text)
println(io)
end
@@ -122,7 +122,7 @@ plaininline(io::IO, md::Italic) = plaininline(io, "*", md.text, "*")
function plaininline(io::IO, md::Code)
if contains(md.code, "`")
n = maximum(length(m) for m in matchall(r"(`+)", md.code))
- s = "`"^((iseven(n) ? 1 : 2) + n)
+ s = repeat("`", (iseven(n) ? 1 : 2) + n)
print(io, s, Base.startswith(md.code, "`") ? " " : "")
print(io, md.code, endswith(md.code, "`") ? " " : "", s)
else
diff --git a/base/markdown/render/rst.jl b/base/markdown/render/rst.jl
index d9fadc4e7910e..7eca9fc85bca2 100644
--- a/base/markdown/render/rst.jl
+++ b/base/markdown/render/rst.jl
@@ -42,7 +42,7 @@ function rst(io::IO, list::List)
print(io, bullet)
lines = split(rstrip(sprint(rst, item)), '\n')
for (n, line) in enumerate(lines)
- print(io, (n == 1 || isempty(line)) ? "" : " "^length(bullet), line)
+ print(io, (n == 1 || isempty(line)) ? "" : repeat(" ",length(bullet)), line)
n < length(lines) && println(io)
end
println(io)
diff --git a/base/markdown/render/terminal/formatting.jl b/base/markdown/render/terminal/formatting.jl
index 36a4d390a7138..27a172bbc9010 100644
--- a/base/markdown/render/terminal/formatting.jl
+++ b/base/markdown/render/terminal/formatting.jl
@@ -72,7 +72,7 @@ function wrapped_lines(s::AbstractString; width = 80, i = 0)
push!(lines, word)
else
i += word_length + 1
- lines[end] *= " " * word
+ lines[end] = lines[end] ++ " " ++ word
end
end
return lines
@@ -95,7 +95,7 @@ print_wrapped(f::Function, io::IO, args...; kws...) = print_wrapped(io, f, args.
function print_centred(io::IO, s...; columns = 80, width = columns)
lines = wrapped_lines(s..., width = width)
for line in lines
- print(io, " "^(div(columns-ansi_length(line), 2)))
+ print(io, repeat(" ",div(columns-ansi_length(line), 2)))
println(io, line)
end
length(lines), length(pre) + length(lines[end])
@@ -103,5 +103,5 @@ end
function centred(s, columns)
pad = div(columns - ansi_length(s), 2)
- " "^pad * s
+ repeat(" ",pad) ++ s
end
diff --git a/base/markdown/render/terminal/render.jl b/base/markdown/render/terminal/render.jl
index f7313dc36b23f..c872d6bcd32ac 100644
--- a/base/markdown/render/terminal/render.jl
+++ b/base/markdown/render/terminal/render.jl
@@ -17,8 +17,8 @@ end
term(io::IO, md::MD, columns = cols(io)) = term(io, md.content, columns)
function term(io::IO, md::Paragraph, columns)
- print(io, " "^margin)
- print_wrapped(io, width = columns-2margin, pre = " "^margin) do io
+ print(io, repeat(" ",margin))
+ print_wrapped(io, width = columns-2margin, pre = repeat(" ",margin)) do io
terminline(io, md.content)
end
end
@@ -26,34 +26,34 @@ end
function term(io::IO, md::BlockQuote, columns)
s = sprint(term, md.content, columns - 10)
for line in split(rstrip(s), "\n")
- println(io, " "^margin, "|", line)
+ println(io, repeat(" ",margin), "|", line)
end
end
function term(io::IO, md::Admonition, columns)
- print(io, " "^margin, "| ")
+ print(io, repeat(" ",margin), "| ")
with_output_format(:bold, print, io, isempty(md.title) ? md.category : md.title)
- println(io, "\n", " "^margin, "|")
+ println(io, "\n", repeat(" ",margin), "|")
s = sprint(term, md.content, columns - 10)
for line in split(rstrip(s), "\n")
- println(io, " "^margin, "|", line)
+ println(io, repeat(" ",margin), "|", line)
end
end
function term(io::IO, f::Footnote, columns)
- print(io, " "^margin, "| ")
+ print(io, repeat(" ",margin), "| ")
with_output_format(:bold, print, io, "[^$(f.id)]")
- println(io, "\n", " "^margin, "|")
+ println(io, "\n", repeat(" ",margin), "|")
s = sprint(term, f.text, columns - 10)
for line in split(rstrip(s), "\n")
- println(io, " "^margin, "|", line)
+ println(io, repeat(" ",margin), "|", line)
end
end
function term(io::IO, md::List, columns)
for (i, point) in enumerate(md.items)
- print(io, " "^2margin, isordered(md) ? "$(i + md.ordered - 1). " : "• ")
- print_wrapped(io, width = columns-(4margin+2), pre = " "^(2margin+2),
+ print(io, repeat(" ",2margin), isordered(md) ? "$(i + md.ordered - 1). " : "• ")
+ print_wrapped(io, width = columns-(4margin+2), pre = repeat(" ",2margin+2),
i = 2margin+2) do io
term(io, point, columns - 10)
end
@@ -63,14 +63,14 @@ end
function _term_header(io::IO, md, char, columns)
text = terminline(md.text)
with_output_format(:bold, io) do io
- print(io, " "^(2margin), " ")
+ print(io, repeat(" ",2margin), " ")
line_no, lastline_width = print_wrapped(io, text,
width=columns - 4margin; pre=" ")
line_width = min(1 + lastline_width, columns)
if line_no > 1
line_width = max(line_width, div(columns, 3))
end
- char != ' ' && println(io, " "^(2margin), string(char) ^ line_width)
+ char != ' ' && println(io, repeat(" ",2margin), string(char) ^ line_width)
end
end
@@ -85,7 +85,7 @@ end
function term(io::IO, md::Code, columns)
with_output_format(:cyan, io) do io
for line in lines(md.code)
- print(io, " "^margin)
+ print(io, repeat(" ",margin))
println(io, line)
end
end
@@ -96,7 +96,7 @@ function term(io::IO, br::LineBreak, columns)
end
function term(io::IO, br::HorizontalRule, columns)
- println(io, " " ^ margin, "-" ^ (columns - 2margin))
+ println(io, repeat(" ",margin), repeat("-", columns - 2margin))
end
term(io::IO, x, _) = show(io, MIME"text/plain"(), x)
diff --git a/base/meta.jl b/base/meta.jl
index bbe4c3f49bde6..8c27d738eff4f 100644
--- a/base/meta.jl
+++ b/base/meta.jl
@@ -28,20 +28,20 @@ const sexpr_indent_width = 2
function show_sexpr(io::IO, ex::QuoteNode, indent::Int)
inner = indent + sexpr_indent_width
- print(io, "(:quote, #QuoteNode\n", " "^inner)
+ print(io, "(:quote, #QuoteNode\n", repeat(" ",inner))
show_sexpr(io, ex.value, inner)
- print(io, '\n', " "^indent, ')')
+ print(io, '\n', repeat(" ",indent), ')')
end
function show_sexpr(io::IO, ex::Expr, indent::Int)
inner = indent + sexpr_indent_width
print(io, '(')
show_sexpr(io, ex.head, inner)
for arg in ex.args
- print(io, ex.head === :block ? ",\n"*" "^inner : ", ")
+ print(io, ex.head === :block ? ",\n"++repeat(" ",inner) : ", ")
show_sexpr(io, arg, inner)
end
if isempty(ex.args); print(io, ",)")
- else print(io, (ex.head === :block ? "\n"*" "^indent : ""), ')')
+ else print(io, (ex.head === :block ? "\n"++repeat(" ",indent) : ""), ')')
end
end
diff --git a/base/methodshow.jl b/base/methodshow.jl
index d6b223da5f1ab..2098dd14778ce 100644
--- a/base/methodshow.jl
+++ b/base/methodshow.jl
@@ -34,7 +34,7 @@ function argtype_decl(env, n, sig::DataType, i::Int, nargs, isva::Bool) # -> (ar
if tt === Any || (isa(tt, TypeVar) && (tt === v1 || tt === v2))
return string(s, "..."), ""
else
- return s, string_with_env(env, tt) * "..."
+ return s, string_with_env(env, tt) ++ "..."
end
end
return s, string_with_env(env, "Vararg{", tt, ",", tn, "}")
@@ -118,7 +118,7 @@ function show(io::IO, m::Method; kwtype::Nullable{DataType}=Nullable{DataType}()
print(io, "(", d1[1], "::", d1[2], ")")
end
print(io, "(")
- join(io, [isempty(d[2]) ? d[1] : d[1]*"::"*d[2] for d in decls[2:end]],
+ join(io, [isempty(d[2]) ? d[1] : d[1]++"::"++d[2] for d in decls[2:end]],
", ", ", ")
if !isnull(kwtype)
kwargs = kwarg_decl(m, get(kwtype))
@@ -185,7 +185,7 @@ function inbase(m::Module)
parent === m ? false : inbase(parent)
end
end
-fileurl(file) = let f = find_source_file(file); f === nothing ? "" : "file://"*f; end
+fileurl(file) = let f = find_source_file(file); f === nothing ? "" : "file://"++f; end
function url(m::Method)
M = m.module
@@ -211,7 +211,7 @@ function url(m::Method)
commit = string(LibGit2.head_oid(repo))
root = LibGit2.path(repo)
if startswith(file, root) || startswith(realpath(file), root)
- "https://github.com/$u/tree/$commit/"*file[length(root)+1:end]*"#L$line"
+ "https://github.com/$u/tree/$commit/"++file[length(root)+1:end]++"#L$line"
else
fileurl(file)
end
@@ -248,7 +248,7 @@ function show(io::IO, ::MIME"text/html", m::Method; kwtype::Nullable{DataType}=N
print(io,"")
end
print(io, "(")
- join(io, [isempty(d[2]) ? d[1] : d[1]*"::"*d[2]*""
+ join(io, [isempty(d[2]) ? d[1] : d[1]++"::"++d[2]++""
for d in decls[2:end]], ", ", ", ")
if !isnull(kwtype)
kwargs = kwarg_decl(m, get(kwtype))
diff --git a/base/path.jl b/base/path.jl
index 28ac0b520e85d..541edef0cbcbc 100644
--- a/base/path.jl
+++ b/base/path.jl
@@ -178,7 +178,7 @@ function splitext(path::String)
a, b = splitdrive(path)
m = match(path_ext_splitter, b)
m === nothing && return (path,"")
- a*m.captures[1], String(m.captures[2])
+ a ++ m.captures[1], String(m.captures[2])
end
function pathsep(paths::AbstractString...)
@@ -252,10 +252,10 @@ function normpath(path::String)
end
path = join(parts, path_separator)
if isabs
- path = path_separator*path
+ path = path_separator ++ path
end
if isdir && !isdirpath(path)
- path *= path_separator
+ path = path ++ path_separator
end
string(drive,path)
end
@@ -333,7 +333,7 @@ function expanduser(path::AbstractString)
if c != '~' return path end
if done(path,i) return homedir() end
c, j = next(path,i)
- if c == '/' return homedir()*path[i:end] end
+ if c == '/' return homedir() ++ path[i:end] end
throw(ArgumentError("~user tilde expansion not yet implemented"))
end
end
@@ -373,10 +373,10 @@ function relpath(path::String, startpath::String = ".")
pathpart = join(path_arr[i+1:findlast(x -> !isempty(x), path_arr)], path_separator)
prefix_num = findlast(x -> !isempty(x), start_arr) - i - 1
if prefix_num >= 0
- prefix = pardir * path_separator
+ prefix = pardir ++ path_separator
relpath_ = isempty(pathpart) ?
- (prefix^prefix_num) * pardir :
- (prefix^prefix_num) * pardir * path_separator * pathpart
+ repeat(prefix,prefix_num) ++ pardir :
+ repeat(prefix,prefix_num) ++ pardir ++ path_separator ++ pathpart
else
relpath_ = pathpart
end
diff --git a/base/pkg/entry.jl b/base/pkg/entry.jl
index 41f638102cfdb..ddefde0c0cde2 100644
--- a/base/pkg/entry.jl
+++ b/base/pkg/entry.jl
@@ -305,7 +305,7 @@ function pin(pkg::AbstractString, head::AbstractString)
# note: changing the following naming scheme requires a corresponding change in Read.ispinned()
branch = "pinned.$(string(id)[1:8]).tmp"
if LibGit2.isattached(repo) && LibGit2.branch(repo) == branch
- info("Package $pkg is already pinned" * (isempty(head) ? "" : " to the selected commit"))
+ info("Package $pkg is already pinned", (isempty(head) ? "" : " to the selected commit"))
should_resolve = false
return
end
@@ -313,7 +313,7 @@ function pin(pkg::AbstractString, head::AbstractString)
try
if !isnull(ref)
if LibGit2.revparseid(repo, branch) != id
- throw(PkgError("Package $pkg: existing branch $branch has " *
+ throw(PkgError("Package $pkg: existing branch $branch has " ++
"been edited and doesn't correspond to its original commit"))
end
info("Package $pkg: checking out existing branch $branch")
@@ -375,8 +375,8 @@ function update(branch::AbstractString, upkgs::Set{String})
end
catch err
cex = CapturedException(err, catch_backtrace())
- throw(PkgError("METADATA cannot be updated. Resolve problems manually in " *
- Pkg.dir("METADATA") * ".", cex))
+ throw(PkgError("METADATA cannot be updated. Resolve problems manually in " ++
+ Pkg.dir("METADATA") ++ ".", cex))
end
end
deferred_errors = CompositeException()
@@ -394,8 +394,8 @@ function update(branch::AbstractString, upkgs::Set{String})
reqs = Reqs.parse("REQUIRE")
if !isempty(upkgs)
for (pkg, (v,f)) in instd
- satisfies(pkg, v, reqs) || throw(PkgError("Package $pkg: current " *
- "package status does not satisfy the requirements, cannot do " *
+ satisfies(pkg, v, reqs) || throw(PkgError("Package $pkg: current " ++
+ "package status does not satisfy the requirements, cannot do " ++
"a partial update; use `Pkg.update()`"))
end
end
@@ -483,11 +483,11 @@ function resolve(
for pkg in keys(reqs)
if !haskey(deps,pkg)
if "julia" in conflicts[pkg]
- throw(PkgError("$pkg can't be installed because it has no versions that support $VERSION " *
+ throw(PkgError("$pkg can't be installed because it has no versions that support $VERSION " ++
"of julia. You may need to update METADATA by running `Pkg.update()`"))
else
sconflicts = join(conflicts[pkg], ", ", " and ")
- throw(PkgError("$pkg's requirements can't be satisfied because " *
+ throw(PkgError("$pkg's requirements can't be satisfied because " ++
"of the following fixed packages: $sconflicts"))
end
end
diff --git a/base/pkg/read.jl b/base/pkg/read.jl
index dc4046fa3db92..60927125235f6 100644
--- a/base/pkg/read.jl
+++ b/base/pkg/read.jl
@@ -245,7 +245,7 @@ function issue_url(pkg::AbstractString)
ispath(pkg,".git") || return ""
m = match(LibGit2.GITHUB_REGEX, url(pkg))
m === nothing && return ""
- return "https://github.com/" * m.captures[1] * "/issues"
+ return "https://github.com/" ++ m.captures[1] ++ "/issues"
end
end # module
diff --git a/base/pkg/resolve.jl b/base/pkg/resolve.jl
index a8481a9aee5c0..0a0caa168804c 100644
--- a/base/pkg/resolve.jl
+++ b/base/pkg/resolve.jl
@@ -44,7 +44,7 @@ function resolve(reqs::Requires, deps::Dict{String,Dict{VersionNumber,Available}
environment variable)
"""
end
- ## info("ERROR MESSAGE:\n" * msg)
+ ## info("ERROR MESSAGE:\n", msg)
throw(PkgError(msg))
end
@@ -101,7 +101,7 @@ function sanity_check(deps::Dict{String,Dict{VersionNumber,Available}},
sub_deps = Query.prune_dependencies(sub_reqs, deps)
catch err
isa(err, PkgError) || rethrow(err)
- ## info("ERROR MESSAGE:\n" * err.msg)
+ ## info("ERROR MESSAGE:\n", err.msg)
for vneq in eq_classes[p][vn]
push!(problematic, (p, vneq, ""))
end
diff --git a/base/printf.jl b/base/printf.jl
index b743ab6e05529..2d34625ad33cc 100644
--- a/base/printf.jl
+++ b/base/printf.jl
@@ -62,7 +62,7 @@ function parse(s::AbstractString)
j -= 1
break
end
- list[i] *= list[j]
+ list[i] = list[i] ++ list[j]
end
deleteat!(list,i+1:j)
end
diff --git a/base/process.jl b/base/process.jl
index ea421ce4e729f..f4e335d63713b 100644
--- a/base/process.jl
+++ b/base/process.jl
@@ -206,10 +206,10 @@ end
byteenv(env::AbstractArray{<:AbstractString}) =
String[cstr(x) for x in env]
byteenv(env::Associative) =
- String[cstr(string(k)*"="*string(v)) for (k,v) in env]
+ String[cstr(string(k)++"="++string(v)) for (k,v) in env]
byteenv(env::Void) = nothing
byteenv(env::Union{AbstractVector{Pair{T}}, Tuple{Vararg{Pair{T}}}}) where {T<:AbstractString} =
- String[cstr(k*"="*string(v)) for (k,v) in env]
+ String[cstr(k++"="++string(v)) for (k,v) in env]
"""
setenv(command::Cmd, env; dir="")
@@ -774,9 +774,9 @@ process_signaled(s::Process) = (s.termsignal > 0)
function process_status(s::Process)
process_running(s) ? "ProcessRunning" :
- process_signaled(s) ? "ProcessSignaled("*string(s.termsignal)*")" :
- #process_stopped(s) ? "ProcessStopped("*string(process_stop_signal(s))*")" :
- process_exited(s) ? "ProcessExited("*string(s.exitcode)*")" :
+ process_signaled(s) ? "ProcessSignaled("*string(s.termsignal)++")" :
+ #process_stopped(s) ? "ProcessStopped("*string(process_stop_signal(s))++")" :
+ process_exited(s) ? "ProcessExited("*string(s.exitcode)++")" :
error("process status error")
end
diff --git a/base/profile.jl b/base/profile.jl
index a5afcb3fdfb62..3a4bf3f8cf18c 100644
--- a/base/profile.jl
+++ b/base/profile.jl
@@ -474,7 +474,7 @@ function tree_format(lilist::Vector{StackFrame}, counts::Vector{Int}, level::Int
for i = 1:length(lilist)
li = lilist[i]
if li != UNKNOWN
- base = " "^nindent
+ base = repeat(" ",nindent)
if showextra
base = string(base, "+", nextra, " ")
end
diff --git a/base/promotion.jl b/base/promotion.jl
index e5f2bdd6f80de..fc681ee282139 100644
--- a/base/promotion.jl
+++ b/base/promotion.jl
@@ -360,3 +360,26 @@ minmax(x::Real) = (x, x)
max(x::T, y::T) where {T<:Real} = select_value(y < x, x, y)
min(x::T, y::T) where {T<:Real} = select_value(y < x, y, x)
minmax(x::T, y::T) where {T<:Real} = y < x ? (y, x) : (x, y)
+
+# Concatenation via a++b++... -> concat(concate_typeof(a,b,..), a,b,...):
+# Similar to promote_rule, you can define a concat_rule(T, S) to
+# determine how instances of two types T and S are concatenated. The
+# default is "Bottom", which gets turned into a vcat call in abstractarray.jl.
+concat_typeof() = concat_type()
+concat_typeof(x) = concat_type(typeof(x))
+concat_typeof(x, xs...) = (@_inline_meta; concat_type(typeof(x), concat_typeof(xs...)))
+concat_type() = Bottom
+concat_type(T, S...) = (@_inline_meta; concat_type(T, concat_type(S...)))
+concat_type(::Type{Bottom}, ::Type{Bottom}) = Bottom
+concat_type(::Type{T}, ::Type{Bottom}) where {T} = T
+concat_type(::Type{Bottom}, ::Type{T}) where {T} = T
+function concat_type(::Type{T}, ::Type{S}) where {T,S}
+ @_inline_meta
+ concat_result(concat_rule(T,S), concat_rule(S,T))
+end
+concat_result(::Type{T},::Type{T}) where {T} = (@_inline_meta; T)
+concat_result(::Type{Bottom},::Type{T}) where {T} = (@_inline_meta; T)
+concat_result(::Type{T},::Type{Bottom}) where {T} = (@_inline_meta; T)
+concat_result(::Type{Bottom},::Type{Bottom}) = (@_inline_meta; Bottom)
+concat_result(::Type{T},::Type{S}) where {T,S} = (@_inline_meta; Bottom)
+concat_rule(T, S) = (@_inline_meta; Bottom)
diff --git a/base/reflection.jl b/base/reflection.jl
index a13fc7e9bdb4a..f64e3f3a64d33 100644
--- a/base/reflection.jl
+++ b/base/reflection.jl
@@ -695,7 +695,7 @@ function _dump_function_linfo(linfo::Core.MethodInstance, world::UInt, native::B
end
# TODO: use jl_is_cacheable_sig instead of isleaftype
- isleaftype(linfo.specTypes) || (str = "; WARNING: This code may not match what actually runs.\n" * str)
+ isleaftype(linfo.specTypes) || (str = "; WARNING: This code may not match what actually runs.\n" ++ str)
return str
end
diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl
index 4beccbff1841b..d3c81d77975f9 100644
--- a/base/repl/LineEdit.jl
+++ b/base/repl/LineEdit.jl
@@ -693,7 +693,7 @@ function add_nested_key!(keymap::Dict, key, value; override = false)
break
else
if !isa(keymap[c], Dict)
- error("Conflicting definitions for keyseq " * escape_string(key) * " within one keymap")
+ error("Conflicting definitions for keyseq ", escape_string(key), " within one keymap")
end
end
elseif done(key, i)
@@ -868,7 +868,7 @@ function keymap_merge(target,source)
while isa(value, Union{Char,AbstractString})
value = normalize_key(value)
if value in visited
- error("Eager redirection cycle detected for key " * escape_string(key))
+ error("Eager redirection cycle detected for key ", escape_string(key))
end
push!(visited,value)
if !haskey(source,value)
@@ -880,7 +880,7 @@ function keymap_merge(target,source)
if isa(value, Union{Char,AbstractString})
value = getEntry(ret, value)
if value === nothing
- error("Could not find redirected value " * escape_string(source[key]))
+ error("Could not find redirected value ", escape_string(source[key]))
end
end
add_nested_key!(ret, key, value; override = true)
@@ -1321,7 +1321,7 @@ function bracketed_paste(s)
indent = Base.indentation(input; tabwidth=tabwidth)[1]
input = Base.unindent(input, indent; tabwidth=tabwidth)
end
- return replace(input, '\t', " "^tabwidth)
+ return replace(input, '\t', repeat(" ",tabwidth))
end
const default_keymap =
@@ -1341,7 +1341,7 @@ AnyDict(
# after a space, e.g., `cd `, while still
# allowing multiple indent levels
(c == UInt8(' ') && i > 3 && buf.data[i-1] == UInt8(' '))
- edit_insert(s, " "^4)
+ edit_insert(s, repeat(" ",4))
return
end
end
diff --git a/base/repl/REPLCompletions.jl b/base/repl/REPLCompletions.jl
index 4a80c24991cf3..cdebca62a65a0 100644
--- a/base/repl/REPLCompletions.jl
+++ b/base/repl/REPLCompletions.jl
@@ -400,9 +400,9 @@ end
function dict_identifier_key(str,tag)
if tag === :string
- str_close = str*"\""
+ str_close = str++"\""
elseif tag === :cmd
- str_close = str*"`"
+ str_close = str++"`"
else
str_close = str
end
@@ -479,7 +479,7 @@ function completions(string, pos)
if inc_tag == :other && should_method_complete(partial)
frange, method_name_end = find_start_brace(partial)
ex = Base.syntax_deprecation_warnings(false) do
- parse(partial[frange] * ")", raise=false)
+ parse(partial[frange] ++ ")", raise=false)
end
if isa(ex, Expr) && ex.head==:call
return complete_methods(ex), start(frange):method_name_end, false
diff --git a/base/repl/emoji_symbols.jl b/base/repl/emoji_symbols.jl
index f8a5043f19f36..b48473b641fe2 100644
--- a/base/repl/emoji_symbols.jl
+++ b/base/repl/emoji_symbols.jl
@@ -6,7 +6,7 @@ emojis = JSON.parsefile(download("https://raw.githubusercontent.com/iamcal/emoji
result = Dict()
for emj in emojis
- name = "\\:" * emj["short_name"] * ":"
+ name = "\\:" ++ emj["short_name"] ++ ":"
unicode = emj["unified"]
if '-' in unicode
continue
diff --git a/base/sharedarray.jl b/base/sharedarray.jl
index 6ef164720b836..45c167deb400d 100644
--- a/base/sharedarray.jl
+++ b/base/sharedarray.jl
@@ -129,7 +129,7 @@ function SharedArray{T,N}(dims::Dims{N}; init=false, pids=Int[]) where {T,N}
else
rc = remotecall_fetch(shm_unlink, shmmem_create_pid, shm_seg_name)
end
- systemerror("Error unlinking shmem segment " * shm_seg_name, rc != 0)
+ systemerror("Error unlinking shmem segment " ++ shm_seg_name, rc != 0)
end
S = SharedArray{T,N}(dims, pids, refs, shm_seg_name, s)
initialize_shared_array(S, onlocalhost, init, pids)
@@ -647,7 +647,7 @@ shm_unlink(shm_seg_name) = 0
else # !windows
function _shm_mmap_array(T, dims, shm_seg_name, mode)
fd_mem = shm_open(shm_seg_name, mode, S_IRUSR | S_IWUSR)
- systemerror("shm_open() failed for " * shm_seg_name, fd_mem < 0)
+ systemerror("shm_open() failed for " ++ shm_seg_name, fd_mem < 0)
s = fdio(fd_mem, true)
@@ -655,7 +655,7 @@ function _shm_mmap_array(T, dims, shm_seg_name, mode)
# and only at creation time
if (mode & JL_O_CREAT) == JL_O_CREAT
rc = ccall(:jl_ftruncate, Cint, (Cint, Int64), fd_mem, prod(dims)*sizeof(T))
- systemerror("ftruncate() failed for shm segment " * shm_seg_name, rc != 0)
+ systemerror("ftruncate() failed for shm segment " ++ shm_seg_name, rc != 0)
end
Mmap.mmap(s, Array{T,length(dims)}, dims, zero(Int64); grow=false)
diff --git a/base/show.jl b/base/show.jl
index b7b1a77032257..f7b2d44efffb3 100644
--- a/base/show.jl
+++ b/base/show.jl
@@ -249,7 +249,7 @@ show_supertypes(typ::DataType) = show_supertypes(STDOUT, typ)
macro show(exs...)
blk = Expr(:block)
for ex in exs
- push!(blk.args, :(print($(sprint(show_unquoted,ex)*" = "))))
+ push!(blk.args, :(print($(sprint(show_unquoted,ex)++" = "))))
push!(blk.args, :(show(STDOUT, "text/plain", begin value=$(esc(ex)) end)))
push!(blk.args, :(println()))
end
@@ -551,10 +551,10 @@ function show_block(io::IO, head, args::Vector, body, indent::Int)
ind = head === :module || head === :baremodule ? indent : indent + indent_width
exs = (is_expr(body, :block) || is_expr(body, :body)) ? body.args : Any[body]
for ex in exs
- print(io, '\n', " "^ind)
+ print(io, '\n', repeat(" ",ind))
show_unquoted(io, ex, ind, -1)
end
- print(io, '\n', " "^indent)
+ print(io, '\n', repeat(" ",indent))
end
show_block(io::IO,head, block,i::Int) = show_block(io,head, [], block,i)
function show_block(io::IO, head, arg, block, i::Int)
diff --git a/base/sparse/cholmod.jl b/base/sparse/cholmod.jl
index 08eec5cdac939..064a6f45579ae 100644
--- a/base/sparse/cholmod.jl
+++ b/base/sparse/cholmod.jl
@@ -240,7 +240,7 @@ mutable struct Sparse{Tv<:VTypes} <: AbstractSparseMatrix{Tv,SuiteSparse_long}
p::Ptr{C_Sparse{Tv}}
function Sparse{Tv}(p::Ptr{C_Sparse{Tv}}) where Tv<:VTypes
if p == C_NULL
- throw(ArgumentError("sparse matrix construction failed for " *
+ throw(ArgumentError("sparse matrix construction failed for " ++
"unknown reasons. Please submit a bug report."))
end
new(p)
@@ -319,7 +319,7 @@ mutable struct Factor{Tv} <: Factorization{Tv}
p::Ptr{C_Factor{Tv}}
function Factor{Tv}(p::Ptr{C_Factor{Tv}}) where Tv
if p == C_NULL
- throw(ArgumentError("factorization construction failed for " *
+ throw(ArgumentError("factorization construction failed for " ++
"unknown reasons. Please submit a bug report."))
end
new(p)
@@ -333,7 +333,7 @@ Factor(p::Ptr{C_Factor{Tv}}) where {Tv<:VTypes} = Factor{Tv}(p)
# when serialized so this can happen when mutiple processes are in use.
function get(p::Ptr{T}) where T<:SuiteSparseStruct
if p == C_NULL
- throw(ArgumentError("pointer to the $T object is null. This can " *
+ throw(ArgumentError("pointer to the $T object is null. This can " ++
"happen if the object has been serialized."))
else
return p
@@ -687,16 +687,16 @@ function scale!(S::Dense{Tv}, scale::Integer, A::Sparse{Tv}) where Tv<:VRealType
if scale == SCALAR && sS.nrow != 1
throw(DimensionMismatch("scaling argument must have length one"))
elseif scale == ROW && sS.nrow*sS.ncol != sA.nrow
- throw(DimensionMismatch("scaling vector has length $(sS.nrow*sS.ncol), " *
+ throw(DimensionMismatch("scaling vector has length $(sS.nrow*sS.ncol), " ++
"but matrix has $(sA.nrow) rows."))
elseif scale == COL && sS.nrow*sS.ncol != sA.ncol
- throw(DimensionMismatch("scaling vector has length $(sS.nrow*sS.ncol), " *
+ throw(DimensionMismatch("scaling vector has length $(sS.nrow*sS.ncol), " ++
"but matrix has $(sA.ncol) columns"))
elseif scale == SYM
if sA.nrow != sA.ncol
throw(DimensionMismatch("matrix must be square"))
elseif sS.nrow*sS.ncol != sA.nrow
- throw(DimensionMismatch("scaling vector has length $(sS.nrow*sS.ncol), " *
+ throw(DimensionMismatch("scaling vector has length $(sS.nrow*sS.ncol), " ++
"but matrix has $(sA.ncol) columns and rows"))
end
end
@@ -786,7 +786,7 @@ end
function solve(sys::Integer, F::Factor{Tv}, B::Dense{Tv}) where Tv<:VTypes
if size(F,1) != size(B,1)
- throw(DimensionMismatch("LHS and RHS should have the same number of rows. " *
+ throw(DimensionMismatch("LHS and RHS should have the same number of rows. " ++
"LHS has $(size(F,1)) rows, but RHS has $(size(B,1)) rows."))
end
d = Dense(ccall((@cholmod_name("solve", SuiteSparse_long),:libcholmod), Ptr{C_Dense{Tv}},
@@ -798,7 +798,7 @@ end
function spsolve(sys::Integer, F::Factor{Tv}, B::Sparse{Tv}) where Tv<:VTypes
if size(F,1) != size(B,1)
- throw(DimensionMismatch("LHS and RHS should have the same number of rows. " *
+ throw(DimensionMismatch("LHS and RHS should have the same number of rows. " ++
"LHS has $(size(F,1)) rows, but RHS has $(size(B,1)) rows."))
end
s = Sparse(ccall((@cholmod_name("spsolve", SuiteSparse_long),:libcholmod),
@@ -970,7 +970,7 @@ end
# Useful when reading in files, but not type stable
function convert(::Type{Sparse}, p::Ptr{C_SparseVoid})
if p == C_NULL
- throw(ArgumentError("sparse matrix construction failed for " *
+ throw(ArgumentError("sparse matrix construction failed for " ++
"unknown reasons. Please submit a bug report."))
end
@@ -979,11 +979,11 @@ function convert(::Type{Sparse}, p::Ptr{C_SparseVoid})
# Check integer type
if s.itype == INT
free_sparse!(p)
- throw(CHOLMODException("the value of itype was $s.itype. " *
+ throw(CHOLMODException("the value of itype was $s.itype. " ++
"Only integer type of $SuiteSparse_long is supported."))
elseif s.itype == INTLONG
free_sparse!(p)
- throw(CHOLMODException("the value of itype was $s.itype. This combination " *
+ throw(CHOLMODException("the value of itype was $s.itype. This combination " ++
"of integer types shouldn't happen. Please submit a bug report."))
elseif s.itype != LONG # must be s.itype == LONG
free_sparse!(p)
@@ -1062,7 +1062,7 @@ convert(::Type{Vector}, D::Dense{T}) where {T} = convert(Vector{T}, D)
function convert(::Type{SparseMatrixCSC{Tv,SuiteSparse_long}}, A::Sparse{Tv}) where Tv
s = unsafe_load(A.p)
if s.stype != 0
- throw(ArgumentError("matrix has stype != 0. Convert to matrix " *
+ throw(ArgumentError("matrix has stype != 0. Convert to matrix " ++
"with stype == 0 before converting to SparseMatrixCSC"))
end
diff --git a/base/sparse/sparsevector.jl b/base/sparse/sparsevector.jl
index 0a540f21d4252..0227b871c0eec 100644
--- a/base/sparse/sparsevector.jl
+++ b/base/sparse/sparsevector.jl
@@ -770,7 +770,7 @@ function show(io::IOContext, x::AbstractSparseVector)
end
k != length(nzind) && println(io)
elseif k == half_screen_rows
- println(io, " ", " "^pad, " \u22ee")
+ println(io, " ", repeat(" ",pad), " \u22ee")
end
end
end
diff --git a/base/sparse/umfpack.jl b/base/sparse/umfpack.jl
index d123ffe04581b..27bd814de9732 100644
--- a/base/sparse/umfpack.jl
+++ b/base/sparse/umfpack.jl
@@ -179,7 +179,7 @@ end
## Wrappers for UMFPACK functions
# generate the name of the C function according to the value and integer types
-umf_nm(nm,Tv,Ti) = "umfpack_" * (Tv == :Float64 ? "d" : "z") * (Ti == :Int64 ? "l_" : "i_") * nm
+umf_nm(nm,Tv,Ti) = "umfpack_" ++ (Tv == :Float64 ? "d" : "z") ++ (Ti == :Int64 ? "l_" : "i_") ++ nm
for itype in UmfpackIndexTypes
sym_r = umf_nm("symbolic", :Float64, itype)
diff --git a/base/strings/basic.jl b/base/strings/basic.jl
index e31b2218de920..53d29a42c35a2 100644
--- a/base/strings/basic.jl
+++ b/base/strings/basic.jl
@@ -55,21 +55,9 @@ sizeof(s::AbstractString) = error("type $(typeof(s)) has no canonical binary rep
eltype(::Type{<:AbstractString}) = Char
-"""
-```
-*(s::AbstractString, t::AbstractString)
-```
-
-Concatenate strings. The `*` operator is an alias to this function.
-
-```jldoctest
-julia> "Hello " * "world"
-"Hello world"
-```
-"""
-(*)(s1::AbstractString, ss::AbstractString...) = string(s1, ss...)
-
-one(::Union{T,Type{T}}) where {T<:AbstractString} = convert(T, "")
+# make ++ concatenate strings [but string++array = vcat(string,array)]
+concat(::Type{String}, X...) = string(X...)
+concat_rule(::Type{<:AbstractString}, T) = (@_inline_meta; String)
length(s::DirectIndexString) = endof(s)
diff --git a/base/strings/types.jl b/base/strings/types.jl
index 587af56c4015d..b44a97d31585e 100644
--- a/base/strings/types.jl
+++ b/base/strings/types.jl
@@ -133,25 +133,22 @@ reverseind(s::RevString, i::Integer) = endof(s) - i + 1
reverseind(s::SubString{String}, i::Integer) =
reverseind(s.string, nextind(s.string, endof(s.string))-s.offset-s.endof+i-1) - s.offset
-function repeat(s::AbstractString, r::Integer)
- r < 0 ? throw(ArgumentError("can't repeat a string $r times")) :
- r == 0 ? "" :
- r == 1 ? s :
- repeat(convert(String, s), r)
-end
-
"""
- ^(s::AbstractString, n::Integer)
+ repeat(s::AbstractString, n::Integer)
-Repeat `n` times the string `s`.
-The [`repeat`](@ref) function is an alias to this operator.
+Construct a new string from `s` by repeating it `n` times.
```jldoctest
-julia> "Test "^3
+julia> repeat("Test ",3)
"Test Test Test "
```
"""
-(^)(s::AbstractString, r::Integer) = repeat(s,r)
+function repeat(s::AbstractString, r::Integer)
+ r < 0 ? throw(ArgumentError("can't repeat a string $r times")) :
+ r == 0 ? "" :
+ r == 1 ? s :
+ repeat(convert(String, s), r)
+end
pointer(x::SubString{String}) = pointer(x.string) + x.offset
pointer(x::SubString{String}, i::Integer) = pointer(x.string) + x.offset + (i-1)
diff --git a/base/strings/util.jl b/base/strings/util.jl
index c4c4459545128..5a8cbffdbed9e 100644
--- a/base/strings/util.jl
+++ b/base/strings/util.jl
@@ -200,12 +200,12 @@ function lpad(s::AbstractString, n::Integer, p::AbstractString=" ")
(m <= 0) && (return s)
l = strwidth(p)
if l==1
- return string(p^m, s)
+ return string(repeat(p,m), s)
end
q = div(m,l)
r = m - q*l
i = r != 0 ? chr2ind(p, r) : -1
- string(p^q, p[1:i], s)
+ string(repeat(p,q), p[1:i], s)
end
function rpad(s::AbstractString, n::Integer, p::AbstractString=" ")
@@ -213,12 +213,12 @@ function rpad(s::AbstractString, n::Integer, p::AbstractString=" ")
(m <= 0) && (return s)
l = strwidth(p)
if l==1
- return string(s, p^m)
+ return string(s, repeat(p,m))
end
q = div(m,l)
r = m - q*l
i = r != 0 ? chr2ind(p, r) : -1
- string(s, p^q, p[1:i])
+ string(s, repeat(p,q), p[1:i])
end
"""
diff --git a/base/test.jl b/base/test.jl
index c841552bb9a88..88d6cd06c8846 100644
--- a/base/test.jl
+++ b/base/test.jl
@@ -754,7 +754,7 @@ function print_counts(ts::DefaultTestSet, depth, align,
subtotal = passes + fails + errors + broken + c_passes + c_fails + c_errors + c_broken
# Print test set header, with an alignment that ensures all
# the test results appear above each other
- print(rpad(string(" "^depth, ts.description), align, " "), " | ")
+ print(rpad(string(repeat(" ",depth), ts.description), align, " "), " | ")
np = passes + c_passes
if np > 0
diff --git a/base/version.jl b/base/version.jl
index 08938b3f48af9..4043db978427c 100644
--- a/base/version.jl
+++ b/base/version.jl
@@ -250,10 +250,10 @@ function banner(io::IO = STDOUT)
c = text_colors
tx = c[:normal] # text
jl = c[:normal] # julia
- d1 = c[:bold] * c[:blue] # first dot
- d2 = c[:bold] * c[:red] # second dot
- d3 = c[:bold] * c[:green] # third dot
- d4 = c[:bold] * c[:magenta] # fourth dot
+ d1 = c[:bold] ++ c[:blue] # first dot
+ d2 = c[:bold] ++ c[:red] # second dot
+ d3 = c[:bold] ++ c[:green] # third dot
+ d4 = c[:bold] ++ c[:magenta] # fourth dot
print(io,""" $(d3)_$(tx)
$(d1)_$(tx) $(jl)_$(tx) $(d2)_$(d3)(_)$(d4)_$(tx) | A fresh approach to technical computing
diff --git a/contrib/julia-config.jl b/contrib/julia-config.jl
index 2a177240d536f..9034f81b9432e 100755
--- a/contrib/julia-config.jl
+++ b/contrib/julia-config.jl
@@ -36,9 +36,9 @@ end
function ldflags()
fl = "-L$(shell_escape(libDir()))"
if is_windows()
- fl = fl * " -Wl,--stack,8388608"
+ fl = fl ++ " -Wl,--stack,8388608"
elseif is_linux()
- fl = fl * " -Wl,--export-dynamic"
+ fl = fl ++ " -Wl,--export-dynamic"
end
return fl
end
diff --git a/doc/src/manual/strings.md b/doc/src/manual/strings.md
index a1298af12de5b..f64631fddec46 100644
--- a/doc/src/manual/strings.md
+++ b/doc/src/manual/strings.md
@@ -332,29 +332,16 @@ julia> string(greet, ", ", whom, ".\n")
"Hello, world.\n"
```
-Julia also provides `*` for string concatenation:
+Julia also provides `++` for string concatenation:
```jldoctest stringconcat
-julia> greet * ", " * whom * ".\n"
+julia> greet ++ ", " ++ whom ++ ".\n"
"Hello, world.\n"
```
-While `*` may seem like a surprising choice to users of languages that provide `+` for string
-concatenation, this use of `*` has precedent in mathematics, particularly in abstract algebra.
-
-In mathematics, `+` usually denotes a *commutative* operation, where the order of the operands does
-not matter. An example of this is matrix addition, where `A + B == B + A` for any matrices `A` and `B`
-that have the same shape. In contrast, `*` typically denotes a *noncommutative* operation, where the
-order of the operands *does* matter. An example of this is matrix multiplication, where in general
-`A * B != B * A`. As with matrix multiplication, string concatenation is noncommutative:
-`greet * whom != whom * greet`. As such, `*` is a more natural choice for an infix string concatenation
-operator, consistent with common mathematical use.
-
-More precisely, the set of all finite-length strings *S* together with the string concatenation operator
-`*` forms a [free monoid](https://en.wikipedia.org/wiki/Free_monoid) (*S*, `*`). The identity element
-of this set is the empty string, `""`. Whenever a free monoid is not commutative, the operation is
-typically represented as `\cdot`, `*`, or a similar symbol, rather than `+`, which as stated usually
-implies commutativity.
+More generally, `++` is a *concatenation* operator that can concatenate
+strings, arrays and elements thereof (for which it calls [`vcat`](@ref)),
+and other types.
## [Interpolation](@id string-interpolation)
diff --git a/examples/typetree.jl b/examples/typetree.jl
index 1ca8714833291..f1e7a192be825 100644
--- a/examples/typetree.jl
+++ b/examples/typetree.jl
@@ -134,7 +134,7 @@ function print_tree(subtypes::Dict{Binding, TTNode}, pfx::String="")
println(pfx, "+- ", n, " = ", v.typ, " ", type_props(v.typ))
end
v.typ === Function && println(pfx, ". ## hiding implicit Function subtypes ##")
- print_tree(v.subtypes, pfx * ". ")
+ print_tree(v.subtypes, pfx ++ ". ")
end
end
diff --git a/src/julia-parser.scm b/src/julia-parser.scm
index e15e23d7fb016..6a18a2bb616b7 100644
--- a/src/julia-parser.scm
+++ b/src/julia-parser.scm
@@ -19,9 +19,10 @@
(append! '(|<:| |>:| in isa)
(add-dots '(> < >= ≥ <= ≤ == === ≡ != ≠ !== ≢ ∈ ∉ ∋ ∌ ⊆ ⊈ ⊂ ⊄ ⊊ ∝ ∊ ∍ ∥ ∦ ∷ ∺ ∻ ∽ ∾ ≁ ≃ ≄ ≅ ≆ ≇ ≈ ≉ ≊ ≋ ≌ ≍ ≎ ≐ ≑ ≒ ≓ ≔ ≕ ≖ ≗ ≘ ≙ ≚ ≛ ≜ ≝ ≞ ≟ ≣ ≦ ≧ ≨ ≩ ≪ ≫ ≬ ≭ ≮ ≯ ≰ ≱ ≲ ≳ ≴ ≵ ≶ ≷ ≸ ≹ ≺ ≻ ≼ ≽ ≾ ≿ ⊀ ⊁ ⊃ ⊅ ⊇ ⊉ ⊋ ⊏ ⊐ ⊑ ⊒ ⊜ ⊩ ⊬ ⊮ ⊰ ⊱ ⊲ ⊳ ⊴ ⊵ ⊶ ⊷ ⋍ ⋐ ⋑ ⋕ ⋖ ⋗ ⋘ ⋙ ⋚ ⋛ ⋜ ⋝ ⋞ ⋟ ⋠ ⋡ ⋢ ⋣ ⋤ ⋥ ⋦ ⋧ ⋨ ⋩ ⋪ ⋫ ⋬ ⋭ ⋲ ⋳ ⋴ ⋵ ⋶ ⋷ ⋸ ⋹ ⋺ ⋻ ⋼ ⋽ ⋾ ⋿ ⟈ ⟉ ⟒ ⦷ ⧀ ⧁ ⧡ ⧣ ⧤ ⧥ ⩦ ⩧ ⩪ ⩫ ⩬ ⩭ ⩮ ⩯ ⩰ ⩱ ⩲ ⩳ ⩴ ⩵ ⩶ ⩷ ⩸ ⩹ ⩺ ⩻ ⩼ ⩽ ⩾ ⩿ ⪀ ⪁ ⪂ ⪃ ⪄ ⪅ ⪆ ⪇ ⪈ ⪉ ⪊ ⪋ ⪌ ⪍ ⪎ ⪏ ⪐ ⪑ ⪒ ⪓ ⪔ ⪕ ⪖ ⪗ ⪘ ⪙ ⪚ ⪛ ⪜ ⪝ ⪞ ⪟ ⪠ ⪡ ⪢ ⪣ ⪤ ⪥ ⪦ ⪧ ⪨ ⪩ ⪪ ⪫ ⪬ ⪭ ⪮ ⪯ ⪰ ⪱ ⪲ ⪳ ⪴ ⪵ ⪶ ⪷ ⪸ ⪹ ⪺ ⪻ ⪼ ⪽ ⪾ ⪿ ⫀ ⫁ ⫂ ⫃ ⫄ ⫅ ⫆ ⫇ ⫈ ⫉ ⫊ ⫋ ⫌ ⫍ ⫎ ⫏ ⫐ ⫑ ⫒ ⫓ ⫔ ⫕ ⫖ ⫗ ⫘ ⫙ ⫷ ⫸ ⫹ ⫺ ⊢ ⊣))))
(define prec-pipe (add-dots '(|\|>| |<\||)))
+(define prec-concat (add-dots '(|++|)))
(define prec-colon '(: |..|))
(define prec-plus (append! '($)
- (add-dots '(+ - |\|| ⊕ ⊖ ⊞ ⊟ |++| ∪ ∨ ⊔ ± ∓ ∔ ∸ ≂ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⧺ ⧻ ⨈ ⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣))))
+ (add-dots '(+ - |\|| ⊕ ⊖ ⊞ ⊟ ∪ ∨ ⊔ ± ∓ ∔ ∸ ≂ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⧺ ⧻ ⨈ ⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣))))
(define prec-bitshift (add-dots '(<< >> >>>)))
(define prec-times (add-dots '(* / ÷ % & ⋅ ∘ × |\\| ∩ ∧ ⊗ ⊘ ⊙ ⊚ ⊛ ⊠ ⊡ ⊓ ∗ ∙ ∤ ⅋ ≀ ⊼ ⋄ ⋆ ⋇ ⋉ ⋊ ⋋ ⋌ ⋏ ⋒ ⟑ ⦸ ⦼ ⦾ ⦿ ⧶ ⧷ ⨇ ⨰ ⨱ ⨲ ⨳ ⨴ ⨵ ⨶ ⨷ ⨸ ⨻ ⨼ ⨽ ⩀ ⩃ ⩄ ⩋ ⩍ ⩎ ⩑ ⩓ ⩕ ⩘ ⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗)))
(define prec-rational (add-dots '(//)))
@@ -34,7 +35,7 @@
(define prec-names '(prec-assignment
prec-conditional prec-lazy-or prec-lazy-and prec-arrow prec-comparison
- prec-pipe prec-colon prec-plus prec-bitshift prec-times prec-rational
+ prec-pipe prec-concat prec-colon prec-plus prec-bitshift prec-times prec-rational
prec-power prec-decl prec-dot))
(define (Set l)
@@ -759,7 +760,8 @@
`(call ,op ,arg1 ,arg2))))
(else ex)))))
-(define (parse-pipes s) (parse-LtoR s parse-range is-prec-pipe?))
+(define (parse-pipes s) (parse-LtoR s parse-concat is-prec-pipe?))
+(define (parse-concat s) (parse-with-chains s parse-range is-prec-concat? '++))
; parse ranges and postfix ...
; colon is strange; 3 arguments with 2 colons yields one call:
@@ -828,7 +830,7 @@
;; parse left to right, combining chains of a certain operator into 1 call
;; e.g. a+b+c => (call + a b c)
-(define (parse-with-chains s down ops chain-ops)
+(define (parse-with-chains s down ops chain-op)
(let loop ((ex (down s)))
(let ((t (peek-token s)))
(if (not (ops t))
@@ -840,15 +842,15 @@
;; here we have "x -y"
(ts:put-back! s t)
ex)
- ((memq t chain-ops)
+ ((eq? t chain-op)
(loop (list* 'call t ex
(parse-chain s down t))))
(else
(loop (list 'call t ex (down s))))))))))
-(define (parse-expr s) (parse-with-chains s parse-shift is-prec-plus? '(+ ++)))
+(define (parse-expr s) (parse-with-chains s parse-shift is-prec-plus? '+))
(define (parse-shift s) (parse-LtoR s parse-term is-prec-bitshift?))
-(define (parse-term s) (parse-with-chains s parse-rational is-prec-times? '(*)))
+(define (parse-term s) (parse-with-chains s parse-rational is-prec-times? '*))
(define (parse-rational s) (parse-LtoR s parse-unary-subtype is-prec-rational?))
;; parse `<: A where B` as `<: (A where B)` (issue #21545)
diff --git a/test/channels.jl b/test/channels.jl
index 7f5d206f99e70..4e21ab0554e61 100644
--- a/test/channels.jl
+++ b/test/channels.jl
@@ -220,7 +220,7 @@ end
# test for yield/wait/event failures
-@noinline garbage_finalizer(f) = finalizer("gar" * "bage", f)
+@noinline garbage_finalizer(f) = finalizer("gar" ++ "bage", f)
let t, run = Ref(0)
gc_enable(false)
# test for finalizers trying to yield leading to failed attempts to context switch
diff --git a/test/choosetests.jl b/test/choosetests.jl
index b44474f0b2751..48ac08670e1d4 100644
--- a/test/choosetests.jl
+++ b/test/choosetests.jl
@@ -153,7 +153,7 @@ function choosetests(choices = [])
try
ipa = getipaddr()
catch
- warn("Networking unavailable: Skipping tests [" * join(net_required_for, ", ") * "]")
+ warn("Networking unavailable: Skipping tests [" ++ join(net_required_for, ", ") ++ "]")
net_on = false
end
diff --git a/test/dates/io.jl b/test/dates/io.jl
index 4a34d87859637..3e1c214d73901 100644
--- a/test/dates/io.jl
+++ b/test/dates/io.jl
@@ -144,15 +144,15 @@ f2 = "1996 1 1"
j = "1996-01-15"
f = "yyyy-mm-dd zzz"
@test Dates.DateTime(j, f) == dt
-@test Dates.format(dt, f) == j * " zzz"
+@test Dates.format(dt, f) == j ++ " zzz"
k = "1996-01-15 10:00:00"
f = "yyyy-mm-dd HH:MM:SS zzz"
@test Dates.DateTime(k, f) == dt + Dates.Hour(10)
-@test Dates.format(dt + Dates.Hour(10), f) == k * " zzz"
+@test Dates.format(dt + Dates.Hour(10), f) == k ++ " zzz"
l = "1996-01-15 10:10:10.25"
f = "yyyy-mm-dd HH:MM:SS.ss zzz"
@test Dates.DateTime(l, f) == dt + Dates.Hour(10) + Dates.Minute(10) + Dates.Second(10) + Dates.Millisecond(250)
-@test Dates.format(dt + Dates.Hour(10) + Dates.Minute(10) + Dates.Second(10) + Dates.Millisecond(250), f) == l * " zzz"
+@test Dates.format(dt + Dates.Hour(10) + Dates.Minute(10) + Dates.Second(10) + Dates.Millisecond(250), f) == l ++ " zzz"
r = "1/15/1996" # Excel
f = "m/dd/yyyy"
@@ -169,7 +169,7 @@ f = "yyyy-mm-dd HH:MM:SS"
w = "1996-01-15T10:00:00"
f = "yyyy-mm-ddTHH:MM:SS zzz"
@test Dates.DateTime(w, f) == dt + Dates.Hour(10)
-@test Dates.format(dt + Dates.Hour(10), f) == w * " zzz"
+@test Dates.format(dt + Dates.Hour(10), f) == w ++ " zzz"
f = "yyyy/m"
y = "1996/1"
@@ -443,7 +443,7 @@ end
@test_throws InexactError Dates.parse_components(".1234", Dates.DateFormat(".s"))
# Ensure that no overflow occurs when using Int32 literals: Int32(10)^10
- @test Dates.parse_components("." * rpad(999, 10, '0'), Dates.DateFormat(".s")) == [Dates.Millisecond(999)]
+ @test Dates.parse_components("." ++ rpad(999, 10, '0'), Dates.DateFormat(".s")) == [Dates.Millisecond(999)]
end
# Time Parsing
diff --git a/test/dates/periods.jl b/test/dates/periods.jl
index f8c068e39e032..307fa2fe4ebfb 100644
--- a/test/dates/periods.jl
+++ b/test/dates/periods.jl
@@ -247,7 +247,7 @@ let
Dates.value(b::Beat) = b.value
Dates.toms(b::Beat) = Dates.value(b) * 86400
- Dates._units(b::Beat) = " beat" * (abs(Dates.value(b)) == 1 ? "" : "s")
+ Dates._units(b::Beat) = " beat" ++ (abs(Dates.value(b)) == 1 ? "" : "s")
Base.promote_rule(::Type{Dates.Day}, ::Type{Beat}) = Dates.Millisecond
Base.convert{T<:Dates.Millisecond}(::Type{T}, b::Beat) = T(Dates.toms(b))
diff --git a/test/distributed_exec.jl b/test/distributed_exec.jl
index 402948cf96ec4..a6a21d447e3db 100644
--- a/test/distributed_exec.jl
+++ b/test/distributed_exec.jl
@@ -273,11 +273,11 @@ dims = (20,20,20)
if is_linux()
S = SharedArray{Int64,3}(dims)
@test startswith(S.segname, "/jl")
- @test !ispath("/dev/shm" * S.segname)
+ @test !ispath("/dev/shm" ++ S.segname)
S = SharedArray{Int64,3}(dims; pids=[id_other])
@test startswith(S.segname, "/jl")
- @test !ispath("/dev/shm" * S.segname)
+ @test !ispath("/dev/shm" ++ S.segname)
end
# TODO : Need a similar test of shmem cleanup for OSX
diff --git a/test/libgit2.jl b/test/libgit2.jl
index 8d0065e0b54ff..1c876be2db4c1 100644
--- a/test/libgit2.jl
+++ b/test/libgit2.jl
@@ -1479,7 +1479,7 @@ mktempdir() do dir
#=
# Explicitly setting these env variables to an existing but invalid key pair
# means the user will be given a prompt with that defaults to the given values.
- withenv("SSH_KEY_PATH" => invalid_key, "SSH_PUB_KEY_PATH" => invalid_key * ".pub") do
+ withenv("SSH_KEY_PATH" => invalid_key, "SSH_PUB_KEY_PATH" => invalid_key ++ ".pub") do
challenges = [
"Private key location for 'git@github.com' [$invalid_key]:" => "$valid_key\n",
]
@@ -1492,7 +1492,7 @@ mktempdir() do dir
# TODO: Tests are currently broken. Credential callback currently infinite loops
# and never prompts user to change private keys.
#=
- withenv("SSH_KEY_PATH" => valid_key, "SSH_PUB_KEY_PATH" => valid_key * ".public") do
+ withenv("SSH_KEY_PATH" => valid_key, "SSH_PUB_KEY_PATH" => valid_key ++ ".public") do
@test !isfile(ENV["SSH_PUB_KEY_PATH"])
# User explicitly sets the SSH_PUB_KEY_PATH incorrectly.
@@ -1762,9 +1762,9 @@ mktempdir() do dir
end
if openssl_installed && !isempty(common_name)
mktempdir() do root
- key = joinpath(root, common_name * ".key")
- cert = joinpath(root, common_name * ".crt")
- pem = joinpath(root, common_name * ".pem")
+ key = joinpath(root, common_name ++ ".key")
+ cert = joinpath(root, common_name ++ ".crt")
+ pem = joinpath(root, common_name ++ ".pem")
# Generated a certificate which has the CN set correctly but no subjectAltName
run(pipeline(`openssl req -new -x509 -newkey rsa:2048 -nodes -keyout $key -out $cert -days 1 -subj "/CN=$common_name"`, stderr=DevNull))
diff --git a/test/numbers.jl b/test/numbers.jl
index 8c1d4307a37f1..fb60b798bc01c 100644
--- a/test/numbers.jl
+++ b/test/numbers.jl
@@ -308,8 +308,8 @@ end
@test base(12,typemin(UInt128)) == "0"
@test base(12,typemax(UInt128)) == "5916b64b41143526a777873841863a6a6993"
-@test bin(typemin(Int8)) == "-1"*"0"^7
-@test bin(typemax(Int8)) == "1"^7
+@test bin(typemin(Int8)) == "-1"++repeat("0",7)
+@test bin(typemax(Int8)) == repeat("1",7)
@test oct(typemin(Int8)) == "-200"
@test oct(typemax(Int8)) == "177"
@test dec(typemin(Int8)) == "-128"
@@ -323,8 +323,8 @@ end
@test base(12,typemin(Int8)) == "-a8"
@test base(12,typemax(Int8)) == "a7"
-@test bin(typemin(Int16)) == "-1"*"0"^15
-@test bin(typemax(Int16)) == "1"^15
+@test bin(typemin(Int16)) == "-1"++repeat("0",15)
+@test bin(typemax(Int16)) == repeat("1",15)
@test oct(typemin(Int16)) == "-100000"
@test oct(typemax(Int16)) == "77777"
@test dec(typemin(Int16)) == "-32768"
@@ -338,7 +338,7 @@ end
@test base(12,typemin(Int16)) == "-16b68"
@test base(12,typemax(Int16)) == "16b67"
-@test bin(typemin(Int32)) == "-1"*"0"^31
+@test bin(typemin(Int32)) == "-1"++repeat("0",31)
@test bin(typemax(Int32)) == "1"^31
@test oct(typemin(Int32)) == "-20000000000"
@test oct(typemax(Int32)) == "17777777777"
@@ -353,8 +353,8 @@ end
@test base(12,typemin(Int32)) == "-4bb2308a8"
@test base(12,typemax(Int32)) == "4bb2308a7"
-@test bin(typemin(Int64)) == "-1"*"0"^63
-@test bin(typemax(Int64)) == "1"^63
+@test bin(typemin(Int64)) == "-1"++repeat("0",63)
+@test bin(typemax(Int64)) == repeat("1",63)
@test oct(typemin(Int64)) == "-1000000000000000000000"
@test oct(typemax(Int64)) == "777777777777777777777"
@test dec(typemin(Int64)) == "-9223372036854775808"
@@ -368,8 +368,8 @@ end
@test base(12,typemin(Int64)) == "-41a792678515120368"
@test base(12,typemax(Int64)) == "41a792678515120367"
-@test bin(typemin(Int128)) == "-1"*"0"^127
-@test bin(typemax(Int128)) == "1"^127
+@test bin(typemin(Int128)) == "-1"++repeat("0",127)
+@test bin(typemax(Int128)) == repeat("1",127)
@test oct(typemin(Int128)) == "-2000000000000000000000000000000000000000000"
@test oct(typemax(Int128)) == "1777777777777777777777777777777777777777777"
@test hex(typemin(Int128)) == "-80000000000000000000000000000000"
diff --git a/test/pkg.jl b/test/pkg.jl
index abd04ea9d59f7..661aa1b4a8940 100644
--- a/test/pkg.jl
+++ b/test/pkg.jl
@@ -202,8 +202,8 @@ temp_pkg_dir() do
error("unexpected")
catch err
@test isa(err.exceptions[1].ex, PkgError)
- @test err.exceptions[1].ex.msg == "REPL can't be installed because " *
- "it has no versions that support $VERSION of julia. You may " *
+ @test err.exceptions[1].ex.msg == "REPL can't be installed because " ++
+ "it has no versions that support $VERSION of julia. You may " ++
"need to update METADATA by running `Pkg.update()`"
end
diff --git a/test/replcompletions.jl b/test/replcompletions.jl
index 6e0d9a38ebda3..96fbf77ac6fd3 100644
--- a/test/replcompletions.jl
+++ b/test/replcompletions.jl
@@ -616,7 +616,7 @@ end
let #test that it can auto complete with spaces in file/path
path = tempdir()
- space_folder = randstring() * " α"
+ space_folder = randstring() ++ " α"
dir = joinpath(path, space_folder)
dir_space = replace(space_folder, " ", "\\ ")
mkdir(dir)
@@ -654,7 +654,7 @@ if is_windows()
s = "cd ..\\\\"
c,r = test_scomplete(s)
@test r == length(s)+1:length(s)
- @test temp_name * "\\\\" in c
+ @test temp_name ++ "\\\\" in c
s = "ls $(file[1:2])"
c,r = test_scomplete(s)
@@ -664,7 +664,7 @@ if is_windows()
s = "cd(\"..\\"
c,r = test_complete(s)
@test r == length(s)+1:length(s)
- @test temp_name * "\\\\" in c
+ @test temp_name ++ "\\\\" in c
s = "cd(\"$(file[1:2])"
c,r = test_complete(s)
diff --git a/test/runtests.jl b/test/runtests.jl
index 262ca6a46ecca..2edf9004088fa 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -70,7 +70,7 @@ cd(dirname(@__FILE__)) do
end
end
if !isa(resp[1], Exception)
- print_with_color(:white, rpad(test*" ($wrkr)", name_align, " "), " | ")
+ print_with_color(:white, rpad(test++" ($wrkr)", name_align, " "), " | ")
time_str = @sprintf("%7.2f",resp[2])
print_with_color(:white, rpad(time_str,elapsed_align," "), " | ")
gc_str = @sprintf("%5.2f",resp[5].total_time/10^9)
diff --git a/test/show.jl b/test/show.jl
index 2c205c478a7a3..5e58a55812ebd 100644
--- a/test/show.jl
+++ b/test/show.jl
@@ -289,7 +289,7 @@ end"
# issue #9474
for s in ("(1::Int64 == 1::Int64)::Bool", "(1:2:3) + 4", "x = 1:2:3")
- @test sprint(show, parse(s)) == ":("*s*")"
+ @test sprint(show, parse(s)) == ":("++s++")"
end
# parametric type instantiation printing
@@ -778,4 +778,4 @@ let fname = tempname()
finally
rm(fname, force=true)
end
-end
\ No newline at end of file
+end
diff --git a/test/socket.jl b/test/socket.jl
index 917d3c240a13c..1e6c8464133c0 100644
--- a/test/socket.jl
+++ b/test/socket.jl
@@ -89,12 +89,12 @@ for testport in [0, defaultport]
close(sock)
end
wait(port)
- @test readstring(connect(fetch(port))) == "Hello World\n" * ("a1\n"^100)
+ @test readstring(connect(fetch(port))) == "Hello World\n" ++ repeat("a1\n",100)
wait(tsk)
end
mktempdir() do tmpdir
- socketname = is_windows() ? ("\\\\.\\pipe\\uv-test-" * randstring(6)) : joinpath(tmpdir, "socket")
+ socketname = is_windows() ? ("\\\\.\\pipe\\uv-test-" ++ randstring(6)) : joinpath(tmpdir, "socket")
c = Base.Condition()
tsk = @async begin
s = listen(socketname)
@@ -329,4 +329,3 @@ let
@test test_connect(addr)
end
-
diff --git a/test/strings/basic.jl b/test/strings/basic.jl
index bf1fb7741c862..69dfc8648e8bd 100644
--- a/test/strings/basic.jl
+++ b/test/strings/basic.jl
@@ -409,13 +409,9 @@ foobaz(ch) = reinterpret(Char, typemax(UInt32))
@test map(foobar, GenericString(str)) == String(repeat(b"\ud800", outer=[17]))
@test map(foobaz, GenericString(str)) == String(repeat(b"\ufffd", outer=[17]))
-@test "a".*["b","c"] == ["ab","ac"]
-@test ["b","c"].*"a" == ["ba","ca"]
-@test ["a","b"].*["c" "d"] == ["ac" "ad"; "bc" "bd"]
-
-@test one(String) == ""
-@test prod(["*" for i in 1:3]) == "***"
-@test prod(["*" for i in 1:0]) == ""
+@test "a".++["b","c"] == ["ab","ac"]
+@test ["b","c"].++"a" == ["ba","ca"]
+@test ["a","b"].++["c" "d"] == ["ac" "ad"; "bc" "bd"]
# Make sure NULL pointers are handled consistently by String
@test_throws ArgumentError unsafe_string(Ptr{UInt8}(0))
diff --git a/test/strings/types.jl b/test/strings/types.jl
index c4ff5227a02e2..4d869796c9dda 100644
--- a/test/strings/types.jl
+++ b/test/strings/types.jl
@@ -4,7 +4,7 @@
## SubString tests ##
u8str = "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
-u8str2 = u8str^2
+u8str2 = repeat(u8str,2)
len_u8str = length(u8str)
slen_u8str = length(u8str)
len_u8str2 = length(u8str2)
diff --git a/test/unicode/utf8proc.jl b/test/unicode/utf8proc.jl
index 403c2775f9897..b88335ca34af0 100644
--- a/test/unicode/utf8proc.jl
+++ b/test/unicode/utf8proc.jl
@@ -6,8 +6,8 @@
@test "\u006e\u0303" == normalize_string("\u00f1", :NFD)
@test normalize_string("\ufb00", :NFC) != "ff"
@test normalize_string("\ufb00", :NFKC) == "ff"
- @test normalize_string("\u006e\u0303\ufb00", :NFKC) == "\u00f1"*"ff"
- @test normalize_string("\u00f1\ufb00", :NFKD) == "\u006e\u0303"*"ff"
+ @test normalize_string("\u006e\u0303\ufb00", :NFKC) == "\u00f1"++"ff"
+ @test normalize_string("\u00f1\ufb00", :NFKD) == "\u006e\u0303"++"ff"
@test normalize_string("\u006e\u0303", compose=true) == "\u00f1"
@test "\u006e\u0303" == normalize_string("\u00f1", decompose=true)
@test normalize_string("\u006e\u0303\u00b5",compat=true) == "\u00f1\u03bc"