Files
mercury/tests/invalid/user_field_access_decl_override.m
Peter Wang 43d7e737dc Allow duplicate field names in the same module.
Allow the same field name to be used in different types in the same
module. The main motivation is that when defining a subtype it often
makes sense to use the same field names as in the base/super type,
rather than trying to invent unique field names.

compiler/add_type.m:
    Check for duplicate field names within a type only,
    not across the module.

compiler/check_parse_tree_type_defns.m:
    Only report duplicate field names within the same type.

compiler/typecheck.m:
    Make user-supplied declarations for field access functions only
    override automatically generated declarations for the same type
    constructor, e.g. a user declaration ':- func foo ^ f1 = int'
    should not affect 'X ^ f1' for X of type 'bar'.

doc/reference_manual.texi:
    Allow duplicate field names in a module, but not within a type.

    Describe how user-supplied declarations interact with duplicate
    field names.

NEWS:
    Announce change.

tests/invalid/repeated_field_name.err_exp:
    Update expected error messages.

tests/invalid/Mmakefile:
tests/invalid/user_field_access_decl_conflict.err_exp:
tests/invalid/user_field_access_decl_conflict.m:
tests/invalid/user_field_access_decl_override.err_exp:
tests/invalid/user_field_access_decl_override.m:
tests/invalid/user_field_access_decl_override2.err_exp:
tests/invalid/user_field_access_decl_override2.m:
    Add test cases.
2021-05-07 17:07:39 +10:00

59 lines
1.5 KiB
Mathematica

% vim: ts=4 sw=4 ft=mercury
:- module user_field_access_decl_override.
:- interface.
:- type dummy ---> dummy.
:- implementation.
:- type foo(T)
---> foo(
f1 :: int,
f2 :: int
).
% These user-supplied declarations deliberately have looser determinisms
% than automatically generated declarations.
%
:- func foo(T) ^ f1 = int is semidet.
:- func (foo(T) ^ f1 := int) = foo(T) is semidet.
:- func get_foo_f1(foo(T)) = int is det.
get_foo_f1(Foo) = X :-
% The user-declared function declaration should be used instead of
% an automatically generated declaration, so this will be semidet.
X = Foo ^ f1.
:- pred set_foo_f1(int::in, foo(T)::in, foo(T)::out) is det.
set_foo_f1(X, !Foo) :-
% The user-declared function declaration should be used instead of
% an automatically generated declaration, so this will be semidet.
!Foo ^ f1 := X.
%---------------------------------------------------------------------------%
:- type bar
---> bar(
f1 :: int,
f2 :: uint
).
:- func get_bar_f1(bar) = int.
get_bar_f1(Bar) = X :-
% The user-supplied declaration of foo(T) ^ f1
% should not shadow any automatically generated declaration
% of the field access function for the f1 field of bar.
X = Bar ^ f1.
:- pred set_bar_f1(int, bar, bar).
:- mode set_bar_f1(in, in, out) is det.
set_bar_f1(X, !Bar) :-
% Similarly for the field update function.
!Bar ^ f1 := X.