[m-rev.] for review: prepare for two new warnings on instances
Julien Fischer
jfischer at opturion.com
Sat Mar 19 13:58:46 AEDT 2022
Hi Zoltan,
On Sat, 19 Mar 2022, Zoltan Somogyi wrote:
> Prepare to add new warnings about instances.
>
> Prepare for these new options, --warn-unnecessarily-private-instance and
> --warn-inconsistent-instance-order, by
>
> - moving some checks on instance declarations to a point in time
> when the set of instance declarations in the module is complete, and
>
> - adding a new field to instance declarations to record a context needed
> for the second of the above warnings.
>
> compiler/add_class.m
> compiler/check_typeclass.m
> Move some checks on instances from add_class.m, where they have to
> work with incomplete data, to check_typeclass.m, where they have access
> to all instance declarations. The tests moved are
>
> - the test whether the abstract and concrete forms of an instance
> specify the same constraints or not,
> - the test for duplicate concrete instances, and
> - the test for overlapping instances.
>
> The new code can be, and is, much more systematic in looking for
> inconsistencies between instance declarations. For example,
> it distinguishes between duplicate and overlapping instance declarations,
> whereas the old code did not. This allows it to generate more precise
> messages.
>
> We do in fact generate a new warning message, for duplicate abstract
> instance declarations.
>
> Crucially, the new code can also gather the information needed
> for --warn-inconsistent-instance-order, although the gather info
s/gather/gathered/
> is then throw away. This will change soon.
...
> diff --git a/compiler/check_typeclass.m b/compiler/check_typeclass.m
> index cc5da35d9..926a4027c 100644
> --- a/compiler/check_typeclass.m
> +++ b/compiler/check_typeclass.m
...
> +:- pred check_for_missing_concrete_instances_in_class_and_vector(class_id::in,
> + pair(type_vector, type_vector_instances)::in, hlds_instance_defn::out,
> list(error_spec)::in, list(error_spec)::out) is det.
>
> -check_for_corresponding_instances_2(Concretes, ClassId, AbstractInstance,
> - !Specs) :-
> - AbstractTypes = AbstractInstance ^ instdefn_types,
> - ( if multi_map.search(Concretes, ClassId, ConcreteInstances) then
> - ( if
> - list.member(ConcreteInstance, ConcreteInstances),
> - ConcreteTypes = ConcreteInstance ^ instdefn_types,
> - ConcreteTypes = AbstractTypes
> - then
> - MissingConcreteError = no
> - else
> - % There were concrete instances for ClassId in the implementation
> - % but none of them matches the abstract instance we have.
> - MissingConcreteError = yes
> - )
> +check_for_missing_concrete_instances_in_class_and_vector(ClassId,
> + _TypeVector - VectorInstances, PickedInstance, !Specs) :-
> + % XXX We should use _TypeVector to implement the check
> + % now done by check_instance_declaration_types_for_instance.
> + %
> + % XXX We should also use it to implement --warn-unnecessarily-private-
> + % instance, which (as proposed by Julien on 2022 mar 8) would warn about
> + % non-exported instances whose type vectors contain only imported
> + % type constructors.
See below.
> diff --git a/compiler/options.m b/compiler/options.m
> index ceb058379..77b23ce26 100644
> --- a/compiler/options.m
> +++ b/compiler/options.m
> @@ -193,6 +193,8 @@
> ; warn_missing_opt_files
> ; warn_missing_trans_opt_files
> ; warn_missing_trans_opt_deps
> + ; warn_unnecessarily_private_instance
> + ; warn_inconsistent_instance_order
> ; warn_inconsistent_pred_order_clauses
> ; warn_inconsistent_pred_order_foreign_procs
> ; warn_non_contiguous_decls
> @@ -1238,6 +1240,8 @@ optdef(oc_warn, warn_nothing_exported, bool(yes)).
> optdef(oc_warn, warn_unused_args, bool(no)).
> optdef(oc_warn, warn_interface_imports, bool(yes)).
> optdef(oc_warn, warn_interface_imports_in_parents, bool(no)).
> +optdef(oc_warn, warn_unnecessarily_private_instance, bool(no)).
> +optdef(oc_warn, warn_inconsistent_instance_order, bool(no)).
> optdef(oc_warn, warn_inconsistent_pred_order_clauses, bool(no)).
> optdef(oc_warn, warn_inconsistent_pred_order_foreign_procs, bool(no)).
> optdef(oc_warn, warn_non_contiguous_decls, bool(yes)).
> @@ -2135,6 +2139,10 @@ long_option("warn-unused-args", warn_unused_args).
> long_option("warn-interface-imports", warn_interface_imports).
> long_option("warn-interface-imports-in-parents",
> warn_interface_imports_in_parents).
> +long_option("warn-unnecessarily-private-instance",
> + warn_unnecessarily_private_instance).
> +long_option("warn-inconsistent-instance-order",
> + warn_inconsistent_instance_order).
> long_option("warn-inconsistent-pred-order",
> warn_inconsistent_pred_order_clauses).
> long_option("warn-inconsistent-pred-order-clauses",
> @@ -4268,6 +4276,19 @@ options_help_warning(Stream, !IO) :-
> "\tto allow `.trans_opt' files to be read when creating other",
> "\t`.trans_opt' files has been lost. The information can be",
> "\trecreated by running `mmake <mainmodule>.depend'",
> +long_option("warn-unnecessarily-private-instance",
> +long_option("warn-inconsistent-instance-order",
> + "--warn-unnecessarily-private-instance",
> + "\tGenerate a warning if an instance declaration is not exported",
> + "\teven though none of the type constructors mentioned in the",
> + % XXX Should this be like this (what Julien proposed)
> + "\tmember types are defined in the current module.",
> + % XXX or like this (my preference)?
> + "\tmember types are local to the current module.",
> + "--warn-inconsistent-instance-order",
> + "\tGenerate a warning if the order of concrete instance declarations",
> + "\tdoes not match the order of the corresponding abstract",
> + "\tdeclarations.",
What I said on the mailing list was "non-local" types, which is a bit
ambiguous; I probably should have said was "non-private".
You should get the warning if a module has a non-exported type class instance
whose type vector consists only of (a) imported types** or (b) types exported
in the interface of the _current_ module.
Should we get the warning if there are any class constraints on the
instance that refer to private type classes?
** Types imported from private submodules are not non-private so should not
trigger the warning.
The diff looks fine.
Julien.
More information about the reviews
mailing list