mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-26 23:04:15 +00:00
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.
59 lines
1.5 KiB
Mathematica
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.
|