mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
typecheck_unify_var_functor.m used to have separate code paths
- to handle the functors of builtin types, and
- to handle the functors of all other types.
However, the second path invoked code in typecheck_cons_infos.m that
*also* handled builtin types.
compiler/typecheck_unify_var_functor.m:
Simplify this arrangement by deleting the code that chose between
the two paths, and handling functors of builtin types together with
all the other functors in (what used to be) the second path.
compiler/typecheck_cons_infos.m:
Return a distinct result for cons_ids of all builtin types
(including some that typecheck_unify_var_functor.m did not handle
via the first code path.)
Document the meanings of the possible results.
compiler/hlds_cons.m:
Change the ctor_field_table type to encode the invariant
that we don't map sym_names to the empty list of field definitions.
compiler/hlds_pred.m:
The predicates that test whether a sym_name/arity pair or pred_info
refer to a field access function must search the ctor_field_table
to answer the question. Make them return the info they get from that
search, to save their callers from having to do it again.
Give a predicate a more meaningful name.
compiler/typecheck_info.m:
Record extra info if we are typechecking in a field access function,
since it may be needed, and storing it costs next to nothing.
compiler/add_clause.m:
compiler/add_type.m:
compiler/check_field_access_functions.m:
compiler/field_access.m:
compiler/intermod_decide.m:
compiler/pre_typecheck.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/typecheck_error_undef.m:
Conform to the changes above.
146 lines
6.0 KiB
Mathematica
146 lines
6.0 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1993-2012 The University of Melbourne.
|
|
% Copyright (C) 2014-2025 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: check_field_access_functions.m.
|
|
%
|
|
% Check that the declarations for field extraction and update functions
|
|
% are sensible, and generate error messages for the ones that aren't.
|
|
% We can do this only after we have processed every predicate declaration,
|
|
% as well as everything that affects either the type table or the
|
|
% constructor table.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module hlds.make_hlds.check_field_access_functions.
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.make_hlds.make_hlds_types.
|
|
:- import_module hlds.status.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.error_spec.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_item.
|
|
|
|
:- import_module list.
|
|
|
|
:- pred check_preds_if_field_access_function(module_info::in,
|
|
sec_list(item_pred_decl_info)::in,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
:- pred maybe_check_field_access_function(module_info::in,
|
|
sym_name::in, user_arity::in, pred_status::in, prog_context::in,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds.hlds_cons.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module parse_tree.prog_util.
|
|
|
|
:- import_module maybe.
|
|
:- import_module one_or_more.
|
|
:- import_module term_context.
|
|
:- import_module varset.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
check_preds_if_field_access_function(_ModuleInfo, [], !Specs).
|
|
check_preds_if_field_access_function(ModuleInfo, [SecList | SecLists],
|
|
!Specs) :-
|
|
SecList = sec_sub_list(SectionInfo, ItemPredSecls),
|
|
SectionInfo = sec_info(ItemMercuryStatus, _NeedQual),
|
|
item_mercury_status_to_pred_status(ItemMercuryStatus, PredStatus),
|
|
list.foldl(check_pred_if_field_access_function(ModuleInfo, PredStatus),
|
|
ItemPredSecls, !Specs),
|
|
check_preds_if_field_access_function(ModuleInfo, SecLists, !Specs).
|
|
|
|
:- pred check_pred_if_field_access_function(module_info::in, pred_status::in,
|
|
item_pred_decl_info::in,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
check_pred_if_field_access_function(ModuleInfo, PredStatus, ItemPredDecl,
|
|
!Specs) :-
|
|
ItemPredDecl = item_pred_decl_info(SymName, PredOrFunc, TypesAndMaybeModes,
|
|
_, _, _, _, _, _, _, _, _, Context, _SeqNum),
|
|
(
|
|
PredOrFunc = pf_predicate
|
|
;
|
|
PredOrFunc = pf_function,
|
|
PredFormArity = types_and_maybe_modes_arity(TypesAndMaybeModes),
|
|
user_arity_pred_form_arity(pf_function, UserArity, PredFormArity),
|
|
maybe_check_field_access_function(ModuleInfo, SymName, UserArity,
|
|
PredStatus, Context, !Specs)
|
|
).
|
|
|
|
maybe_check_field_access_function(ModuleInfo, FuncSymName, UserArity,
|
|
FuncStatus, Context, !Specs) :-
|
|
UserArity = user_arity(UserArityInt),
|
|
( if
|
|
% XXX ARITY Make this take UserArity, not UserArityInt.
|
|
is_field_access_function_name(ModuleInfo, FuncSymName, UserArityInt,
|
|
AccessType, FieldName, OoMFieldDefns)
|
|
then
|
|
check_field_access_function(Context, FuncSymName, UserArity,
|
|
FuncStatus, AccessType, FieldName, OoMFieldDefns, !Specs)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred check_field_access_function(prog_context::in,
|
|
sym_name::in, user_arity::in, pred_status::in,
|
|
field_access_type::in, sym_name::in, one_or_more(hlds_ctor_field_defn)::in,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
check_field_access_function(Context, FuncSymName, UserArity,
|
|
FuncStatus, _AccessType, _FieldName, OoMFieldDefns, !Specs) :-
|
|
% Check that a function applied to an exported type is also exported.
|
|
( if
|
|
% Abstract types have status `abstract_exported', so errors won't be
|
|
% reported for local field access functions for them.
|
|
% XXX This check is effectively disabled if the module contains
|
|
% two or more definitions of the field name that this access function
|
|
% is for.
|
|
OoMFieldDefns = one_or_more(FieldDefn, []),
|
|
FieldDefn = hlds_ctor_field_defn(_, DefnStatus, _, _, _),
|
|
DefnStatus = type_status(status_exported),
|
|
FuncStatus \= pred_status(status_exported)
|
|
then
|
|
user_arity_pred_form_arity(pf_function, UserArity, PredFormArity),
|
|
PFSymNameArity =
|
|
pf_sym_name_arity(pf_function, FuncSymName, PredFormArity),
|
|
report_field_status_mismatch(Context, PFSymNameArity, !Specs)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred report_field_status_mismatch(prog_context::in, pf_sym_name_arity::in,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
report_field_status_mismatch(Context, PFSymNameArity, !Specs) :-
|
|
Pieces = [words("In declaration of"),
|
|
unqual_pf_sym_name_pred_form_arity(PFSymNameArity), suffix(":"), nl,
|
|
words("error:")] ++
|
|
color_as_subject(
|
|
[words("a field access function for an exported field")]) ++
|
|
color_as_incorrect([words("must also be exported.")]) ++ [nl],
|
|
% XXX Should we add "to ensure consistency"?
|
|
Spec = spec($pred, severity_error, phase_pt2h, Context, Pieces),
|
|
!:Specs = [Spec | !.Specs].
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module hlds.make_hlds.check_field_access_functions.
|
|
%---------------------------------------------------------------------------%
|