[m-rev.] fix lcc type errors in hlc grades

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Aug 18 02:43:14 AEST 2003


I've attached a simplified test case which demonstrates the compiler
bug that I mentioned earlier in this thread.  The bug only shows up
when you build with intermodule optimization enabled:

	$ mmc --make-opt-int illtyped_compare.m
	Uncaught Mercury exception:
	Software Error: type error in pred call: no matching pred

I think the exception occurs when intermod.m calls
typecheck__resolve_pred_overloading to resolve the comparison
predicate.  That's not suprising; the program is ill-typed,
and typecheck__resolve_pred_overloading is documented to abort
in this sitatuion.  What is suprising is the fact that we got as
far as in the process as writing out the .opt file; we don't do 
that if there are any type errors.  The surprise is that the type
error is not being detected during type checking.

The problem seems to be that for some reason, the unification and
comparison procedures for the foreign type are not being typechecked
during the typecheck pass.

Oh, I see now.  This is related to mixing Mercury type definitions
with `pragma foreign_type' definitions.  When building the
`.opt' file, the unification procedure for this type is just the
default (target-independent) unification procedure for the Mercury
representation, which *is* well-typed.  We do not create a procedure for
the foreign_type's unification procedure.  As a result, the heuristics
in typecheck.m for skipping type checking notice that the unification
procedure is guaranteed to have been generated type-correct,
and therefore don't both type-checking it.

But I'm not sure about the best way to fix it.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
-------------- next part --------------
:- module illtyped_compare.

:- interface.

:- type bar.

:- implementation.
:- type bar ---> bar(bar_rep).

:- type bar_rep ---> bar_rep(int).
:- pragma foreign_type("C", bar_rep, "long")
	where comparison is compare_bar_rep.

:- pred compare_bar_rep(comparison_result::uo, bar::in, bar::in) is det.

compare_bar_rep((=), _, _).


More information about the reviews mailing list