[m-rev.] for review: Fix abstract equivalence types.
Peter Wang
novalazy at gmail.com
Sun Aug 20 11:21:00 AEST 2017
Fix Mantis bug 411. When an abstract type that is defined as equivalent
to another type is imported into another module, the other module would
see through the equivalence, making the abstract type not abstract at all.
The regression was introduced in commit 2856408ab0fbf74c272a999b9c5c7e269001e3fe
"Separate the different kinds of sections in aug_comp_units."
-build_eqv_maps_in_blocks([], !TypeEqvMap, !InstEqvMap).
-build_eqv_maps_in_blocks([AugItemBlock | AugItemBlocks],
+build_eqv_maps_in_item_blocks([], !TypeEqvMap, !InstEqvMap).
+build_eqv_maps_in_item_blocks([ItemBlock | ItemBlocks],
!TypeEqvMap, !InstEqvMap) :-
- AugItemBlock = item_block(AugSection, _, Items),
- ( if AugSection = ams_abstract_imported(_) then
- true
- else
- build_eqv_maps_in_items(Items, !TypeEqvMap, !InstEqvMap)
- ),
- build_eqv_maps_in_blocks(AugItemBlocks, !TypeEqvMap, !InstEqvMap).
+ ItemBlock = item_block(_Section, _, Items),
+ build_eqv_maps_in_items(Items, !TypeEqvMap, !InstEqvMap),
+ build_eqv_maps_in_item_blocks(ItemBlocks, !TypeEqvMap, !InstEqvMap).
Before the change, items in an abstract-imported item block did not
contribute to the type equivalence maps. After the change, they would,
so abstract types would be replaced by their equivalent types.
Similarly for insts.
compiler/equiv_type.m:
Filter out abstract-imported item blocks from when building the type
and inst equivalence maps.
tests/invalid/Mmakefile:
tests/invalid/abstract_eqv.err_exp:
tests/invalid/abstract_eqv.m:
tests/invalid/abstract_eqv2.m:
Add test case.
---
compiler/equiv_type.m | 21 +++++++++++++++++++--
tests/invalid/Mmakefile | 1 +
tests/invalid/abstract_eqv.err_exp | 6 ++++++
tests/invalid/abstract_eqv.m | 19 +++++++++++++++++++
tests/invalid/abstract_eqv2.m | 19 +++++++++++++++++++
5 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 tests/invalid/abstract_eqv.err_exp
create mode 100644 tests/invalid/abstract_eqv.m
create mode 100644 tests/invalid/abstract_eqv2.m
diff --git a/compiler/equiv_type.m b/compiler/equiv_type.m
index 362e28b..c4723a4 100644
--- a/compiler/equiv_type.m
+++ b/compiler/equiv_type.m
@@ -127,9 +127,13 @@ expand_eqv_types_insts(AugCompUnit0, AugCompUnit, EventSpecMap0, EventSpecMap,
map.init(!:InstEqvMap),
build_eqv_maps_in_item_blocks(SrcItemBlocks0,
!TypeEqvMap, !InstEqvMap),
- build_eqv_maps_in_item_blocks(DirectIntItemBlocks0,
+ list.filter(non_abstract_imported_int_item_block,
+ DirectIntItemBlocks0, NonAbstractDirectIntItemBlocks0),
+ build_eqv_maps_in_item_blocks(NonAbstractDirectIntItemBlocks0,
!TypeEqvMap, !InstEqvMap),
- build_eqv_maps_in_item_blocks(IndirectIntItemBlocks0,
+ list.filter(non_abstract_imported_int_item_block,
+ IndirectIntItemBlocks0, NonAbstractIndirectIntItemBlocks0),
+ build_eqv_maps_in_item_blocks(NonAbstractIndirectIntItemBlocks0,
!TypeEqvMap, !InstEqvMap),
build_eqv_maps_in_item_blocks(IntForOptItemBlocks0,
!TypeEqvMap, !InstEqvMap),
@@ -195,6 +199,19 @@ expand_eqv_types_insts(AugCompUnit0, AugCompUnit, EventSpecMap0, EventSpecMap,
---> type_decl
; mode_decl.
+:- pred non_abstract_imported_int_item_block(
+ item_block(int_module_section)::in) is semidet.
+
+non_abstract_imported_int_item_block(ItemBlock) :-
+ ItemBlock = item_block(Section, _, _, _, _),
+ require_complete_switch [Section]
+ (
+ Section = ims_imported_or_used(_, _, _, _)
+ ;
+ Section = ims_abstract_imported(_, _),
+ fail
+ ).
+
:- pred build_eqv_maps_in_item_blocks(list(item_block(MS))::in,
type_eqv_map::in, type_eqv_map::out,
inst_eqv_map::in, inst_eqv_map::out) is det.
diff --git a/tests/invalid/Mmakefile b/tests/invalid/Mmakefile
index ced2af6..9bf9c0c 100644
--- a/tests/invalid/Mmakefile
+++ b/tests/invalid/Mmakefile
@@ -15,6 +15,7 @@ MAYBE_J1 =
# not be included in this list; we handle those specially (see below).
MULTIMODULE_PROGS= \
+ abstract_eqv \
duplicate_instance_2 \
exported_unify \
exported_unify3 \
diff --git a/tests/invalid/abstract_eqv.err_exp b/tests/invalid/abstract_eqv.err_exp
new file mode 100644
index 0000000..7c6bc7d
--- /dev/null
+++ b/tests/invalid/abstract_eqv.err_exp
@@ -0,0 +1,6 @@
+abstract_eqv.m:016: In clause for predicate `bad'/0:
+abstract_eqv.m:016: in argument 1 of call to predicate
+abstract_eqv.m:016: `abstract_eqv2.call_with_foo'/1:
+abstract_eqv.m:016: type error: argument has type `abstract_eqv2.bar',
+abstract_eqv.m:016: expected type was `abstract_eqv2.foo'.
+For more information, recompile with `-E'.
diff --git a/tests/invalid/abstract_eqv.m b/tests/invalid/abstract_eqv.m
new file mode 100644
index 0000000..5a6751c
--- /dev/null
+++ b/tests/invalid/abstract_eqv.m
@@ -0,0 +1,19 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+%
+% Mantis bug 411. Abstract types should not be replaced by their equivalent
+% types.
+
+:- module abstract_eqv.
+
+:- interface.
+
+:- pred bad is det.
+
+:- implementation.
+
+:- import_module abstract_eqv2.
+
+bad :-
+ call_with_foo(bar(1)).
diff --git a/tests/invalid/abstract_eqv2.m b/tests/invalid/abstract_eqv2.m
new file mode 100644
index 0000000..c1f4916
--- /dev/null
+++ b/tests/invalid/abstract_eqv2.m
@@ -0,0 +1,19 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module abstract_eqv2.
+:- interface.
+
+:- type foo.
+
+:- type bar
+ ---> bar(int).
+
+:- pred call_with_foo(foo::in) is det.
+
+:- implementation.
+
+:- type foo == bar.
+
+call_with_foo(_).
--
2.9.0
More information about the reviews
mailing list