Commit Graph

10 Commits

Author SHA1 Message Date
Zoltan Somogyi
b843d53a4c Improve actual/expected mismatch diagnostics.
compiler/typecheck_errors.m:
    Improve the diagnostics we generate for mismatches between actual and
    expected types. If the mismatch was between a single actual type and
    a single expected type, we already printed a message whose format
    was specialized for that case, but in every other case, we fell back
    to a more general but less readable error message template. Improve on this
    by splitting the task into two halves, one for the actual type(s) and one
    for the expected type(s), each of which generates simpler text if
    there is only one such type.

    Separate the actual type part of the diagnostic from the expected type part
    using a semicolon instead of a comma, because we now use commas to
    separate multiple actual types from each other, and multiple expected
    types from each other.

    Don't insist on putting a newline after the "type error:" part of the
    diagnostic.

    Do all of the above in just one predicate, factoring out code that
    used to be duplicated.

    Delete a function that has never been used. (I added it around 2008
    for later use by a student working on software transactional memory,
    but that use never happened.) This used to contain a third copy
    of the code that was factored out.

    For functions that used to take both a typecheck_info and a
    type_error_clause_context, delete the latter argument, since the caller
    invariably took it out of the typecheck_info that it also passed.

compiler/typecheck.m:
    Don't pass now-unneeded type_error_clause_contexts.

compiler/typecheck_error_type_assign.m:
    Fix typo in a field name.

tests/invalid/abstract_eqv.err_exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/actual_more_expected.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/integral_constant_no_suffix.err_exp:
tests/invalid/method_impl.err_exp:
tests/invalid/mixed_up_streams.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/type_diff.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/types2.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
    Update expected error messages.
2023-02-02 15:44:11 +11:00
Zoltan Somogyi
3fb55722be Print structured terms on one line if they fit.
The compiler's diagnostic outputs often contain terms, representing
either terms in the program, or other entities such as types or modes.
These can be printed either as

    f(a, b)

or as

    f(
        a,
        b
    )

We usually want the former if the term fits on one line, but the latter
if it is too big to fit on one line. The problem is that the code
generating the diagnostic often does not know what fits on one line.

compiler/error_spec.m:
    This diff adds two new format pieces that respectively stand for
    each half of a matched pair of left and right parentheses.
    The idea is that these can be printed

    - either with a newline, and an indent increment, after the left paren,
      and an indent decrement, and a newline, before the right paren,
      and with all newlines being honored between them,
    - or with no newline after the left paren or before the right paren,
      and all newlines between them being replaced by spaces.

compiler/write_error_spec.m:
    Implement the new format pieces, using the one-line format above
    if the term fits in the space available, or the multi-line format
    if it does not.

compiler/error_type_util.m:
    Use the new mechanism to represent the structure of types.

    Delete an old piece of code that had the same objective,
    but was much cruder and less effective.

tests/invalid/actual_expected.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/fbnf.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/type_diff.err_exp:
    Expect more compact representations of the structure of types.

tests/invalid/type_error_ambiguous.err_exp:
    Expect a different ordering of the same information.
    The difference is due to the changed internal representation
    (in terms of format_pieces) of a type.
