diff options
author | Étienne Barrié <[email protected]> | 2023-12-01 11:33:00 +0100 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2024-03-19 09:26:49 +0100 |
commit | 12be40ae6be78ac41e8e3f3c313cc6f63e7fa6c4 () | |
tree | f6b81fac770da6b705557623224dbf9b9c2d2847 /include/ruby | |
parent | 86b15316a748a579dd4fd4df42b6db42accebdc2 (diff) |
Implement chilled strings
[Feature #20205] As a path toward enabling frozen string literals by default in the future, this commit introduce "chilled strings". From a user perspective chilled strings pretend to be frozen, but on the first attempt to mutate them, they lose their frozen status and emit a warning rather than to raise a `FrozenError`. Implementation wise, `rb_compile_option_struct.frozen_string_literal` is no longer a boolean but a tri-state of `enabled/disabled/unset`. When code is compiled with frozen string literals neither explictly enabled or disabled, string literals are compiled with a new `putchilledstring` instruction. This instruction is identical to `putstring` except it marks the String with the `STR_CHILLED (FL_USER3)` and `FL_FREEZE` flags. Chilled strings have the `FL_FREEZE` flag as to minimize the need to check for chilled strings across the codebase, and to improve compatibility with C extensions. Notes: - `String#freeze`: clears the chilled flag. - `String#-@`: acts as if the string was mutable. - `String#+@`: acts as if the string was mutable. - `String#clone`: copies the chilled flag. Co-authored-by: Jean Boussier <[email protected]>
-rw-r--r-- | include/ruby/internal/fl_type.h | 3 | ||||
-rw-r--r-- | include/ruby/internal/intern/error.h | 1 |
2 files changed, 3 insertions, 1 deletions
@@ -916,6 +916,9 @@ static inline void RB_OBJ_FREEZE_RAW(VALUE obj) { RB_FL_SET_RAW(obj, RUBY_FL_FREEZE); } RUBY_SYMBOL_EXPORT_BEGIN @@ -190,7 +190,6 @@ RBIMPL_ATTR_NONNULL(()) */ void rb_error_frozen(const char *what); -RBIMPL_ATTR_NORETURN() /** * Identical to rb_error_frozen(), except it takes arbitrary Ruby object * instead of C's string. |