[m-rev.] for review: Include variable name in coerce type error messages.

Peter Wang novalazy at gmail.com
Tue Jul 2 17:24:23 AEST 2024


Writing

    error: cannot coerce [the term bound to] `X' from ...
or
    warning: type conversion of [the term bound to] `X' from ...

seems too long-winded, so I've omitted the bracketed words.
Do the messages give the impression that variables can somehow change
types? Suggestions welcome.

----

compiler/typecheck.m:
compiler/typecheck_errors.m:
    As above.

tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_int.err_exp:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_non_du.err_exp:
tests/invalid/coerce_type_error.err_exp:
tests/invalid/coerce_unify_tvars.err_exp:
tests/invalid/coerce_uniq.err_exp:
tests/warnings/redundant_coerce.err_exp:
    Update expected outputs.

diff --git a/compiler/typecheck.m b/compiler/typecheck.m
index e401d849b..49097e3e4 100644
--- a/compiler/typecheck.m
+++ b/compiler/typecheck.m
@@ -1066,18 +1066,16 @@ report_coercion(TypeAssign, Coercion, !Info) :-
         unexpected($pred, "need to check")
     ;
         Status = unsatisfiable,
-        % XXX could include FromVar name
-        Spec = report_invalid_coerce_from_to(ClauseContext, Context, TVarSet,
-            FromType, ToType)
+        Spec = report_invalid_coerce_from_to(ClauseContext, Context, FromVar,
+            TVarSet, FromType, ToType)
     ;
         Status = not_yet_resolved,
         Spec = report_unresolved_coerce_from_to(ClauseContext, Context,
             FromVar, TVarSet, FromType, ToType)
     ;
         Status = satisfied_but_redundant,
-        % XXX could include FromVar name
-        Spec = report_redundant_coerce(ClauseContext, Context, TVarSet,
-            FromType)
+        Spec = report_redundant_coerce(ClauseContext, Context, FromVar,
+            TVarSet, FromType)
     ),
     typecheck_info_add_error(Spec, !Info).
 
diff --git a/compiler/typecheck_errors.m b/compiler/typecheck_errors.m
index 98361add1..73605991b 100644
--- a/compiler/typecheck_errors.m
+++ b/compiler/typecheck_errors.m
@@ -42,13 +42,13 @@
     prog_context, string) = error_spec.
 
 :- func report_invalid_coerce_from_to(type_error_clause_context, prog_context,
-    tvarset, mer_type, mer_type) = error_spec.
+    prog_var, tvarset, mer_type, mer_type) = error_spec.
 
 :- func report_unresolved_coerce_from_to(type_error_clause_context,
     prog_context, prog_var, tvarset, mer_type, mer_type) = error_spec.
 
 :- func report_redundant_coerce(type_error_clause_context, prog_context,
-    tvarset, mer_type) = error_spec.
+    prog_var, tvarset, mer_type) = error_spec.
 
 %---------------------------------------------------------------------------%
 
@@ -278,7 +278,7 @@ report_missing_tvar_in_foreign_code(ClauseContext, Context, VarName) = Spec :-
 
 %---------------------------------------------------------------------------%
 