2022-10-14 19:13:38 +11:00
Zoltan Somogyi
bc1bf0470f Get type_to_pieces to generate structured output.
compiler/error_util.m:
    Rewrite the type_to_pieces function, which typecheck_errors.m uses
    to format types in error messages, in order to fix five problems.

    The first two problems were with formatting higher order types.
    First, if a higher order type included an existentially quantified
    type variable, that quantification was *not* printed around the
    higher order type. Second, that quantification *was* printed around
    the type of every (non-higher-order) argument of the higher order value.
    The only reason why this has not been a problem so far is that
    we have no test case that contains a higher order type with an
    existentially quantified type variable :-(

    The fix to both these problems is to always put the existential
    quantification of any such type variables at the top level, regardless
    of the kind of type the quantification ranges over, and to never print
    any quantification of any of its component types.

    The third problem was that non-higher-order types were output in a
    non-structured fashion. (The special-case code we used to format
    higher order types did already output *them* in a structured fashion,
    though only at the top level.) We did this by converting (unparsing)
    the type to a term, and then calling mercury_term_to_string.

    Generating structured output by replacing only the mercury_term_to_string
    part would not worked well; most of the code would have been devoted
    to working out what kind of type the given term was representing.
    Therefore this diff changes the approach to formatting types without
    converting them to a term. The output we generate for each type
    uses indentation levels to show the type's structure, but for
    types whose formatted form is sufficiently short, we delete all
    the newlines from that representation.

    The fourth problem was while most of the existing code took care
    to treat function names as unbreakable, one part of it did not,
    which caused the name of a field update function, "f1 :=",
    to be split across two lines. This diff fixes that bug as well.

    A fifth problem, pointed out by Peter, was that we were printing
    arity-0 functions as "func" instead of as "(func)", even though
    Mercury syntax for types demands the latter.

    An arguable sixth problem was that we formatted existential
    quantifications as
        (some [Vars] Type)
    We now format that as
        some [Vars] (Type)

    Change the order of the arguments of type_to_pieces to reduce
    the difference between it and type_pieces, its internal version,
    which we use to format types that do not need existential quantification.

    Export the function that filters newlines out of lists of format
    components, since other parts of the compiler may also need it
    in the future.

    Fix two occurrences of a bug that is totally unrelated to the above:
    list_to_pieces and strict_list_to_pieces treated the last element
    in their input list differently from all the other elements.

compiler/parse_tree_out_term.m:
    Add a utility function for use by new code in error_util.m.

compiler/typecheck_errors.m:
    Conform to the new argument order of type_to_pieces.

tests/invalid/actual_expected.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/higher_order_mode_mismatch.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/no_method.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/type_mismatch.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_override2.err_exp:
tests/invalid_purity/impure_func_t5.err_exp:
tests/invalid_purity/impure_pred_t1.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
    Expect types in error messages in their updated format.
2022-02-21 17:56:52 +11:00
Zoltan Somogyi
29ff7d5732 Improve diagnostics for type- and mode-errors.
compiler/mode_errors.m:
    When generating an error message for a bad higher order inst,
    print the specific cause of the mismatch, instead of just
    "actual inst is X, expected inst was Y".

compiler/modecheck_call.m:
    Change the code that generates that error to record the specific cause
    in the mode_error structure of the error.

tests/invalid/higher_order_mode_mismatch.{m,err_exp}:
    Add a new test case for the specific causes that other test cases
    don't already cover. (As it happens, most of those causes can't be
    caught by mode analysis because typechecking reports them first,
    but it did so in ways that could be improved. Hence the change to
    typecheck_errors.m and most of the .err_exp files below.)

tests/invalid/Mmakefile:
    Enable the new test case.

compiler/typecheck_errors.m:
    Instead of generating output of the form

        <something> has type `abc',
        expected type was `def'

    generate output of the form

        <something> has type
            abc,
        expected type was
            def

    The indentation directs the eye to the differences that matter,
    and automatically lines up any corresponding parts of the actual
    and expected types. It also replaces the quotes as a method
    of separating the types being referred to from their surroundings.

tests/invalid/abstract_eqv.err_exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/arg_permutation.err_exp:
tests/invalid/bad_statevar_bad_context.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/comparison.err_exp:
tests/invalid/error_in_list.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid/getopt_old.err_exp:
tests/invalid/ho_type_arity_bug.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/illtyped_compare.err_exp:
tests/invalid/integral_constant_no_suffix.err_exp:
tests/invalid/method_impl.err_exp:
tests/invalid/mixed_up_streams.err_exp:
tests/invalid/mpj1.err_exp:
tests/invalid/mpj4.err_exp:
tests/invalid/no_method.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/invalid/type_error_in_arg.err_exp:
tests/invalid/type_mismatch.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_override2.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/invalid_purity/impure_func_t5.err_exp:
tests/invalid_purity/impure_pred_t1.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/invalid_purity/purity_type_error.err_exp:
    Expect the updated error messages.

tests/invalid/ho_type_mode_bug.m:
    Update obsolete comments.
2022-02-19 00:03:45 +11:00
Zoltan Somogyi
a9c2e88cab Improve diagnostics for type mismatches.
compiler/typecheck_errors.m:
    Improve diagnostics for some type errors in two separate ways.

    First, when printing an error message for a type mismatch,
    replace messages of the form

        ... has type T1,
        expected type was T2

    with messages of the form

        ... has type
            T1,
        expected type was
            T2.

    This way, the types both (a) stand out from the rest of the message,
    and (b) any corresponding parts will line up, making discrepancies
    easier to see.

    Second, avoid messages of the form

        ... has type `some [T] T'
        expected type was `some [T] T'.

    which can be both baffling and infuriating, by including the variable
    numbers of the type variables if this is needed to make two different
    types *visibly* different, yielding messages such as

        ... has type
            `some [T_2] T2',
        expected type was
            `some [T_3] T3'.

    which can still be baffling, in the absence of any info about where T_2
    and T_3 came from, but at least should not be infuriating, since it
    *does* show a difference between actual and expected.

compiler/error_util.m:
    Provide the infrastructure for the second part, by letting callers
    control how type variables are printed.

tests/invalid/actual_expected.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/coerce_ambig.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/foreign_procs_exist_type.err_exp:
tests/invalid_purity/impure_pred_t1_fixed.err_exp:
tests/invalid_purity/impure_pred_t2.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
    Expect the updated error messages.
