Skip to content

Commit

Permalink
treat String as immutable in ===. part of #22193
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Jul 25, 2017
1 parent 9186ae4 commit 6a3a308
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ JL_DLLEXPORT int jl_egal(jl_value_t *a, jl_value_t *b)
jl_datatype_t *dtb = (jl_datatype_t*)b;
return dta->name == dtb->name && compare_svec(dta->parameters, dtb->parameters);
}
if (dt == jl_string_type) {
size_t l = jl_string_len(a);
if (jl_string_len(b) != l)
return 0;
return !memcmp(jl_string_data(a), jl_string_data(b), l);
}
if (dt->mutabl) return 0;
size_t sz = jl_datatype_size(dt);
if (sz == 0) return 1;
Expand Down Expand Up @@ -186,6 +192,13 @@ static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v)
#else
if (v == jl_ANY_flag) return 0x8ee30bdd;
#endif
if (dt == jl_string_type) {
#ifdef _P64
return memhash_seed(jl_string_data(v), jl_string_len(v), 0xedc3b677);
#else
return memhash32_seed(jl_string_data(v), jl_string_len(v), 0xedc3b677);
#endif
}
if (dt->mutabl) return inthash((uintptr_t)v);
size_t sz = jl_datatype_size(tv);
uintptr_t h = jl_object_id(tv);
Expand Down
3 changes: 2 additions & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2349,7 +2349,8 @@ static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgva
if ((jl_is_type_type(rt1) && jl_is_leaf_type(jl_tparam0(rt1))) ||
(jl_is_type_type(rt2) && jl_is_leaf_type(jl_tparam0(rt2)))) // can compare leaf types by pointer
ptr_comparable = 1;
if (rt1 == (jl_value_t*)jl_simplevector_type && rt2 == (jl_value_t*)jl_simplevector_type)
if ((rt1 == (jl_value_t*)jl_string_type && rt2 == (jl_value_t*)jl_string_type) ||
(rt1 == (jl_value_t*)jl_simplevector_type && rt2 == (jl_value_t*)jl_simplevector_type))
ptr_comparable = 0; // technically mutable, but compared by contents
if (ptr_comparable) {
Value *varg1 = arg1.constant ? literal_pointer_val(ctx, arg1.constant) : arg1.V;
Expand Down
2 changes: 1 addition & 1 deletion test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ let d = ImmutableDict{String, String}(),
@test (k1 => v2) in d3
@test (k1 => v1) in d4
@test (k1 => v2) in d4
@test !in(k2 => "value2", d4, ===)
@test in(k2 => "value2", d4, ===)
@test in(k2 => v2, d4, ===)
@test in(k2 => NaN, dnan, isequal)
@test in(k2 => NaN, dnan, ===)
Expand Down
10 changes: 10 additions & 0 deletions test/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@
@test eltype(GenericString) == Char
@test start("abc") == 1
@test cmp("ab","abc") == -1
@test "abc" === "abc"
@test "ab" !== "abc"
@test string("ab", 'c') === "abc"
codegen_egal_of_strings(x, y) = (x===y, x!==y)
@test codegen_egal_of_strings(string("ab", 'c'), "abc") === (true, false)
let strs = ["", "a", "a b c", "до свидания"]
for x in strs, y in strs
@test (x === y) == (object_id(x) == object_id(y))
end
end

# {starts,ends}with
@test startswith("abcd", 'a')
Expand Down

0 comments on commit 6a3a308

Please sign in to comment.