Commit Graph

7 Commits

Author SHA1 Message Date
Zoltan Somogyi
18817d62d0 Record more than a pred_proc_id for each method.
Class and instance definitions both contain lists of methods,
predicates and/or functions, that each have one or more procedures.
Until now, we represented the methods in class and instance definitions
as lists of nothing more than pred_proc_ids. This fact complicated
several operations,

- partly because there was no simple way to tell which procedures
  were part of the same predicate or function, and

- partly because the order of the list is important (we identify
  each method procedure in our equivalent of vtables with a number,
  which is simply the procedure's position in this list), but there was
  absolutely no information about recorded about this.

This diff therefore replaces the lists of pred_proc_ids with lists of
method_infos. Each method_info contains

- the method procedure number, i.e. the vtable index,

- the pred_or_func, sym_name and user arity of the predicate or function
  that the method procedure is a part of, to make it simple to test
  whether two method_infos represent different modes of the same predicate
  or function, or not,

- the original pred_proc_id of the method procedure, which never changes,
  and

- the current pred_proc_id, which program transformations *can* change.

compiler/hlds_class.m:
    Make the change above in the representations of class and instance
    definitions.

    Put the fields of both types into a better order, by putting
    related fields next to each other.

    Put a notag wrapper around method procedure numbers to prevent
    accidentally mixing them up with plain integers.

    Add some utility functions.

compiler/prog_data.m:
    Replace three fields containing pred_or_func, sym_name and arity
    in the parse tree representation of instance methods with just one,
    which contains all three pieces of info. This makes it easier to operate
    on them as a unit.

    Change the representation of methods defined by clauses from a list
    of clauses to a cord of clauses, since this supports constant-time
    append.

compiler/hlds_goal.m:
    Switch from plain ints to the new notag representation of method
    procedure numbers in method call goals.

compiler/add_class.m:
    Simplify the code for adding new classes to the HLDS.

    Give some predicates better names.

compiler/check_typeclass.m:
    Significantly simplify the code for that generates the pred_infos and
    proc_infos implementing all the methods of an instances definition,
    and construct lists of method_infos instead of lists of pred_proc_ids.

    Give some predicates better names.

    Some error messages about problems in instance definitions started with

        In instance declaration for class/arity:

    while others started with

        In instance declaration for class(module_a.foo, module_b.bar):

    Replace both with

        In instance declaration for class(foo, bar):

    because it contains more useful information than the first, and less
    non-useful information than the second. Improve the wording of some
    error messages.

    Factor out some common code.

compiler/prog_mode.m:
compiler/prog_type.m:
compiler/prog_util.m:
    Generalize the existing predicates for stripping "builtin.m" module
    qualifiers from sym_names, cons_ids, insts, types and modes
    to allow also the stripping of *all* module qualifiers. This capability
    is now used when we print an instance's type vector as a context
    for diagnostics about problems inside instance definitions.

compiler/add_pred.m:
    Add a mechanism for returning the pred_id of a newly created pred_info,
    whether or not it was declared using a predmode declaration. This
    capability is now needed by add_class.m.

    Move the code creating an error message into its own function, and export
    that function for add_class.m.

compiler/polymorphism_type_info.m:
    Fix some comment rot.

compiler/base_typeclass_info.m:
compiler/call_gen.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/direct_arg_in_out.m:
compiler/error_msg_inst.m:
compiler/float_regs.m:
compiler/get_dependencies.m:
compiler/higher_order.m:
compiler/hlds_error_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_typeclass_table.m:
compiler/instance_method_clauses.m:
compiler/intermod.m:
compiler/make_hlds_error.m:
compiler/ml_call_gen.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/old_type_constraints.m:
compiler/parse_class.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_inst.m:
compiler/polymorphism_post_copy.m:
compiler/polymorphism_type_class_info.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/recompilation.usage.m:
compiler/state_var.m:
compiler/type_class_info.m:
compiler/typecheck_debug.m:
compiler/typecheck_error_type_assign.m:
compiler/typecheck_errors.m:
compiler/typecheck_msgs.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_mode_3.err_exp:
tests/invalid/typeclass_mode_4.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
    Expect the updated wording of some error messages.
2022-11-22 02:27:33 +11:00
Zoltan Somogyi
a832857b5e Give more precise context in an error message.
compiler/check_typeclass.m:
    When reporting an error for an instance declaration that has
    just one unrecognized method, use the context of the method itself
    in the error message. (If there is more than one unrecognized method,
    continue to use the context of the instance declaration as a whole.)

    Make the test of whether a method is recognized or not clearer.

tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_9.err_exp:
    Update the expected context.
2022-02-21 15:24:17 +11:00
Zoltan Somogyi
d64961d79d Use checked types/insts/modes in parse_tree_module_src.
This means that we can do the exact same checks (and, if needed, generate
the exact same error messages) when generating interface files as when
generating target language code.

This should also allow us to simplify the process of adding type, inst
and mode definitions to the HLDS.

compiler/prog_item.m:
    As above.

    Delete unused function.

compiler/error_util.m:
    Add mechanisms that allow us to distinguish (a) error specs that represent
    a type, inst or mode name definition being invalid, from (b) other error
    specs.

compiler/check_type_inst_mode_defns.m:
    Improve the error messages we generate, in several ways.

    First, for each message, specify a real severity. When the messages
    could be seen only when generating interface files, making them all
    warnings was fine and preserved old behavior, but since soon these
    will be the only place for these checks, we need to call errors errors.

    Second, specify, in the phase, which errors represent a invalid type,
    inst or mode definition, and which don't.

    Third, improve the wording of messages. In some places, do this by
    being clearer about the distinction between declarations and definitions.
    In others, do it by including more information in the message. In yet
    others, do it by recovering some kinds of mistakes (mostly items being
    in the wrong section) enough to avoid avalanche errors.

    Fourth, fix a bug. If a type ctor has an exported *declaration*,
    then it is ok for any foreign type definitions for that type_ctor
    being in the implementation section, but if the type_ctor has an
    exported Mercury *definition*, then any foreign_type definitions
    must be in the interface section as well. The code that handled
    both these situations did not enforce that.

    Fifth, fix another bug: do not include foreign type definitions
    in the source definitions of a type_ctor twice, once as a "du" (sic)
    definition, and once as itself.

compiler/convert_parse_tree.m:
    Check type, inst and mode definitions in raw_compilation_units
    when creating parse_tree_module_srcs.

compiler/comp_unit_interface.m:
    Make the code constructing interface files work from the checked maps
    in parse_tree_module_srcs.

compiler/make_hlds_passes.m:
    Set the flags that say we have found invalid type, inst or mode definitions
    from the error specs constructed during the creation of the checked
    type, inst and mode maps.

compiler/add_type.m:
    Comment out an error message for a condition that will be detected and
    reported by check_type_inst_mode_defns.m.

compiler/make_hlds_separate_items.m:
    For now, turn checked maps of type, inst and mode definitions
    back to item lists for addition to the HLDS. Adding whole checked
    definitions to the HLDS will be done by a future change.

compiler/make_hlds_error.m:
    Fix misleading indentation in an error message.

compiler/parse_tree_out.m:
    Conform to the changes above.

    Generate output whose indentation does not depend on tab settings.

compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
    Conform to the changes above.

compiler/parse_type_defn.m:
    Fix misleading error message for ":- type <name> = <type>".

tests/debugger/foreign_type.{m,exp}:
    Delete a redundant type declaration to avoid a warning, and update
    the .exp file to expect the new line numbers.

tests/invalid/any_mode.err_exp:
tests/invalid/bug436.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/exported_foreign_enum.err_exp:
tests/invalid/fe_unmapped_nonverbose.err_exp:
tests/invalid/fe_unmapped_verbose.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/foreign_solver_type.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/pragma_qual_error.err_exp:
tests/invalid/repeated_field_name.err_exp:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_conflict.err_exp:
tests/invalid_nodepend/bad_foreign_type.err_exp:
tests/invalid_nodepend/bigtest.err_exp:
tests/invalid_nodepend/invalid_typeclass.err_exp:
tests/invalid_nodepend/types.err_exp:
tests/invalid_nodepend/uu_type.err_exp:
tests/invalid_nodepend/where_abstract_enum.err_exp:
    Expect the new error messages.

tests/invalid/abstract_solver_type.{m,err_exp}:
tests/warnings/abstract_solver_type.{m,exp}:
    Move the abstract_solver_type test case from invalid to warnings, because
    this diff changes its only error to be only a warning.

tests/invalid/Mmakefile
2021-10-16 17:37:36 +11:00
Peter Wang
88047bbb45 Delete Erlang from tests.
tests/general/float_test.exp3:
tests/general/float_test.m:
tests/general/read_dir_regression.exp4:
tests/general/read_dir_regression.m:
tests/hard_coded/remove_file.exp2:
tests/hard_coded/remove_file.m:
    Delete Erlang backend specific expected outputs.

tests/hard_coded/Mmakefile:
tests/hard_coded/erlang_deconstruct.exp:
tests/hard_coded/erlang_deconstruct.m:
tests/hard_coded/existential_list.exp:
tests/hard_coded/existential_list.m:
tests/valid/Mmakefile:
tests/valid/erl_ite_vars.m:
tests/valid/zf_erlang_bug.m:
    Delete erlang target specific tests.

tests/*:
    Delete Erlang foreign procs and foreign types.
2020-10-27 11:10:11 +11:00
Zoltan Somogyi
3a1ed2efcb Replace simple_call_id with pf_sym_name_arity.
compiler/prog_data.m:
    Delete the simple_call_id data type, since it is isomorphic
    to the pf_sym_name_arity type, which more clearly specifies
    what is stored inside it.

compiler/prog_out.m:
    Rename (all three versions of) simple_call_id_to_string to
    pf_sym_name_orig_arity_to_string, both to conform to the change
    in the input data type, and to emphasize that the resulting string
    will contain the *original* arity of functions (which does not include
    the return value), which is one less than the arity in the
    pf_sym_name_arity structure (which, in accordance with the
    convention inside the compiler that the arity is the length
    of the argument list, *does* include the return value).

    Delete the provision inside simple_call_id_to_string, now
    pf_sym_name_orig_arity_to_string, for special handling of the names
    of the predicates we use to implement promises, because it seems that
    *none* of the call sites to any of the three versions of this function
    can actually pass to it the identity of such a predicate. These calls
    refer to a predicate or mode declaration item (which promise predicates
    do not have), to clause or foreign_proc items (which again, promise
    predicates cannot have) or calls to the predicate (promise predicates
    cannot be called).

    Delete the exported predicate simple_call_id_to_sym_name_arity.
    It was called from exactly one place, inside prog_out.m itself,
    and this diff inlines that call.

    Avoid unnecessary forwarding of work from prog_out.m to error_util.m.

    Delete (all three versions of) write_simple_call_id. The changes
    below replace all their (few) uses with calls to
    pf_sym_name_orig_arity_to_string.

compiler/error_util.m:
    Replace the simple_call() error piece with qual_pf_sym_name_orig_arity,
    and add a new version unqual_pf_sym_name_orig_arity. Their names
    explicitly say that they print the original arities of functions,
    also say whether they strip away any module qualification on the
    sym_name inside the pf_sym_name_arity. We prefer the unqual version
    in situations where the module qualifier is implicit, which usually means
    that it must be the same as the name of the module being compiled, because
    it reduces visual clutter for readers of error messages.

    Put {qual,unqual}_pf_sym_name_orig_arity next to their most closely
    related function symbols, {qual,unqual}_sym_name_arity, in the
    format_component type. (This yields a few inconsequential changes
    in the order of error_specs when sorted.)

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_data.m:
compiler/hlds_desc.m:
compiler/hlds_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/inst_util.m:
compiler/llds_out_instr.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/ml_unify_gen_construct.m:
compiler/mlds_to_c_stmt.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modecheck_util.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_type_repn.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/recompilation.version.m:
compiler/term_constr_build.m:
compiler/termination.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unused_imports.m:
    Conform to the changes above. Where I am pretty sure that in an error
    message, the module qualifier of a name must be the current module,
    use unqual_pf_sym_name_orig_arity instead of qual_pf_sym_name_orig_arity.

    Add some sanity checks where they seem appropriate.

    Replace sequences of io.write_strings with uses of io.format where this
    yields clearer code. (This is why there were no remaining calls to
    write_simple_call_id.)

    Shorten some too-long lines.

    In add_pred.m, make the order of some predicate definitions match
    the order of the calls to them.

tests/invalid/ambiguous_method.err_exp:
tests/invalid/ambiguous_method_2.err_exp:
tests/invalid/bad_pred_arity.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug278.err_exp:
tests/invalid/bug410.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/complex_constraint_err.err_exp:
tests/invalid/constrained_poly_insts.err_exp:
tests/invalid/errors.err_exp:
tests/invalid/errors1.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/exported_mode.err_exp:
tests/invalid/field_syntax_error.err_exp:
tests/invalid/foreign_singleton.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/imported_mode.err_exp:
tests/invalid/invalid_binary_literal.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/invalid_hex_literal.err_exp:
tests/invalid/invalid_octal_literal.err_exp:
tests/invalid/make_opt_error.err_exp:
tests/invalid/missing_det_decls.err_exp:
tests/invalid/multimode_syntax.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/occurs.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/ref_to_implicit_pred.err_exp:
tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_1.err_exp2:
tests/invalid/require_tailrec_2.err_exp:
tests/invalid/require_tailrec_2.err_exp2:
tests/invalid/require_tailrec_3.err_exp:
tests/invalid/require_tailrec_3.err_exp2:
tests/invalid/state_vars_test2.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/state_vars_test5.err_exp:
tests/invalid/type_inf_loop.err_exp:
tests/invalid/typeclass_constraint_extra_var.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_test_12.err_exp:
tests/invalid/typeclass_test_2.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/unbound_type_vars.err_exp:
tests/invalid/with_type.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/warnings/double_underscore.exp:
tests/warnings/pragma_source_file.exp:
tests/warnings/singleton_test.exp:
tests/warnings/singleton_test.exp2:
tests/warnings/singleton_test.exp3:
tests/warnings/singleton_test.exp4:
tests/warnings/singleton_test_state_var.exp:
tests/warnings/warn_return.exp:
tests/warnings/warn_return.exp2:
tests/warnings/warn_return.exp3:
tests/warnings/warn_succ_ind.exp:
tests/warnings/warn_succ_ind.exp2:
tests/warnings/warn_succ_ind.exp3:
tests/warnings/warn_succ_ind.exp4:
    Update all these expected output files. Most changes are due to
    predicate and function names no longer being module qualified when
    the module qualification is obvious. A few changes are due to the
    change in the relative ordering of the function symbols of the
    format_component type.

    For singleton_test, warn_return and warn_succ_ind in warnings,
    the changes to the non-C .exp files were done by hand, so they
    may have the wrong white space.
2020-03-16 12:10:28 +11:00
Zoltan Somogyi
214ec425be Make some error messages order-independent.
The old code in modules.m that was recently delete preserved the order
of the items in the source code. The new code that replaced it groups
all the items in a section together. If the source code follows any
pattern other than "one interface section, one implementation section",
then this can change the relative order of two items.

Previously we assumed that items are added to the HLDS in order of their
occurrence in the source code. This diff eliminates that assumption
when we generate error messages that refer to two or more items.

compiler/add_class.m:
    Eliminate this adding-items-by-source-context-order assumption
    when diagnosing duplicate instance declarations.

compiler/add_type.m:
    Eliminate this adding-items-by-source-context-order assumption
    when diagnosing duplicate type declarations and definitions
    (both Mercury types and foreign types).

compiler/make_hlds_error.m:
    Eliminate this adding-items-by-source-context-order assumption
    when diagnosing duplicate declarations of many different kinds
    of items.

compiler/style_checks.m:
    Eliminate this adding-items-by-source-context-order assumption
    when diagnosing non-adjacent argument type and mode declarations
    for the same predicate or function.

compiler/termination.m:
    Eliminate this adding-items-by-source-context-order assumption
    when diagnosing inconsistent termination assertions
    for mutually recursive procedures. Simplify the code
    that generates the error messages doing this.

tests/invalid/bug476.err_exp:
    Expect an error message that uses the phrase
    "previous definition" correctly.
2019-04-24 22:36:02 +10:00
Zoltan Somogyi
bbb0971cd3 Fix a compiler abort caused by name clash between pred and method.
This fixes Mantis bug 476. The root cause of the compiler abort was the
following sequence of events.

- We first inserted the declaration of the predicate named "mark"
  near the bottom of bug476.m file into the predicate table.

- Later we tried to insert the declaration of the class method predicate
  named "mark" near the top of the file into the predicate table.
  This insertion failed, but it nevertheless returned a valid pred_proc_id
  to the code handling the addition of the class methods to the HLDS.
  This was the pred_proc_id resulting from the first, successful insertion.

- The compiler expects every predicate that represents a class method
  to have at least one universal typeclass constraint on it, this being
  the constraint implicit in its nature as a typeclass method. The code
  that checks typeclass constraints aborts if it does not find it.
  In this case, it did not find it, since we added into the pred_info
  we constructed it for the second, unsuccessful insertion, but this
  never made it into the HLDS.

The fix is entirely in the change to add_pred.m. The rest of the changes
represent a cleanup of the affected code, which enabled me to find the
root cause of the problem.

compiler/add_pred.m:
    When adding a predmode declaration to the HLDS, if adding the pred
    part fails (because there is already another predicate with the
    same name in the HLDS), do not try to add the mode part, because
    it does not make sense to add the mode part of a predmode declaration
    to the predicate resulting from a *different* pred declaration.

    Mantis bug 476 was caused by (a) the compiler doing this nonsensical
    addition, (b) by chance this addition being successful, and (c) this
    success misleading the code in add_class.m that handles the predmode
    declarations of class methods.

compiler/prog_item.m:
    Change the representation of the two kinds of declarations that may occur
    inside class declarations, predicate declarations (including predmode
    declarations) and mode declarations, to allow each kind to be handled
    separately.

    Document their fields a bit better.

compiler/add_class.m:
    Use the new representation in prog_item.m to simplify the old,
    convoluted code for adding the pred and mode declarations inside
    typeclass definitions to the HLDS.

compiler/hlds_pred.m:
    Document the invariant whose violation led to the compiler abort.

compiler/make_hlds_passes.m:
    Fix a comment.

compiler/equiv_type.m:
compiler/module_qual.qualify_items.m:
compiler/parse_class.m:
compiler/parse_item.m:
compiler/parse_tree_out.m:
compiler/prog_data.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
    Conform to the change in prog_item.m.

tests/invalid/bug476.{m,err_exp}:
    A regression test for the bug.

tests/invalid/Mmakefile:
    Enable the new test case.
2019-04-08 01:12:41 +10:00