summaryrefslogtreecommitdiff
path: root/error.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2026-02-05 20:38:00 +0100
committerBenoit Daloze <eregontp@gmail.com>2026-02-07 10:06:36 +0100
commitd066b9e01ccb2260fac8b2580c10e73335c7c7db (patch)
treeece08ae6b0309149e09a640a3b41537a6485ee13 /error.c
parent96d00640978d78ede1f5b2b63e422cfd1e849891 (diff)
Refactor type error to be more consistent
[Bug #21864] Co-Authored-By: Benoit Daloze <eregontp@gmail.com>
Diffstat (limited to 'error.c')
-rw-r--r--error.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/error.c b/error.c
index d6518feb34..140049fdd2 100644
--- a/error.c
+++ b/error.c
@@ -2758,6 +2758,68 @@ nometh_err_private_call_p(VALUE self)
return rb_attr_get(self, id_private_call_p);
}
+static const char *
+type_err_cname(VALUE val)
+{
+ if (NIL_P(val)) {
+ return "nil";
+ }
+ else if (val == Qtrue) {
+ return "true";
+ }
+ else if (val == Qfalse) {
+ return "false";
+ }
+ return NULL;
+}
+
+NORETURN(static void type_err_raise(VALUE val, const char *tname, const char *msg));
+static void
+type_err_raise(VALUE val, const char *tname, const char *msg)
+{
+ const char *cname = type_err_cname(val);
+ rb_encoding *enc = rb_utf8_encoding();
+ if (cname) {
+ rb_enc_raise(enc, rb_eTypeError, "%s %s into %s", msg, cname, tname);
+ }
+ rb_enc_raise(enc, rb_eTypeError, "%s %"PRIsVALUE" into %s", msg, rb_obj_class(val), tname);
+}
+
+NORETURN(void rb_no_implicit_conversion(VALUE val, const char *tname));
+void
+rb_no_implicit_conversion(VALUE val, const char *tname)
+{
+ type_err_raise(val, tname, "no implicit conversion of");
+}
+
+NORETURN(void rb_cant_convert(VALUE val, const char *tname));
+void
+rb_cant_convert(VALUE val, const char *tname)
+{
+ type_err_raise(val, tname, "can't convert");
+}
+
+NORETURN(void rb_cant_convert_invalid_return(VALUE val, const char *tname, const char *method_name, VALUE ret));
+void
+rb_cant_convert_invalid_return(VALUE val, const char *tname, const char *method_name, VALUE ret)
+{
+ const char *cname = type_err_cname(val);
+ rb_encoding *enc = rb_utf8_encoding();
+ if (cname) {
+ rb_enc_raise(
+ enc, rb_eTypeError, "can't convert %s into %s (%s#%s gives %s)",
+ cname, tname, cname, method_name, type_err_cname(ret));
+ }
+ VALUE klass = rb_obj_class(val);
+ const char *retname = type_err_cname(ret);
+ if (!retname) {
+ retname = rb_obj_classname(ret);
+ }
+ rb_enc_raise(
+ enc, rb_eTypeError, "can't convert %"PRIsVALUE" into %s (%"PRIsVALUE"#%s gives %s)",
+ klass, tname, klass, method_name, retname);
+}
+
void
rb_invalid_str(const char *str, const char *type)
{