mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-24 22:04:13 +00:00
Estimated hours taken: 6
Allow class methods to be impure or semipure. Previously any purity annotation
on a class method was ignored, and the method assumed to be pure. (We have
for some time caught the case of providing an impure implementation for
a (pure) class method, though).
compiler/prog_data.m:
Add purity to the information we store about each method.
compiler/prog_io_typeclass.m:
Record the declared purity of each method.
compiler/make_hlds.m:
For the predicate we generate corresponding to a method, add any
purity annotations that the method has.
compiler/check_typeclass.m:
Add the appropriate impurity marker to the predicate we generate for
each instance method.
compiler/purity.m:
Be careful not to spit out spurious purity warnings:
- Never warn about excessive impurity for a class methods.
(The body of the method is just class_method_call, which
never looks impure as far as it is concerned).
- Never warn about excessive impurity for class instance
method. The fact that a method is impure doesn't mean that
its instances need to be impure, and it would be excessive
to warn about it, seeing that there is no way for the user
to avoid it (other than actually making their implementation
impure...).
compiler/mercury_to_mercury.m:
Print out method purity in interface files.
compiler/module_qual.m:
compiler/equiv_type.m:
Handle the fact that we now store purity info for class methods.
tests/hard_coded/typeclasses/impure_methods.{m,exp}:
A test case for this change.
tests/hard_coded/typeclasses/Mmakefile:
Turn this change on.
tests/invalid/impure_method_impl.{m,err_exp}:
A test case for invalid use of impurity and class methods
tests/invalid/Mmakefile:
Turn this change on.
33 lines
645 B
Mathematica
33 lines
645 B
Mathematica
:- module impure_method_impl.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io__state::di, io__state::uo) is det.
|
|
|
|
:- typeclass c(T) where [
|
|
pred m1(T::in, int::out) is det,
|
|
semipure pred m2(T::in, int::out) is det
|
|
].
|
|
|
|
:- type foo ---> foo.
|
|
|
|
:- instance c(foo) where [
|
|
pred(m1/2) is foo_m1,
|
|
pred(m2/2) is foo_m2
|
|
].
|
|
|
|
:- semipure pred foo_m1(foo::in, int::out) is det.
|
|
:- impure pred foo_m2(foo::in, int::out) is det.
|
|
|
|
:- implementation.
|
|
|
|
main -->
|
|
[].
|
|
|
|
:- pragma c_header_code("int foo_counter = 0;").
|
|
|
|
:- pragma c_code(foo_m1(_F::in, Val::out), "Val = foo_counter;").
|
|
:- pragma c_code(foo_m2(_F::in, Val::out), "Val = foo_counter++;").
|
|
|