summaryrefslogtreecommitdiff
path: root/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'error.c')
-rw-r--r--error.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/error.c b/error.c
index d266f8fd9b..b6ed5d22d1 100644
--- a/error.c
+++ b/error.c
@@ -3973,13 +3973,25 @@ inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
return mesg;
}
+static VALUE
+get_created_info(VALUE obj, int *pline)
+{
+ VALUE info = rb_attr_get(obj, id_debug_created_info);
+
+ if (NIL_P(info)) return Qnil;
+
+ VALUE path = rb_ary_entry(info, 0);
+ VALUE line = rb_ary_entry(info, 1);
+ if (NIL_P(path)) return Qnil;
+ *pline = NUM2INT(line);
+ return StringValue(path);
+}
+
void
rb_error_frozen_object(VALUE frozen_obj)
{
rb_yjit_lazy_push_frame(GET_EC()->cfp->pc);
- VALUE debug_info;
- const ID created_info = id_debug_created_info;
VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
CLASS_OF(frozen_obj));
VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
@@ -3987,15 +3999,46 @@ rb_error_frozen_object(VALUE frozen_obj)
rb_ivar_set(exc, id_recv, frozen_obj);
rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
- if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
- VALUE path = rb_ary_entry(debug_info, 0);
- VALUE line = rb_ary_entry(debug_info, 1);
-
- rb_str_catf(mesg, ", created at %"PRIsVALUE":%"PRIsVALUE, path, line);
+ int created_line;
+ VALUE created_path = get_created_info(frozen_obj, &created_line);
+ if (!NIL_P(created_path)) {
+ rb_str_catf(mesg, ", created at %"PRIsVALUE":%d", created_path, created_line);
}
rb_exc_raise(exc);
}
+void
+rb_warn_unchilled(VALUE obj)
+{
+ rb_warning_category_t category = RB_WARN_CATEGORY_DEPRECATED;
+ if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
+ int line;
+ VALUE file = rb_source_location(&line);
+ VALUE mesg = NIL_P(file) ? rb_str_new(0, 0) : rb_str_dup(file);
+
+ if (!NIL_P(file)) {
+ if (line) rb_str_catf(mesg, ":%d", line);
+ rb_str_cat2(mesg, ": ");
+ }
+ rb_str_cat2(mesg, "warning: literal string will be frozen in the future");
+
+ VALUE str = obj;
+ if (STR_SHARED_P(str)) {
+ str = RSTRING(obj)->as.heap.aux.shared;
+ }
+ VALUE created = get_created_info(str, &line);
+ if (NIL_P(created)) {
+ rb_str_cat2(mesg, " (run with --debug-frozen-string-literal for more information)\n");
+ } else {
+ rb_str_cat2(mesg, "\n");
+ rb_str_append(mesg, created);
+ if (line) rb_str_catf(mesg, ":%d", line);
+ rb_str_cat2(mesg, ": info: the string was created here\n");
+ }
+ rb_warn_category(mesg, rb_warning_category_to_name(category));
+ }
+}
+
#undef rb_check_frozen
void
rb_check_frozen(VALUE obj)