diff --git a/NEWS.md b/NEWS.md index c9a0c3a29..5f7781873 100644 --- a/NEWS.md +++ b/NEWS.md @@ -822,6 +822,8 @@ Changes to the Mercury standard library - func `all_ucount/1` - pred `all_ucount/2` - func `get_values_for_key/2` + - func `to_sorted_assoc_list/1` + - pred `to_sorted_assoc_list/2` - func `ucount/1` - pred `ucount/2` diff --git a/compiler/hlds_error_util.m b/compiler/hlds_error_util.m index c8e7ccbbb..5f9b98f9a 100644 --- a/compiler/hlds_error_util.m +++ b/compiler/hlds_error_util.m @@ -466,7 +466,7 @@ describe_one_proc_name_pred_info_maybe_argmodes(PredInfo, Lang, MaybeColor, % front by polymorphism.m - we only want the last `PredFormArity' % of them. list.det_drop(NumExtraArgs, ArgModes0, ArgModes), - strip_module_names_from_mode_list(strip_builtin_module_name, + strip_module_names_from_mode_list(strip_all_module_names, set_default_func, ArgModes, StrippedArgModes0), strip_typed_insts_from_mode_list(StrippedArgModes0, StrippedArgModes), proc_info_get_inst_varset(ProcInfo, InstVarSet), diff --git a/compiler/polymorphism_type_class_info.m b/compiler/polymorphism_type_class_info.m index 994e8f0ff..cdbcbb3c1 100644 --- a/compiler/polymorphism_type_class_info.m +++ b/compiler/polymorphism_type_class_info.m @@ -310,8 +310,9 @@ get_or_make_typeclass_info_from_proof_subclass(ExistQVars, Context, Seen, list.det_index1(OtherArgs, Index, SelectedArg), SelectedArg = csa_const_struct(SelectedConstNum) then - materialize_typeclass_info_var(Constraint, SelectedConstNum, - TypeClassInfoVar, MaybeConsId, Goals, !Info), + materialize_typeclass_info_var(Context, Constraint, + SelectedConstNum, TypeClassInfoVar, MaybeConsId, + Goals, !Info), TypeClassInfoVarMCA = TypeClassInfoVar - yes(SelectedArg), record_constructed_typeclass_info_var("subclass constant", do_not_dump_all_tables, -1, Constraint, @@ -425,7 +426,7 @@ get_or_make_typeclass_info_from_proof_instance(ExistQVars, Context, Seen, search_for_constant_instance(ConstStructDb0, ConstInstanceId, InstanceIdConstNum) then - materialize_typeclass_info_var(Constraint, InstanceIdConstNum, + materialize_typeclass_info_var(Context, Constraint, InstanceIdConstNum, TypeClassInfoVar, MaybeConsId, Goals, !Info), CSA = csa_const_struct(InstanceIdConstNum), TypeClassInfoVarMCA = TypeClassInfoVar - yes(CSA), @@ -564,7 +565,8 @@ make_typeclass_info_from_proof_instance(ExistQVars, Context, instance_id(InstanceNum), InstanceTypes, BaseConsId), materialize_base_typeclass_info_var(Constraint, BaseConsId, BaseVar, BaseGoals, !Info), - construct_typeclass_info(Constraint, BaseVar, BaseConsId, ArgVarsMCAs, + construct_typeclass_info(Context, Constraint, + BaseVar, BaseConsId, ArgVarsMCAs, InitialVarMapsSnapshot, TypeClassInfoVar, TypeClassInfoMCA, BaseGoals ++ PrevGoals, Goals, !Info), TypeClassInfoVarMCA = TypeClassInfoVar - TypeClassInfoMCA, @@ -630,14 +632,14 @@ make_const_or_var_arg(Var - MCA, ConstOrVarArg) :- %---------------------------------------------------------------------------% -:- pred construct_typeclass_info(prog_constraint::in, +:- pred construct_typeclass_info(prog_context::in, prog_constraint::in, prog_var::in, cons_id::in, assoc_list(prog_var, maybe(const_struct_arg))::in, var_maps::in, prog_var::out, maybe(const_struct_arg)::out, list(hlds_goal)::in, list(hlds_goal)::out, poly_info::in, poly_info::out) is det. -construct_typeclass_info(Constraint, BaseVar, BaseConsId, ArgVarsMCAs, +construct_typeclass_info(Context, Constraint, BaseVar, BaseConsId, ArgVarsMCAs, InitialVarMapsSnapshot, TypeClassInfoVar, TypeClassInfoMCA, PrevGoals, AllGoals, !Info) :- % Build a unification to add the argvars to the base_typeclass_info. @@ -688,18 +690,15 @@ construct_typeclass_info(Constraint, BaseVar, BaseConsId, ArgVarsMCAs, Unification, UnifyContext), % Create a goal_info for the unification. - goal_info_init(GoalInfo0), NonLocals = set_of_var.make_singleton(TypeClassInfoVar), - goal_info_set_nonlocals(NonLocals, GoalInfo0, GoalInfo1), % Note that we could perhaps be more accurate than `ground(shared)', % but it shouldn't make any difference. TypeClassInfoInst = bound(shared, inst_test_results_fgtc, [bound_functor(ConsId, [])]), TypeClassInfoVarInst = TypeClassInfoVar - TypeClassInfoInst, InstMapDelta = instmap_delta_from_assoc_list([TypeClassInfoVarInst]), - goal_info_set_instmap_delta(InstMapDelta, GoalInfo1, GoalInfo2), - goal_info_set_determinism(detism_det, GoalInfo2, GoalInfo), - + goal_info_init(NonLocals, InstMapDelta, detism_erroneous, + purity_pure, Context, GoalInfo), Goal = hlds_goal(GoalExpr, GoalInfo), % XXX reset varset and vartypes AllGoals = [Goal] @@ -726,9 +725,7 @@ construct_typeclass_info(Constraint, BaseVar, BaseConsId, ArgVarsMCAs, Unification, UnifyContext), % Create a goal_info for the unification. - goal_info_init(GoalInfo0), set_of_var.list_to_set([TypeClassInfoVar | AllArgVars], NonLocals), - goal_info_set_nonlocals(NonLocals, GoalInfo0, GoalInfo1), list.duplicate(NumArgs, Ground, ArgInsts), % Note that we could perhaps be more accurate than `ground(shared)', % but it shouldn't make any difference. @@ -744,8 +741,8 @@ construct_typeclass_info(Constraint, BaseVar, BaseConsId, ArgVarsMCAs, [bound_functor(InstConsId, ArgInsts)]), TypeClassInfoVarInst = TypeClassInfoVar - TypeClassInfoInst, InstMapDelta = instmap_delta_from_assoc_list([TypeClassInfoVarInst]), - goal_info_set_instmap_delta(InstMapDelta, GoalInfo1, GoalInfo2), - goal_info_set_determinism(detism_det, GoalInfo2, GoalInfo), + goal_info_init(NonLocals, InstMapDelta, detism_det, purity_pure, + Context, GoalInfo), Goal = hlds_goal(GoalExpr, GoalInfo), AllGoals = PrevGoals ++ [Goal] @@ -1006,17 +1003,17 @@ materialize_base_typeclass_info_var(Constraint, ConsId, Var, Goals, !Info) :- % Create the rest of the unification goal. NonLocals = set_of_var.make_singleton(Var), - InstmapDelta = instmap_delta_bind_var(Var), - goal_info_init(NonLocals, InstmapDelta, detism_det, purity_pure, + InstMapDelta = instmap_delta_bind_var(Var), + goal_info_init(NonLocals, InstMapDelta, detism_det, purity_pure, GoalInfo), Goal = hlds_goal(Unify, GoalInfo), Goals = [Goal]. -:- pred materialize_typeclass_info_var(prog_constraint::in, int::in, - prog_var::out, maybe(cons_id)::out, list(hlds_goal)::out, +:- pred materialize_typeclass_info_var(prog_context::in, prog_constraint::in, + int::in, prog_var::out, maybe(cons_id)::out, list(hlds_goal)::out, poly_info::in, poly_info::out) is det. -materialize_typeclass_info_var(Constraint, InstanceIdConstNum, +materialize_typeclass_info_var(Context, Constraint, InstanceIdConstNum, Var, MaybeConsId, Goals, !Info) :- poly_info_get_const_struct_var_map(!.Info, ConstStructVarMap0), InstanceIdConstArg = csa_const_struct(InstanceIdConstNum), @@ -1048,9 +1045,9 @@ materialize_typeclass_info_var(Constraint, InstanceIdConstNum, % Create a goal_info for the unification. NonLocals = set_of_var.make_singleton(Var), - InstmapDelta = instmap_delta_bind_var(Var), - goal_info_init(NonLocals, InstmapDelta, detism_det, purity_pure, - GoalInfo), + InstMapDelta = instmap_delta_bind_var(Var), + goal_info_init(NonLocals, InstMapDelta, detism_det, purity_pure, + Context, GoalInfo), Goal = hlds_goal(GoalExpr, GoalInfo), Goals = [Goal] ). diff --git a/compiler/simplify_proc.m b/compiler/simplify_proc.m index b68dee65e..374179685 100644 --- a/compiler/simplify_proc.m +++ b/compiler/simplify_proc.m @@ -127,9 +127,11 @@ :- import_module int. :- import_module map. :- import_module multi_map. +:- import_module pair. :- import_module require. :- import_module set. :- import_module string. +:- import_module term_context. :- import_module varset. %---------------------------------------------------------------------------% @@ -522,8 +524,8 @@ check_typeclass_records(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, proc_info_get_goal(ProcInfo, Goal), look_for_typeclass_info_conflict_in_goal(DupTCIVars, DupTCIVarsToConstraintMap, InstMap0, Goal, - multi_map.init, _, set.init, ConflictConstraints), - ( if set.is_empty(ConflictConstraints) then + multi_map.init, _, multi_map.init, ConflictConstraints), + ( if multi_map.is_empty(ConflictConstraints) then true else report_typeclass_info_problem(ModuleInfo, PredId, ProcId, @@ -532,7 +534,11 @@ check_typeclass_records(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, ) ). -:- type conflict_constraints == set(prog_constraint). +:- type constraint_tci_db == multi_map(prog_constraint, constraint_tci). +:- type constraint_tci + ---> constraint_tci(prog_var, prog_context). + +:- type conflict_constraints == constraint_tci_db. % Look for branched goals in which two different branches % produce typeclass_infos for the same constraint. @@ -550,8 +556,7 @@ check_typeclass_records(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, % :- pred look_for_typeclass_info_conflict_in_goal(set_of_progvar::in, map(prog_var, prog_constraint)::in, instmap::in, hlds_goal::in, - multi_map(prog_constraint, prog_var)::in, - multi_map(prog_constraint, prog_var)::out, + constraint_tci_db::in, constraint_tci_db::out, conflict_constraints::in, conflict_constraints::out) is det. look_for_typeclass_info_conflict_in_goal(DupTCIVars, TCIVarToConstraintMap, @@ -567,8 +572,11 @@ look_for_typeclass_info_conflict_in_goal(DupTCIVars, TCIVarToConstraintMap, instmap_delta_changed_vars(InstMapDelta, ChangedVars), set_of_var.intersect(DupTCIVars, ChangedVars, ChangedDupTCIVars), ( if set_of_var.is_non_empty(ChangedDupTCIVars) then + Context = goal_info_get_context(GoalInfo), set_of_var.to_sorted_list(ChangedDupTCIVars, ChangedDupTCIVarList), - list.foldl(record_delta_typeclass_info_var(TCIVarToConstraintMap), + list.foldl( + record_delta_typeclass_info_var(TCIVarToConstraintMap, + Context), ChangedDupTCIVarList, !TCIConstraints) else true @@ -648,21 +656,20 @@ look_for_typeclass_info_conflict_in_goal(DupTCIVars, TCIVarToConstraintMap, ). :- pred record_delta_typeclass_info_var(map(prog_var, prog_constraint)::in, - prog_var::in, - multi_map(prog_constraint, prog_var)::in, - multi_map(prog_constraint, prog_var)::out) is det. + prog_context::in, prog_var::in, + constraint_tci_db::in, constraint_tci_db::out) is det. -record_delta_typeclass_info_var(TCIVarToConstraintMap, TCIVar, +record_delta_typeclass_info_var(TCIVarToConstraintMap, Context, TCIVar, !TCIConstraints) :- map.lookup(TCIVarToConstraintMap, TCIVar, Constraint), - multi_map.add(Constraint, TCIVar, !TCIConstraints). + ConstraintTCI = constraint_tci(TCIVar, Context), + multi_map.add(Constraint, ConstraintTCI, !TCIConstraints). %---------------------% :- pred look_for_typeclass_info_conflict_in_plain_conj(set_of_progvar::in, map(prog_var, prog_constraint)::in, instmap::in, list(hlds_goal)::in, - multi_map(prog_constraint, prog_var)::in, - multi_map(prog_constraint, prog_var)::out, + constraint_tci_db::in, constraint_tci_db::out, conflict_constraints::in, conflict_constraints::out) is det. look_for_typeclass_info_conflict_in_plain_conj(_, _, _, [], @@ -681,8 +688,7 @@ look_for_typeclass_info_conflict_in_plain_conj(DupTCIVars, :- pred look_for_typeclass_info_conflict_in_disj(set_of_progvar::in, map(prog_var, prog_constraint)::in, instmap::in, list(hlds_goal)::in, - multi_map(prog_constraint, prog_var)::in, - multi_map(prog_constraint, prog_var)::out, + constraint_tci_db::in, constraint_tci_db::out, conflict_constraints::in, conflict_constraints::out) is det. look_for_typeclass_info_conflict_in_disj(DupTCIVars, TCIVarToConstraintMap, @@ -695,7 +701,7 @@ look_for_typeclass_info_conflict_in_disj(DupTCIVars, TCIVarToConstraintMap, :- pred look_for_typeclass_info_conflict_in_disjuncts(set_of_progvar::in, map(prog_var, prog_constraint)::in, instmap::in, list(hlds_goal)::in, - list(multi_map(prog_constraint, prog_var))::out, + list(constraint_tci_db)::out, conflict_constraints::in, conflict_constraints::out) is det. look_for_typeclass_info_conflict_in_disjuncts(_, _, _, [], [], @@ -714,8 +720,7 @@ look_for_typeclass_info_conflict_in_disjuncts(DupTCIVars, :- pred look_for_typeclass_info_conflict_in_switch(set_of_progvar::in, map(prog_var, prog_constraint)::in, instmap::in, list(case)::in, - multi_map(prog_constraint, prog_var)::in, - multi_map(prog_constraint, prog_var)::out, + constraint_tci_db::in, constraint_tci_db::out, conflict_constraints::in, conflict_constraints::out) is det. look_for_typeclass_info_conflict_in_switch(DupTCIVars, TCIVarToConstraintMap, @@ -728,7 +733,7 @@ look_for_typeclass_info_conflict_in_switch(DupTCIVars, TCIVarToConstraintMap, :- pred look_for_typeclass_info_conflict_in_cases(set_of_progvar::in, map(prog_var, prog_constraint)::in, instmap::in, list(case)::in, - list(multi_map(prog_constraint, prog_var))::out, + list(constraint_tci_db)::out, conflict_constraints::in, conflict_constraints::out) is det. look_for_typeclass_info_conflict_in_cases(_, _, _, [], [], @@ -750,9 +755,8 @@ look_for_typeclass_info_conflict_in_cases(DupTCIVars, TCIVarToConstraintMap, %---------------------% :- pred detect_conflicts_in_arms(set(prog_constraint)::in, - list(multi_map(prog_constraint, prog_var))::in, - multi_map(prog_constraint, prog_var)::in, - multi_map(prog_constraint, prog_var)::out, + list(constraint_tci_db)::in, + constraint_tci_db::in, constraint_tci_db::out, conflict_constraints::in, conflict_constraints::out) is det. detect_conflicts_in_arms(_, [], !AllArmTCIConstraints, !ConflictConstraints). @@ -764,7 +768,9 @@ detect_conflicts_in_arms(!.SeenConstraints, ( if set.is_non_empty(SeenHeadConstraints) then % This arm and one (or more) of the previous arms both define % typeclass_infos for the constraints in SeenHeadConstraints. - set.union(SeenHeadConstraints, !ConflictConstraints) + multi_map.select(HeadArmTCIConstraints, SeenHeadConstraints, + HeadArmSeenTCIConstraints), + multi_map.merge(HeadArmSeenTCIConstraints, !ConflictConstraints) else true ), @@ -786,10 +792,12 @@ report_typeclass_info_problem(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, output_debug, yes(color_subject), should_not_module_qualify, [], proc(PredId, ProcId)), pred_info_get_typevarset(PredInfo, TVarSet), - set.to_sorted_list(ConflictConstraintSet, ConflictConstraints), + multi_map.to_sorted_assoc_list(ConflictConstraintSet, ConflictConstraints), list.map(conflict_constraint_to_piece(TVarSet), - ConflictConstraints, ConflictConstraintPieces0), - list.intersperse(nl, ConflictConstraintPieces0, ConflictConstraintPieces), + ConflictConstraints, ConflictConstraintPieceLists0), + list.intersperse([nl], + ConflictConstraintPieceLists0, ConflictConstraintPieceLists), + list.condense(ConflictConstraintPieceLists, ConflictConstraintPieces), ( if list.length(ConflictConstraints) > 1 then ConflictPieces = [words("The constraints involved are:"), nl_indent_delta(1)] ++ @@ -806,10 +814,11 @@ report_typeclass_info_problem(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, % the most common way for body_typeinfo_liveness to be set. % Both alternatives, the use of .agc grades and manual setting % of the option, are extremely rare. - MainPieces = [words("Sorry: the compiler cannot compile")] ++ + MainPieces = [words("Sorry: the compiler")] ++ + color_as_incorrect([words("cannot correctly compile")]) ++ ProcPieces ++ [words("with debugging enabled."), words("This is due to a known limitation that concerns"), - words("the mapping between typeclass on the one hand,"), + words("the mapping between typeclass constraints on the one hand,"), words("and the hidden, compiler-generated variables"), words("storing information about them on the other hand."), nl] ++ @@ -830,13 +839,25 @@ report_typeclass_info_problem(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, Spec = gen_spec($pred, severity_error, Phase, [Msg]), !:Specs = [Spec | !.Specs]. -:- pred conflict_constraint_to_piece(tvarset::in, prog_constraint::in, - format_piece::out) is det. +:- pred conflict_constraint_to_piece(tvarset::in, + pair(prog_constraint, list(constraint_tci))::in, + list(format_piece)::out) is det. -conflict_constraint_to_piece(TVarSet, Constraint, Piece) :- +conflict_constraint_to_piece(TVarSet, Constraint - ConstraintTCIs, Pieces) :- ConstraintStr = mercury_constraint_to_string(TVarSet, print_name_only, Constraint), - Piece = words(ConstraintStr). + ContextToLineNumberPiece = + ( func(ConstraintTCI) = LineNumberPiece :- + ConstraintTCI = constraint_tci(_TCIVar, Context), + LineNumber = context_line(Context), + LineNumberPiece = int_fixed(LineNumber) + ), + LineNumberPieces0 = list.map(ContextToLineNumberPiece, ConstraintTCIs), + list.sort_and_remove_dups(LineNumberPieces0, LineNumberPieces), + OnLineS = choose_number(LineNumberPieces, "on line", "on lines"), + LineNumbersPieces = piece_list_to_pieces("and", LineNumberPieces), + Pieces = [words(ConstraintStr), nl_indent_delta(1)] ++ + [words(OnLineS)] ++ LineNumbersPieces ++ [nl_indent_delta(-1)]. %---------------------------------------------------------------------------% diff --git a/library/multi_map.m b/library/multi_map.m index adafb6527..f54742368 100644 --- a/library/multi_map.m +++ b/library/multi_map.m @@ -246,6 +246,13 @@ :- pred to_assoc_list(multi_map(K, V)::in, assoc_list(K, list(V))::out) is det. + % Convert a multi_map to an association list, with all the values + % for each key in one element of the association list, sorted on the keys. + % +:- func to_sorted_assoc_list(multi_map(K, V)) = assoc_list(K, list(V)). +:- pred to_sorted_assoc_list(multi_map(K, V)::in, + assoc_list(K, list(V))::out) is det. + % Convert an association list with all the values for each key % in one element of the list to a multi_map. % @@ -588,6 +595,12 @@ to_assoc_list(MultiMap) = AssocList :- to_assoc_list(MultiMap, AssocList) :- map.to_assoc_list(MultiMap, AssocList). +to_sorted_assoc_list(MultiMap) = AssocList :- + multi_map.to_sorted_assoc_list(MultiMap, AssocList). + +to_sorted_assoc_list(MultiMap, AssocList) :- + map.to_sorted_assoc_list(MultiMap, AssocList). + from_assoc_list(AssocList) = MultiMap :- multi_map.from_assoc_list(AssocList, MultiMap). diff --git a/tests/invalid/tci_liveness_abort.err_exp b/tests/invalid/tci_liveness_abort.err_exp index 389ede795..3614ef70d 100644 --- a/tests/invalid/tci_liveness_abort.err_exp +++ b/tests/invalid/tci_liveness_abort.err_exp @@ -1,11 +1,12 @@ -tci_liveness_abort.m:020: Sorry: the compiler cannot compile predicate -tci_liveness_abort.m:020: `test1'/4 with debugging enabled. This is due to a -tci_liveness_abort.m:020: known limitation that concerns the mapping between -tci_liveness_abort.m:020: typeclass on the one hand, and the hidden, -tci_liveness_abort.m:020: compiler-generated variables storing information -tci_liveness_abort.m:020: about them on the other hand. +tci_liveness_abort.m:020: Sorry: the compiler cannot correctly compile +tci_liveness_abort.m:020: predicate `test1'/4 with debugging enabled. This is +tci_liveness_abort.m:020: due to a known limitation that concerns the mapping +tci_liveness_abort.m:020: between typeclass constraints on the one hand, and +tci_liveness_abort.m:020: the hidden, compiler-generated variables storing +tci_liveness_abort.m:020: information about them on the other hand. tci_liveness_abort.m:020: The constraint involved is: tci_liveness_abort.m:020: tci_liveness_abort.host(T) +tci_liveness_abort.m:020: on line 53 tci_liveness_abort.m:020: The limitation occurs when the definition of a tci_liveness_abort.m:020: predicate or function contains both the tci_liveness_abort.m:020: deconstructions of terms that contain existentially @@ -14,11 +15,12 @@ tci_liveness_abort.m:020: if-then-elses, disjunctions and/or switches. You tci_liveness_abort.m:020: can work around the limitation by moving such tci_liveness_abort.m:020: deconstruction unifications to helper predicates tci_liveness_abort.m:020: that contain no branching. -tci_liveness_abort.m:022: Sorry: the compiler cannot compile predicate -tci_liveness_abort.m:022: `test2'/3 with debugging enabled. This is due to a -tci_liveness_abort.m:022: known limitation that concerns the mapping between -tci_liveness_abort.m:022: typeclass on the one hand, and the hidden, -tci_liveness_abort.m:022: compiler-generated variables storing information -tci_liveness_abort.m:022: about them on the other hand. +tci_liveness_abort.m:022: Sorry: the compiler cannot correctly compile +tci_liveness_abort.m:022: predicate `test2'/3 with debugging enabled. This is +tci_liveness_abort.m:022: due to a known limitation that concerns the mapping +tci_liveness_abort.m:022: between typeclass constraints on the one hand, and +tci_liveness_abort.m:022: the hidden, compiler-generated variables storing +tci_liveness_abort.m:022: information about them on the other hand. tci_liveness_abort.m:022: The constraint involved is: tci_liveness_abort.m:022: tci_liveness_abort.host(T) +tci_liveness_abort.m:022: on line 77 diff --git a/tests/warnings/unused_args_some_modes.err_exp b/tests/warnings/unused_args_some_modes.err_exp index 5e1f1ea3d..3fb7b612a 100644 --- a/tests/warnings/unused_args_some_modes.err_exp +++ b/tests/warnings/unused_args_some_modes.err_exp @@ -1,10 +1,8 @@ -unused_args_some_modes.m:024: In `p(in(unused_args_some_modes.i1), in, in, -unused_args_some_modes.m:024: in(free), in(free), out)': +unused_args_some_modes.m:024: In `p(in(i1), in, in, in(free), in(free), out)': unused_args_some_modes.m:024: warning: arguments 2 and 3 are unused. unused_args_some_modes.m:024: (Arguments 4 and 5 are also unused, but their unused_args_some_modes.m:024: modes mark them as unused.) -unused_args_some_modes.m:025: In `p(in(unused_args_some_modes.i2), in, in, -unused_args_some_modes.m:025: in(free), in, out)': +unused_args_some_modes.m:025: In `p(in(i2), in, in, in(free), in, out)': unused_args_some_modes.m:025: warning: arguments 3 and 5 are unused. unused_args_some_modes.m:025: (Argument 4 is also unused, but its mode marks unused_args_some_modes.m:025: it as unused.)