[m-rev.] for review: check that abstract type declarations have definitions
Julien Fischer
juliensf at cs.mu.OZ.AU
Fri Apr 22 10:46:39 AEST 2005
Estimated hours taken: 10
Branches: main, release
Check that abstract type declarations do actually have a
corresponding definition somewhere in the module. Emit
an error message if an abstract type declarations does not
have a corresponding definition.
compiler/post_typecheck.m:
Check that abstract type declarations have a corresponding
definition somewhere in the module. Emit an error message
if they do not.
compiler/gcc.m:
Comment an abstract type declaration that does not have
a corresponding definition.
compiler/typecheck.m:
Module qualify the names of predicates in the error message
about predicates have no clauses.
tests/invalid/Mmakefile:
tests/invalid/type_with_no_defn.m:
tests/invalid/type_with_no_defn.err_exp:
Add a test case for the above.
tests/invalid/*:
Update test cases and expected error outputs as
necessary.
Julien.
Workspace:/home/swordfish/juliensf/ws75
Index: compiler/gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/gcc.m,v
retrieving revision 1.32
diff -u -r1.32 gcc.m
--- compiler/gcc.m 24 Mar 2005 02:00:25 -0000 1.32
+++ compiler/gcc.m 21 Apr 2005 08:18:14 -0000
@@ -184,7 +184,10 @@
%
% A GCC `tree' representing a declaration.
-:- type gcc__decl.
+% XXX This doesn't have a definition and appears to be unused anyway.
+% - juliensf
+%
+%:- type gcc__decl.
%
% Stuff for variable declarations
Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/post_typecheck.m,v
retrieving revision 1.72
diff -u -r1.72 post_typecheck.m
--- compiler/post_typecheck.m 1 Apr 2005 14:28:59 -0000 1.72
+++ compiler/post_typecheck.m 21 Apr 2005 08:20:26 -0000
@@ -21,6 +21,8 @@
% - it reports errors for unsatisfied type class constraints
% - it reports an error if there are indistinguishable modes for
% a predicate of function.
+% - it checks that declarations for abstract types also have a
+% corresponding definition somewhere in the module.
%
% These actions cannot be done until after type inference is complete,
% so they need to be a separate "post-typecheck pass". For efficiency
@@ -118,6 +120,7 @@
hlds_goal::out) is det.
%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
:- implementation.
@@ -147,7 +150,6 @@
:- import_module require.
:- import_module set.
:- import_module string.
-:- import_module term.
:- import_module varset.
%-----------------------------------------------------------------------------%
@@ -155,7 +157,10 @@
post_typecheck__finish_preds(PredIds, ReportTypeErrors, NumErrors,
FoundTypeError, !ModuleInfo, !IO) :-
post_typecheck__finish_preds(PredIds, ReportTypeErrors,
- !ModuleInfo, 0, NumErrors, no, FoundTypeError, !IO).
+ !ModuleInfo, 0, NumErrors0, no, FoundTypeError0, !IO),
+ check_for_missing_definitions(!.ModuleInfo,
+ NumErrors0, NumErrors, FoundTypeError0, FoundTypeError,
+ !IO).
:- pred post_typecheck__finish_preds(list(pred_id)::in, bool::in,
module_info::in, module_info::out, int::in, int::out,
@@ -1651,4 +1656,80 @@
map__det_insert(!.VarTypes, Var, Type, !:VarTypes).
%-----------------------------------------------------------------------------%
+%
+% Check that every abstract type in a module has at least one definition
+% in either the interface or implementation of the module. A type may
+% have several definitions, e.g. some foreign definitions and a default
+% Mercury definition.
+%
+
+:- pred check_for_missing_definitions(module_info::in,
+ int::in, int::out, bool::in, bool::out, io::di, io::uo) is det.
+
+check_for_missing_definitions(ModuleInfo, !NumErrors, !FoundTypeError,
+ !IO) :-
+ module_info_types(ModuleInfo, TypeTable),
+ map.foldl3(check_for_missing_definitions_2, TypeTable,
+ !NumErrors, !FoundTypeError, !IO).
+
+:- pred check_for_missing_definitions_2(type_ctor::in, hlds_type_defn::in,
+ int::in, int::out, bool::in, bool::out, io::di, io::uo) is det.
+
+check_for_missing_definitions_2(TypeCtor, TypeDefn, !NumErrors,
+ !FoundTypeError, !IO) :-
+ (
+ get_type_defn_status(TypeDefn, ImportStatus),
+ status_defined_in_this_module(ImportStatus, LocalDefn),
+ LocalDefn = yes,
+ get_type_defn_body(TypeDefn, TypeBody),
+ TypeBody = abstract_type(_)
+ ->
+ % We expect builtin types character, float, int and
+ % string to have abstract declarations with no
+ % definitions. The following types from the type_desc
+ % module also only have abstract declarations:
+ %
+ % - type_desc/0
+ % - pseudo_type_desc/0
+ % - type_ctor_desc/0
+ %
+ % We do not emit an error for these types. In addition,
+ % we also don't bother checking for corresponding
+ % definitions in any of the builtin modules in the
+ % standard library.
+ %
+ TypeCtor = SymName - Arity,
+ BuiltinTypeCtors = builtin_type_ctors_with_no_hlds_type_defn,
+ (
+ sym_name_get_module_name(SymName, ModuleName),
+ not any_mercury_builtin_module(ModuleName),
+ %
+ % Several of the type defined in type_desc do not
+ % have Mercury definitions.
+ %
+ not ModuleName = unqualified("type_desc"),
+ not list.member(TypeCtor, BuiltinTypeCtors)
+ ->
+ ErrorPieces = [
+ words("Error: abstract"),
+ words("declaration for type"),
+ sym_name_and_arity(SymName / Arity),
+ words("has no corresponding"),
+ words("definition.")
+ ],
+ get_type_defn_context(TypeDefn, TypeContext),
+ write_error_pieces(TypeContext, 0,
+ ErrorPieces, !IO),
+ io.set_exit_status(1, !IO),
+ !:FoundTypeError = yes,
+ !:NumErrors = !.NumErrors + 1
+ ;
+ true
+ )
+ ;
+ true
+ ).
+
+%-----------------------------------------------------------------------------%
+:- end_module post_typecheck.
%-----------------------------------------------------------------------------%
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.370
diff -u -r1.370 typecheck.m
--- compiler/typecheck.m 20 Apr 2005 12:57:17 -0000 1.370
+++ compiler/typecheck.m 22 Apr 2005 00:24:38 -0000
@@ -5157,7 +5157,7 @@
report_no_clauses(MessageKind, PredId, PredInfo, ModuleInfo, !IO) :-
pred_info_context(PredInfo, Context),
PredPieces = describe_one_pred_name(ModuleInfo,
- should_not_module_qualify, PredId),
+ should_module_qualify, PredId),
ErrorMsg = [words(MessageKind ++ ": no clauses for ") | PredPieces] ++
[suffix(".")],
error_util__write_error_pieces(Context, 0, ErrorMsg, !IO).
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.165
diff -u -r1.165 Mmakefile
--- tests/invalid/Mmakefile 20 Apr 2005 12:57:44 -0000 1.165
+++ tests/invalid/Mmakefile 20 Apr 2005 23:26:53 -0000
@@ -169,6 +169,7 @@
type_mismatch \
types \
type_vars \
+ type_with_no_defn \
unbound_type_vars \
undeclared_mode \
undef_inst \
Index: tests/invalid/import_in_parent.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/import_in_parent.err_exp,v
retrieving revision 1.2
diff -u -r1.2 import_in_parent.err_exp
--- tests/invalid/import_in_parent.err_exp 17 Jan 2003 05:57:08 -0000 1.2
+++ tests/invalid/import_in_parent.err_exp 21 Apr 2005 06:43:58 -0000
@@ -1,3 +1,3 @@
-import_in_parent.m:019: In clause for predicate `import_in_parent.sub.foo/1':
-import_in_parent.m:019: error: undefined predicate `bool.foo/1'.
+import_in_parent.m:021: In clause for predicate `import_in_parent.sub.foo/1':
+import_in_parent.m:021: error: undefined predicate `bool.foo/1'.
For more information, try recompiling with `-E'.
Index: tests/invalid/import_in_parent.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/import_in_parent.m,v
retrieving revision 1.1
diff -u -r1.1 import_in_parent.m
--- tests/invalid/import_in_parent.m 24 Oct 2002 04:36:57 -0000 1.1
+++ tests/invalid/import_in_parent.m 21 Apr 2005 06:43:13 -0000
@@ -8,6 +8,8 @@
:- implementation.
+ :- type foo ---> foo.
+
:- module import_in_parent__sub.
:- interface.
Index: tests/invalid/modes_erroneous.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/modes_erroneous.err_exp,v
retrieving revision 1.5
diff -u -r1.5 modes_erroneous.err_exp
--- tests/invalid/modes_erroneous.err_exp 23 Aug 2004 09:53:13 -0000 1.5
+++ tests/invalid/modes_erroneous.err_exp 21 Apr 2005 06:42:35 -0000
@@ -1,7 +1,5 @@
-modes_erroneous.m:001: Warning: interface for module `modes_erroneous' does not
-modes_erroneous.m:001: export anything.
-modes_erroneous.m:009: In clause for `p((ground >> ground), (free >> ground))':
-modes_erroneous.m:009: in argument 1 of call to predicate `modes_erroneous.p/2':
-modes_erroneous.m:009: mode error: variable `V_5' has instantiatedness `free',
-modes_erroneous.m:009: expected instantiatedness was `ground'.
+modes_erroneous.m:015: In clause for `p((ground >> ground), (free >> ground))':
+modes_erroneous.m:015: in argument 1 of call to predicate `modes_erroneous.p/2':
+modes_erroneous.m:015: mode error: variable `V_5' has instantiatedness `free',
+modes_erroneous.m:015: expected instantiatedness was `ground'.
For more information, try recompiling with `-E'.
Index: tests/invalid/modes_erroneous.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/modes_erroneous.m,v
retrieving revision 1.2
diff -u -r1.2 modes_erroneous.m
--- tests/invalid/modes_erroneous.m 25 Aug 2004 08:21:29 -0000 1.2
+++ tests/invalid/modes_erroneous.m 21 Apr 2005 06:42:06 -0000
@@ -1,10 +1,17 @@
:- module modes_erroneous.
+:- interface.
+
:- type foo.
+:- implementation.
+
+:- type foo ---> foo.
+
:- pred p(foo, foo).
:- mode p(ground >> ground, free >> ground).
p(_, X) :-
p(_, X).
p(_, _).
+
Index: tests/invalid/type_spec.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/type_spec.m,v
retrieving revision 1.2
diff -u -r1.2 type_spec.m
--- tests/invalid/type_spec.m 3 Oct 1999 04:17:29 -0000 1.2
+++ tests/invalid/type_spec.m 21 Apr 2005 06:32:59 -0000
@@ -26,3 +26,8 @@
:- pragma type_spec(type_spec2/1, U = list(U)).
:- pragma type_spec(type_spec2/1, (U = int, U = list(int))).
+
+:- implementation.
+
+:- type the_type(T, U) ---> type_type(T, U).
+
Index: tests/invalid/type_with_no_defn.err_exp
===================================================================
RCS file: tests/invalid/type_with_no_defn.err_exp
diff -N tests/invalid/type_with_no_defn.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/type_with_no_defn.err_exp 21 Apr 2005 07:01:03 -0000
@@ -0,0 +1,7 @@
+type_with_no_defn.m:005: Error: abstract declaration for type
+type_with_no_defn.m:005: `type_with_no_defn.alpha'/0 has no corresponding
+type_with_no_defn.m:005: definition.
+type_with_no_defn.m:013: Error: abstract declaration for type
+type_with_no_defn.m:013: `type_with_no_defn.baz'/0 has no corresponding
+type_with_no_defn.m:013: definition.
+For more information, try recompiling with `-E'.
Index: tests/invalid/type_with_no_defn.m
===================================================================
RCS file: tests/invalid/type_with_no_defn.m
diff -N tests/invalid/type_with_no_defn.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/type_with_no_defn.m 21 Apr 2005 07:00:34 -0000
@@ -0,0 +1,19 @@
+:- module type_with_no_defn.
+
+:- interface.
+
+:- type alpha.
+
+:- type beta == int.
+
+:- type gamma.
+
+:- implementation.
+
+:- type baz. % This is redundant but we allow it.
+
+:- type beta.
+
+:- type gamma == float.
+
+:- type delta == string.
Index: tests/invalid/typeclass_missing_det.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/typeclass_missing_det.m,v
retrieving revision 1.1
diff -u -r1.1 typeclass_missing_det.m
--- tests/invalid/typeclass_missing_det.m 29 Apr 2001 07:54:37 -0000 1.1
+++ tests/invalid/typeclass_missing_det.m 21 Apr 2005 06:44:39 -0000
@@ -9,3 +9,5 @@
:- typeclass c(T) where [
pred p(T::in) % error -- missing det declaration for p/1
].
+
+:- type dummy ---> dummy.
Index: tests/invalid/typeclass_missing_det_2.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/typeclass_missing_det_2.m,v
retrieving revision 1.1
diff -u -r1.1 typeclass_missing_det_2.m
--- tests/invalid/typeclass_missing_det_2.m 29 Apr 2001 07:54:37 -0000 1.1
+++ tests/invalid/typeclass_missing_det_2.m 21 Apr 2005 06:47:17 -0000
@@ -10,3 +10,5 @@
pred p(T),
mode p(in) % error -- missing det declaration for p/1
].
+
+:- type dummy ---> dummy.
Index: tests/invalid/types.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/types.err_exp,v
retrieving revision 1.10
diff -u -r1.10 types.err_exp
--- tests/invalid/types.err_exp 17 Jan 2003 05:57:10 -0000 1.10
+++ tests/invalid/types.err_exp 22 Apr 2005 00:31:02 -0000
@@ -1,4 +1,4 @@
-types.m: 1: Warning: interface for module `types' does not export anything.
+types.m:001: Warning: interface for module `types' does not export anything.
types.m:003: Error: constructor `types.a/0' for type `types.t/0' multiply defined.
types.m:003: Error: constructor `types.f/1' for type `types.t/0' multiply defined.
types.m:017: Error: clause for predicate `types.r/0'
@@ -25,6 +25,6 @@
types.m:018: error: undefined predicate `s/0'.
types.m:020: In clause for predicate `types.a/1':
types.m:020: error: undefined predicate `b/1'.
-types.m:042: Error: no mode declaration for predicate `types.baz/1'.
-types.m:052: Error: no mode declaration for predicate `types.baz2/1'.
+types.m:048: Error: abstract declaration for type `types.t'/2 has no
+types.m:048: corresponding definition.
For more information, try recompiling with `-E'.
Index: tests/invalid/uu_type.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/uu_type.err_exp,v
retrieving revision 1.3
diff -u -r1.3 uu_type.err_exp
--- tests/invalid/uu_type.err_exp 26 Feb 2002 02:46:05 -0000 1.3
+++ tests/invalid/uu_type.err_exp 21 Apr 2005 06:34:45 -0000
@@ -1,2 +1,4 @@
uu_type.m:022: Error: type parameters must be variables: hiddenrenamedtype = hiddentype.
+uu_type.m:012: Error: abstract declaration for type
+uu_type.m:012: `uu_type.hiddenrenamedtype'/0 has no corresponding definition.
For more information, try recompiling with `-E'.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list