-report_invalid_coerce_from_to(ClauseContext, Context, TVarSet,
+report_invalid_coerce_from_to(ClauseContext, Context, FromVar, TVarSet,
         FromType, ToType) = Spec :-
     % XXX TYPECHECK_ERRORS
     % This code can generate some less-than-helpful diagnostics.
@@ -290,6 +290,8 @@ report_invalid_coerce_from_to(ClauseContext, Context, TVarSet,
     % unresolved. For the remaining cases, is there something we can report
     % that would be more helpful?
     InClauseForPieces = in_clause_for_pieces(ClauseContext),
+    VarSet = ClauseContext ^ tecc_varset,
+    FromVarStr = mercury_var_to_name_only_vs(VarSet, FromVar),
     FromTypeStr = mercury_type_to_string(TVarSet, print_num_only, FromType),
     ToTypeStr = mercury_type_to_string(TVarSet, print_num_only, ToType),
     OnlyDuPieces = [words("You can only coerce"),
@@ -352,7 +354,8 @@ report_invalid_coerce_from_to(ClauseContext, Context, TVarSet,
             )
         )
     ),
-    ErrorPieces = [words("error: cannot coerce from")] ++
+    ErrorPieces = [words("error: cannot coerce")] ++
+        color_as_subject([quote(FromVarStr)]) ++ [words("from")] ++
         color_as_inconsistent([quote(FromTypeStr)]) ++ [words("to")] ++
         color_as_inconsistent([quote(ToTypeStr), suffix(".")]) ++ [nl] ++
         CausePieces ++ [nl],
@@ -374,11 +377,15 @@ report_unresolved_coerce_from_to(ClauseContext, Context, FromVar, TVarSet,
     Spec = spec($pred, severity_error, phase_type_check, Context,
         InClauseForPieces ++ ErrorPieces).
 
-report_redundant_coerce(ClauseContext, Context, TVarSet, FromType) = Spec :-
+report_redundant_coerce(ClauseContext, Context, FromVar, TVarSet, FromType) =
+        Spec :-
     InClauseForPieces = in_clause_for_pieces(ClauseContext),
+    VarSet = ClauseContext ^ tecc_varset,
+    FromVarStr = mercury_var_to_name_only_vs(VarSet, FromVar),
     FromTypeStr = mercury_type_to_string(TVarSet, print_num_only, FromType),
-    ErrorPieces = [words("warning: type conversion from")] ++
-        [quote(FromTypeStr), words("to the same type is")] ++
+    ErrorPieces = [words("warning: type conversion of")] ++
+        color_as_subject([quote(FromVarStr)]) ++
+        [words("from"), quote(FromTypeStr), words("to the same type is")] ++
         color_as_incorrect([words("redundant.")]) ++ [nl],
     Severity = severity_conditional(warn_redundant_coerce, yes,
         severity_warning, no),
diff --git a/tests/invalid/coerce_clobbered.err_exp b/tests/invalid/coerce_clobbered.err_exp
index c25024888..99d246eee 100644
--- a/tests/invalid/coerce_clobbered.err_exp
+++ b/tests/invalid/coerce_clobbered.err_exp
@@ -3,6 +3,6 @@ coerce_clobbered.m:021:   in coerce expression:
 coerce_clobbered.m:021:   mode error: the coerced term has instantiatedness
 coerce_clobbered.m:021:   `clobbered', but it must have a ground inst.
 coerce_clobbered.m:021: In clause for predicate `bad'/2:
-coerce_clobbered.m:021:   warning: type conversion from
+coerce_clobbered.m:021:   warning: type conversion of `X' from
 coerce_clobbered.m:021:   `coerce_clobbered.fruit' to the same type is
 coerce_clobbered.m:021:   redundant.
diff --git a/tests/invalid/coerce_int.err_exp b/tests/invalid/coerce_int.err_exp
index 581d491b1..d5e403397 100644
--- a/tests/invalid/coerce_int.err_exp
+++ b/tests/invalid/coerce_int.err_exp
@@ -1,6 +1,6 @@
 coerce_int.m:020: In clause for function `ok'/1:
-coerce_int.m:020:   warning: type conversion from `coerce_int.wrap(int)' to the
-coerce_int.m:020:   same type is redundant.
+coerce_int.m:020:   warning: type conversion of `X' from `coerce_int.wrap(int)'
+coerce_int.m:020:   to the same type is redundant.
 coerce_int.m:026: In clause for `bad(in(coerce_int.wrap(bound(1 ; 2)))) =
 coerce_int.m:026:   out(coerce_int.wrap(bound(1 ; 3)))':
 coerce_int.m:026:   mode error: the function result had the wrong
@@ -26,8 +26,8 @@ coerce_int.m:026:           )
 coerce_int.m:026:         )
 coerce_int.m:026:       ).
 coerce_int.m:026: In clause for function `bad'/1:
-coerce_int.m:026:   warning: type conversion from `coerce_int.wrap(int)' to the
-coerce_int.m:026:   same type is redundant.
+coerce_int.m:026:   warning: type conversion of `X' from `coerce_int.wrap(int)'
+coerce_int.m:026:   to the same type is redundant.
 coerce_int.m:032: In clause for `bad_wrong_type(in(coerce_int.wrap(bound(1 ; 2
 coerce_int.m:032:   ; 42u)))) = out(coerce_int.wrap(bound(1 ; 2)))':
 coerce_int.m:032:   in coerce expression:
@@ -39,5 +39,5 @@ coerce_int.m:032:   term's instantiatedness are not part of the input
 coerce_int.m:032:     1,
 coerce_int.m:032:     2.
 coerce_int.m:032: In clause for function `bad_wrong_type'/1:
-coerce_int.m:032:   warning: type conversion from `coerce_int.wrap(uint)' to
-coerce_int.m:032:   the same type is redundant.
+coerce_int.m:032:   warning: type conversion of `X' from
+coerce_int.m:032:   `coerce_int.wrap(uint)' to the same type is redundant.
diff --git a/tests/invalid/coerce_mode_error.err_exp b/tests/invalid/coerce_mode_error.err_exp
index f3b3f2516..99f902c17 100644
--- a/tests/invalid/coerce_mode_error.err_exp
+++ b/tests/invalid/coerce_mode_error.err_exp
@@ -3,7 +3,7 @@ coerce_mode_error.m:035:   in coerce expression:
 coerce_mode_error.m:035:   mode error: the coerced term has instantiatedness
 coerce_mode_error.m:035:   `free', but it must have a ground inst.
 coerce_mode_error.m:035: In clause for predicate `bad_coerce_free_input'/2:
-coerce_mode_error.m:035:   warning: type conversion from
+coerce_mode_error.m:035:   warning: type conversion of `X' from
 coerce_mode_error.m:035:   `coerce_mode_error.fruit' to the same type is
 coerce_mode_error.m:035:   redundant.
 coerce_mode_error.m:045: In clause for `bad_fruit_to_citrus(in, out)':
diff --git a/tests/invalid/coerce_non_du.err_exp b/tests/invalid/coerce_non_du.err_exp
index 8830a182c..c8852737a 100644
--- a/tests/invalid/coerce_non_du.err_exp
+++ b/tests/invalid/coerce_non_du.err_exp
@@ -1,22 +1,22 @@
 coerce_non_du.m:015: In clause for function `f1'/1:
-coerce_non_du.m:015:   error: cannot coerce from `int' to `int'.
+coerce_non_du.m:015:   error: cannot coerce `X' from `int' to `int'.
 coerce_non_du.m:015:   You can only coerce from one discriminated union type to
 coerce_non_du.m:015:   another, and `int' is a builtin type.
 coerce_non_du.m:019: In clause for function `f2'/1:
-coerce_non_du.m:019:   error: cannot coerce from `float' to `float'.
+coerce_non_du.m:019:   error: cannot coerce `X' from `float' to `float'.
 coerce_non_du.m:019:   You can only coerce from one discriminated union type to
 coerce_non_du.m:019:   another, and `float' is a builtin type.
 coerce_non_du.m:023: In clause for function `f3'/1:
-coerce_non_du.m:023:   error: cannot coerce from `{}' to `{}'.
+coerce_non_du.m:023:   error: cannot coerce `X' from `{}' to `{}'.
 coerce_non_du.m:023:   You can only coerce from one discriminated union type to
 coerce_non_du.m:023:   another, and `{}' is a tuple type.
 coerce_non_du.m:027: In clause for function `f4'/1:
-coerce_non_du.m:027:   error: cannot coerce from `((func int) = int)' to
+coerce_non_du.m:027:   error: cannot coerce `X' from `((func int) = int)' to
 coerce_non_du.m:027:   `((func int) = int)'.
 coerce_non_du.m:027:   You can only coerce from one discriminated union type to
 coerce_non_du.m:027:   another, and `((func int) = int)' is a function type.
 coerce_non_du.m:031: In clause for function `f5'/1:
-coerce_non_du.m:031:   error: cannot coerce from `pred(int, int)' to
+coerce_non_du.m:031:   error: cannot coerce `X' from `pred(int, int)' to
 coerce_non_du.m:031:   `pred(int, int)'.
 coerce_non_du.m:031:   You can only coerce from one discriminated union type to
 coerce_non_du.m:031:   another, and `pred(int, int)' is a predicate type.
diff --git a/tests/invalid/coerce_type_error.err_exp b/tests/invalid/coerce_type_error.err_exp
index ff670e9ae..809f612d7 100644
--- a/tests/invalid/coerce_type_error.err_exp
+++ b/tests/invalid/coerce_type_error.err_exp
@@ -1,23 +1,23 @@
 coerce_type_error.m:045: In clause for predicate `bad_unrelated'/2:
-coerce_type_error.m:045:   error: cannot coerce from
+coerce_type_error.m:045:   error: cannot coerce `X' from
 coerce_type_error.m:045:   `coerce_type_error.orange_non_fruit' to
 coerce_type_error.m:045:   `coerce_type_error.citrus'.
 coerce_type_error.m:070: In clause for predicate `bad_phantom'/2:
-coerce_type_error.m:070:   error: cannot coerce from
+coerce_type_error.m:070:   error: cannot coerce `X' from
 coerce_type_error.m:070:   `coerce_type_error.phantom(int)' to
 coerce_type_error.m:070:   `coerce_type_error.phantom(float)'.
 coerce_type_error.m:091: In clause for predicate `bad_higher_order'/2:
-coerce_type_error.m:091:   error: cannot coerce from
+coerce_type_error.m:091:   error: cannot coerce `X' from
 coerce_type_error.m:091:   `coerce_type_error.wrap_ho(coerce_type_error.citrus)'
 coerce_type_error.m:091:   to
 coerce_type_error.m:091:   `coerce_type_error.wrap_ho(coerce_type_error.fruit)'.
 coerce_type_error.m:106: In clause for predicate `bad_foreign_type'/2:
-coerce_type_error.m:106:   error: cannot coerce from
+coerce_type_error.m:106:   error: cannot coerce `X' from
 coerce_type_error.m:106:   `coerce_type_error.wrap_ft(coerce_type_error.citrus)'
 coerce_type_error.m:106:   to
 coerce_type_error.m:106:   `coerce_type_error.wrap_ft(coerce_type_error.fruit)'.
 coerce_type_error.m:118: In clause for predicate `bad_abs_type'/2:
-coerce_type_error.m:118:   error: cannot coerce from
+coerce_type_error.m:118:   error: cannot coerce `X' from
 coerce_type_error.m:118:   `coerce_type_error.wrap_abs(coerce_type_error.citrus)'
 coerce_type_error.m:118:   to
 coerce_type_error.m:118:   `coerce_type_error.wrap_abs(coerce_type_error.fruit)'.
diff --git a/tests/invalid/coerce_unify_tvars.err_exp b/tests/invalid/coerce_unify_tvars.err_exp
index 8d5379f57..7e3294902 100644
--- a/tests/invalid/coerce_unify_tvars.err_exp
+++ b/tests/invalid/coerce_unify_tvars.err_exp
@@ -1,3 +1,3 @@
 coerce_unify_tvars.m:063: In clause for predicate `head_type_params'/2:
-coerce_unify_tvars.m:063:   error: cannot coerce from `list.list(V_1)' to
+coerce_unify_tvars.m:063:   error: cannot coerce `X' from `list.list(V_1)' to
 coerce_unify_tvars.m:063:   `list.list(V_2)'.
diff --git a/tests/invalid/coerce_uniq.err_exp b/tests/invalid/coerce_uniq.err_exp
index 59e54e01a..3521ea690 100644
--- a/tests/invalid/coerce_uniq.err_exp
+++ b/tests/invalid/coerce_uniq.err_exp
@@ -4,11 +4,11 @@ coerce_uniq.m:024:   instantiated.
 coerce_uniq.m:024:   Final instantiatedness of `X' was `ground',
 coerce_uniq.m:024:   expected final instantiatedness was `unique'.
 coerce_uniq.m:024: In clause for predicate `coerce_ui'/2:
-coerce_uniq.m:024:   warning: type conversion from `coerce_uniq.fruit' to the
-coerce_uniq.m:024:   same type is redundant.
+coerce_uniq.m:024:   warning: type conversion of `X' from `coerce_uniq.fruit'
+coerce_uniq.m:024:   to the same type is redundant.
 coerce_uniq.m:029: In clause for predicate `coerce_di'/2:
-coerce_uniq.m:029:   warning: type conversion from `coerce_uniq.fruit' to the
-coerce_uniq.m:029:   same type is redundant.
+coerce_uniq.m:029:   warning: type conversion of `X' from `coerce_uniq.fruit'
+coerce_uniq.m:029:   to the same type is redundant.
 coerce_uniq.m:034: In clause for predicate `coerce_become_shared'/2:
-coerce_uniq.m:034:   warning: type conversion from `coerce_uniq.fruit' to the
-coerce_uniq.m:034:   same type is redundant.
+coerce_uniq.m:034:   warning: type conversion of `X' from `coerce_uniq.fruit'
+coerce_uniq.m:034:   to the same type is redundant.
diff --git a/tests/warnings/redundant_coerce.err_exp b/tests/warnings/redundant_coerce.err_exp
index 248110a27..b0542ab69 100644
--- a/tests/warnings/redundant_coerce.err_exp
+++ b/tests/warnings/redundant_coerce.err_exp
@@ -1,11 +1,11 @@
 redundant_coerce.m:035: In clause for predicate `test1'/0:
-redundant_coerce.m:035:   warning: type conversion from `maybe.maybe(int)' to
-redundant_coerce.m:035:   the same type is redundant.
+redundant_coerce.m:035:   warning: type conversion of `V_4' from
+redundant_coerce.m:035:   `maybe.maybe(int)' to the same type is redundant.
 redundant_coerce.m:039: In clause for predicate `test2'/0:
-redundant_coerce.m:039:   warning: type conversion from
+redundant_coerce.m:039:   warning: type conversion of `X' from
 redundant_coerce.m:039:   `redundant_coerce.box(redundant_coerce.fruit)' to the
 redundant_coerce.m:039:   same type is redundant.
 redundant_coerce.m:049: In clause for predicate `test3'/0:
-redundant_coerce.m:049:   warning: type conversion from
+redundant_coerce.m:049:   warning: type conversion of `X' from
 redundant_coerce.m:049:   `redundant_coerce.maybe_box(redundant_coerce.citrus)'
 redundant_coerce.m:049:   to the same type is redundant.
-- 
2.44.0



More information about the reviews mailing list