2022-01-01 06:02:07 +11:00
Zoltan Somogyi
fdd141bf77 Clean up the tests in the other test directories.
tests/invalid/*.{m,err_exp}:
tests/misc_tests/*.m:
tests/mmc_make/*.m:
tests/par_conj/*.m:
tests/purity/*.m:
tests/stm/*.m:
tests/string_format/*.m:
tests/structure_reuse/*.m:
tests/submodules/*.m:
tests/tabling/*.m:
tests/term/*.m:
tests/trailing/*.m:
tests/typeclasses/*.m:
tests/valid/*.m:
tests/warnings/*.{m,exp}:
    Make these tests use four-space indentation, and ensure that
    each module is imported on its own line. (I intend to use the latter
    to figure out which subdirectories' tests can be executed in parallel.)

    These changes usually move code to different lines. For the tests
    that check compiler error messages, expect the new line numbers.

browser/cterm.m:
browser/tree234_cc.m:
    Import only one module per line.

tests/hard_coded/boyer.m:
    Fix something I missed.
2015-02-16 12:32:18 +11:00
Zoltan Somogyi
ec1f92b6e2 Module qualify predicate names in type errors.
compiler/typecheck_errors.m:
    Add a mechanism to allow the specification of a called predicate not just
    by simple_call_id, in which the sym_name is the original sym_name
    in the call, which may be unqualified, but by pred_id, through which
    we can always look up the predicate's module qualified name.

compiler/typecheck.m:
    Use that mechanism when the called predicate is uniquely known.

    Give a predicate a better name.

tests/invalid/comparison.{m,err_exp}:
tests/invalid/Mmakefile:
    Add and enable the motivating test case.

tests/invalid/*.err_exp:
    Update other expected output files reporting type errors in calls.
2015-01-20 20:54:05 +11:00
Julien Fischer
c1b0fdc047 Fix a couple of issues with some of the set types in the standard library
Branches: main, 11.01

Fix a couple of issues with some of the set types in the standard library
being used in type class instances.

library/set_unordlist.m:
	Define set_unordlists using a notag type rather than an equivalence.
	This allows them to be safely used in type class instances.

library/set.m:
	Export the definition of the type set/1 in an undocumented interface
	section.  Not exporting it leads to problems when it used used in
	type class instances (since it is defined using an abstract
	equivalence).  We don't want to use a notag wrapper here since that
	would lead to some operations, e.g. power_union/2, being less efficient.
	This should be ok; the abstraction barrier is still in place  since set/1
	is defined to be set_ordlist/1 (which is itself abstract).

tests/invalid/actual_expected.err_exp:
tests/invalid/overloading.err_exp:
	Conform to the above changes.
2011-02-16 02:11:50 +00:00
Peter Wang
d9e30aec5b Don't write an outer pair of brackets when formatting terms with '.'
Branches: main

compiler/mercury_to_mercury.m:
	Don't write an outer pair of brackets when formatting terms with '.'
	or ':' as the functor, which made module-qualified types in error
	messages unnecessarily ugly.

tests/hard_coded/impl_def_literal.exp:
tests/invalid/actual_expected.err_exp:
tests/invalid/bad_instance.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/ext_type.err_exp:
tests/invalid/ext_type_bug.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/illtyped_compare.err_exp:
tests/invalid/instance_dup_var.err_exp:
tests/invalid/invalid_instance_declarations.err_exp:
tests/invalid/method_impl.err_exp:
tests/invalid/mixed_up_streams.err_exp:
tests/invalid/mpj4.err_exp:
tests/invalid/nullary_ho_func_error.err_exp:
tests/invalid/overloading.err_exp:
tests/invalid/purity/impure_func_t5.err_exp:
tests/invalid/purity/impure_pred_t1.err_exp:
tests/invalid/purity/impure_pred_t1_fixed.err_exp:
tests/invalid/purity/impure_pred_t2.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/type_error_ambiguous.err_exp:
tests/misc_tests/pretty_print_test.exp:
tests/warnings/inference_test.exp:
	Update test cases.
2009-04-16 02:09:09 +00:00
Zoltan Somogyi
5b19d96951 When printing error messages about mismatches between actual and
Estimated hours taken: 3
Branches: main

compiler/typecheck_errors.m:
	When printing error messages about mismatches between actual and
	expected types, eliminate duplicates not on the basis of the raw
	data, but on the basis of what is to be printed. This is an
	improvement, because irrelevant differences in the raw data (e.g. the
	numbers of variables in varsets) were causing us to print duplicates.

tests/invalid/actual_expected.{m,err_exp}:
	New test case to test the new error message. It is an extract from
	use_local_vars.m, which is where I found the problem.

tests/invalid/Mmakefile:
	Enable the new test case.
2006-12-27 03:49:26 +00:00