[m-rev.] for review: --inform-incomplete-switch
Julien Fischer
jfischer at opturion.com
Mon Jan 23 11:29:46 AEDT 2017
Hi Zoltan,
On Sun, 22 Jan 2017, Zoltan Somogyi wrote:
> I have now implemented both improvements above, minus the configurability
> of the "how many cons_ids to print maximum", and the diff is ready for
> review, by anyone, though Julien is the logical reviewer.
>
> The two INCOMPLETE* files attached show the messages we get with the
> threshold set at 50 and 60% respectively. These, and printing a maximum of
> 10 cons_ids per message, have cut down the total size of the messages
> a lot.
> Add a new compiler option --inform-incomplete-switch.
>
...
> diff --git a/compiler/det_report.m b/compiler/det_report.m
> index fe3ba65..71989e8 100644
> --- a/compiler/det_report.m
> +++ b/compiler/det_report.m
...
> @@ -969,48 +990,123 @@ det_diagnose_orelse_goals([Goal | Goals], InstMap0, Desired, SwitchContexts0,
> Msgs = Msgs1 ++ Msgs2.
>
> %-----------------------------------------------------------------------------%
> +%
> +% There are two reasons why we may want to report that a switch is incomplete:
> +%
> +% - because the switch is wrapped in a require_complete_switch scope, and
> +% - because the --inform-incomplete-switch option is set.
> +
> + % This type says whether the --inform-incomplete-switch option is set.
> + %
> +:- type maybe_inform_incomplete_switches
> + ---> do_not_inform_incomplete_switches
> + ; inform_incomplete_switches.
> +
> + % This type says which of the above two reasons causes us to report
> + % the given incomplete switch.
> + %
> +:- type why_report_incomplete_switch
> + ---> switch_required_to_be_complete
> + ; inform_incomplete_switch_option.
> +
> + % It is possible for *both* reasons to apply to the same incomplete switch.
> + % In such cases, we want to generate only the error required by the scope,
> + % and not the information message that the option calls for. We process
> + % procedure bodied top down, so we process the scope goal before
s/bodied/bodies/
> + % the switch it wraps, so when we generate an error report for an
> + % incomplete switch, we pass along its details when we process the
> + % goal inside the scope (which may either be the incomplete switch,
> + % or a conjunction of feature_lifted_by_cse deconstruction unifications
> + % followed by the incomplete switch).
> + %
> +:- type reported_switch
> + ---> reported_switch(
> + prog_context,
> + prog_var,
> + list(case)
> + ).
...
> @@ -1376,61 +1573,162 @@ lambda_update_instmap([Var - Mode | VarsModes], ModuleInfo, !InstMap) :-
>
> %-----------------------------------------------------------------------------%
>
> -:- pred find_missing_cons_ids(det_info::in, instmap::in, prog_var::in,
> - list(case)::in, string::out, maybe(list(format_component))::out) is det.
> +:- type missing_cons_id_info
> + ---> missing_cons_id_info(
> + % The number of cons_ids that the switch variable could
> + % be bound to on entry to the switch. May be the number of
> + % function symbols in the variable's type, or it may be
> + % the number of cons_ids that appear in the variable's
> + % initial bound(...) inst.
> + int,
> +
> + % The number of these cons_ids that do NOT occur
> + % in any of the cases.
> + int,
> +
> + % The diagnostic listing the missing cons_ids.
> + %
> + % If there are more missing cons_ids than the
> + % specified limit, we return two different versions
> + % of the error message fragment. The first is the version
> + % to use if the user doesn't want verbose errors,
> + % the second is the version to use if he/she does want them.
> + %
> + % If the number of missing cons_ids is below the limit,
> + % or if the caller did not specify the limit,
> + % the second list will be empty.
> + list(format_component),
> + list(format_component)
> + ).
> +
> +:- pred find_missing_cons_ids(det_info::in, maybe(int)::in, instmap::in,
> + list(switch_context)::in, prog_var::in, list(case)::in,
> + list(format_component)::out, string::out,
> + maybe(missing_cons_id_info)::out) is det.
> +
> +find_missing_cons_ids(DetInfo, MaybeLimit, InstMap0, SwitchContexts,
> + Var, Cases, NestingPieces, VarStr, MaybeMissingInfo) :-
> + det_diagnose_switch_context(DetInfo, SwitchContexts, NestingPieces),
>
> -find_missing_cons_ids(DetInfo, InstMap0, Var, Cases, VarStr,
> - MaybeMissingPieces) :-
> det_get_proc_info(DetInfo, ProcInfo),
> proc_info_get_varset(ProcInfo, VarSet),
> VarStr = mercury_var_to_name_only(VarSet, Var),
> det_info_get_module_info(DetInfo, ModuleInfo),
> + instmap_lookup_var(InstMap0, Var, VarInst),
> ( if
> ( if
> - instmap_lookup_var(InstMap0, Var, VarInst),
> inst_is_bound_to_functors(ModuleInfo, VarInst, BoundInsts)
> then
> det_info_get_vartypes(DetInfo, VarTypes),
> lookup_var_type(VarTypes, Var, VarType),
> type_to_ctor_det(VarType, VarTypeCtor),
> - list.map(bound_inst_to_cons_id(VarTypeCtor),
> - BoundInsts, ConsIds)
> + bound_insts_to_cons_ids(VarTypeCtor, BoundInsts, BoundConsIds),
> + list.sort_and_remove_dups(BoundConsIds, SortedBoundConsIds),
> + set_tree234.sorted_list_to_set(SortedBoundConsIds,
> + BoundConsIdsSet),
> + % Since should insist that all insts used in predicate
Since _we_ should ...
> + % declarations be specific to the type of the arguments
> + % they apply to. However, I (zs) don't think we enforce this
> + % yet with any consistency in the mode checker. The intersection
> + % operation below should compenate for this, but we can invoke it
s/compenate/compensate/
> + % only for the switch variable's type is a du type, and not
> + % a builtin type such as int or string.
> + ( if
> + det_lookup_var_type(ModuleInfo, ProcInfo, Var, TypeDefn),
> + hlds_data.get_type_defn_body(TypeDefn, TypeBody),
> + ConsTable = TypeBody ^ du_type_cons_tag_values
> + then
> + map.keys(ConsTable, SortedTypeConsIds),
> + set_tree234.sorted_list_to_set(SortedTypeConsIds,
> + TypeConsIdsSet),
> + set_tree234.intersect(TypeConsIdsSet, BoundConsIdsSet,
> + PossibleConsIdsSet)
> + else
...
> @@ -1668,6 +1964,7 @@ failing_context_description(ModuleInfo, VarSet, FailingContext) = Msg :-
> FailingGoal = incomplete_switch(Var),
> VarStr = mercury_var_to_name_only(VarSet, Var),
> Pieces = [words("Switch on"), fixed(VarStr), words("is incomplete.")]
> + % ZZZ
> ;
That ZZZ is presumably meaningful to you?
The rest looks fine.
Julien.
More information about the reviews
mailing list