diff --git a/compiler/add_pragma_impl.m b/compiler/add_pragma_impl.m index 82c50ea8a..da438824a 100644 --- a/compiler/add_pragma_impl.m +++ b/compiler/add_pragma_impl.m @@ -613,7 +613,7 @@ add_pragma_require_tail_rec_proc(RequireTailrec, Context, MaybePredOrFunc, [nl], OrigPieces = [words("The earlier pragma is here."), nl], ( RequireTailrecOrig = suppress_tailrec_warnings(ContextOrig) - ; RequireTailrecOrig = enable_tailrec_warnings(_, _, ContextOrig) + ; RequireTailrecOrig = enable_tailrec_warnings(_, _, _, ContextOrig) ), Spec = error_spec($pred, severity_error, phase_pt2h, [msg(Context, MainPieces), diff --git a/compiler/hlds_dependency_graph.m b/compiler/hlds_dependency_graph.m index 05c671c24..cdd583b2d 100644 --- a/compiler/hlds_dependency_graph.m +++ b/compiler/hlds_dependency_graph.m @@ -47,20 +47,20 @@ % Ensure that the module_info contains a version of the dependency_info % which only contains arcs between procedures for which there are clauses - % defined (everything that is not imported, plus opt_imported). + % defined (everything that is not imported or external). % Return this dependency_info. % - % There is no guarantee that the dependency_info is current. + % There is no guarantee that the returned hlds_dependency_info is current. % :- pred module_info_ensure_dependency_info(module_info::in, module_info::out, hlds_dependency_info::out) is det. % Ensure that the module_info contains a version of the dependency_info % which only contains arcs between procedures for which there are clauses - % defined (everything that is not imported, plus opt_imported). + % defined (everything that is not import or external). % Return this dependency_info. % - % The dependency_info will be up-to-date. + % The returned hlds_dependency_info will be up-to-date. % :- pred module_info_rebuild_dependency_info(module_info::in, module_info::out, hlds_dependency_info::out) is det. @@ -189,6 +189,8 @@ module_info_rebuild_dependency_info(!ModuleInfo, DepInfo) :- pred_id::in, list(pred_proc_id)::in, list(pred_proc_id)::out) is det. gather_pred_proc_ids(ModuleInfo, Imported, PredId, !PredProcIds) :- + % XXX The only call to this predicate always sets Imported to + % do_not_include_imported. module_info_pred_info(ModuleInfo, PredId, PredInfo), ( % Don't bother to add imported procedures, since we don't have diff --git a/compiler/hlds_pred.m b/compiler/hlds_pred.m index 07ff49656..fade91299 100644 --- a/compiler/hlds_pred.m +++ b/compiler/hlds_pred.m @@ -562,6 +562,7 @@ % Return a list of the proc_ids for all the modes of this predicate % that are not imported. + % ZZZ % :- func pred_info_all_non_imported_procids(pred_info) = list(proc_id). diff --git a/compiler/mark_tail_calls.m b/compiler/mark_tail_calls.m index 43d52ecd4..853f1307b 100644 --- a/compiler/mark_tail_calls.m +++ b/compiler/mark_tail_calls.m @@ -46,6 +46,7 @@ :- import_module parse_tree. :- import_module parse_tree.error_spec. :- import_module parse_tree.prog_data. +:- import_module parse_tree.prog_data_pragma. :- import_module list. @@ -120,6 +121,7 @@ :- type warn_non_tail_rec_params ---> warn_non_tail_rec_params( warning_or_error, + report_in_which_grades, maybe_warn_non_tail_self_rec, maybe_warn_non_tail_mutual_rec ). @@ -234,7 +236,6 @@ :- import_module libs.options. :- import_module mdbcomp. :- import_module mdbcomp.sym_name. -:- import_module parse_tree.prog_data_pragma. :- import_module parse_tree.prog_type. :- import_module parse_tree.var_table. @@ -374,12 +375,16 @@ mark_tail_rec_calls_in_proc_for_llds_code_gen(ModuleInfo, PredId, ProcId, :- func no_warnings_non_tail_rec_params = warn_non_tail_rec_params. no_warnings_non_tail_rec_params = Params :- - % Since neither SelfRec nor MutualRec is set, the value of - % WarnOrError does not matter. - Params = warn_non_tail_rec_params(we_warning, + % Since neither SelfRec nor MutualRec is set, the values of + % WarnOrError and Grades do not matter. + Params = warn_non_tail_rec_params(we_warning, in_tailrec_grades_only, do_not_warn_non_tail_self_rec, do_not_warn_non_tail_mutual_rec). get_default_warn_parms(Globals, WarnNonTailRecParams) :- + % XXX Should we add an option to control the setting of this default? + % I (zs) do not think so. + Grades = in_tailrec_grades_only, + globals.lookup_bool_option(Globals, warn_non_tail_recursion_self, WarnNonTailSelfRecBool), ( @@ -398,7 +403,7 @@ get_default_warn_parms(Globals, WarnNonTailRecParams) :- WarnNonTailMutualRecBool = no, WarnNonTailMutualRecOpt = do_not_warn_non_tail_mutual_rec ), - WarnNonTailRecParams = warn_non_tail_rec_params(we_warning, + WarnNonTailRecParams = warn_non_tail_rec_params(we_warning, Grades, WarnNonTailSelfRecOpt, WarnNonTailMutualRecOpt). maybe_override_warn_params_for_proc(ProcInfo, WarnParams, ProcWarnParams) :- @@ -412,7 +417,8 @@ maybe_override_warn_params_for_proc(ProcInfo, WarnParams, ProcWarnParams) :- Pragma = suppress_tailrec_warnings(_), ProcWarnParams = no_warnings_non_tail_rec_params ; - Pragma = enable_tailrec_warnings(WarnOrError, RecType, _Context), + Pragma = enable_tailrec_warnings(WarnOrError, RecType, Grades, + _Context), ( RecType = only_self_recursion_must_be_tail, SelfRec = warn_non_tail_self_rec, @@ -422,8 +428,8 @@ maybe_override_warn_params_for_proc(ProcInfo, WarnParams, ProcWarnParams) :- SelfRec = warn_non_tail_self_rec, MutualRec = warn_non_tail_mutual_rec ), - ProcWarnParams = - warn_non_tail_rec_params(WarnOrError, SelfRec, MutualRec) + ProcWarnParams = warn_non_tail_rec_params(WarnOrError, Grades, + SelfRec, MutualRec) ) ). @@ -529,7 +535,7 @@ do_mark_tail_rec_calls_in_proc(Params, ModuleInfo, SCC, PredId, ProcId, MaybeSelfFeature = no, MaybeMutualFeature = no, MaybeRecordTailCalls = do_not_record_tail_recursion, - WarnNonTailRecParams = warn_non_tail_rec_params(_WarnOrError, + WarnNonTailRecParams = warn_non_tail_rec_params(_, _, do_not_warn_non_tail_self_rec, do_not_warn_non_tail_mutual_rec) then WasProcChanged = proc_was_not_changed @@ -1067,7 +1073,7 @@ not_at_tail(Before, After) :- maybe_report_nontail_recursive_call(ModuleInfo, CallerPredProcId, CalleePredProcId, Context, Reason, Obviousness, WarnParams, !Specs) :- - WarnParams = warn_non_tail_rec_params(WarnOrError, + WarnParams = warn_non_tail_rec_params(WarnOrError, Grades, WarnNonTailSelfRec, WarnNonTailMutualRec), ( if ( if CallerPredProcId = CalleePredProcId then @@ -1082,6 +1088,12 @@ maybe_report_nontail_recursive_call(ModuleInfo, module_info_get_globals(ModuleInfo, Globals), globals.lookup_bool_option(Globals, warn_obvious_non_tail_recursion, yes) + ), + ( + Grades = in_all_grades + ; + Grades = in_tailrec_grades_only, + grade_supports_tail_recursion(ModuleInfo) ) then report_nontail_recursive_call(ModuleInfo, @@ -1091,6 +1103,17 @@ maybe_report_nontail_recursive_call(ModuleInfo, true ). +:- pred grade_supports_tail_recursion(module_info::in) is semidet. + +grade_supports_tail_recursion(ModuleInfo) :- + module_info_get_globals(ModuleInfo, Globals), + % XXX Are there any other grade components that disable tail recursion? + globals.lookup_bool_option(Globals, profile_deep, no), + globals.lookup_bool_option(Globals, exec_trace, no), + globals.lookup_bool_option(Globals, source_to_source_debug, no), + globals.lookup_bool_option(Globals, use_minimal_model_stack_copy, no), + globals.lookup_bool_option(Globals, use_minimal_model_own_stacks, no). + :- pred report_nontail_recursive_call(module_info::in, pred_proc_id::in, pred_proc_id::in, prog_context::in, nontail_rec_call_reason::in, warning_or_error::in, @@ -1226,7 +1249,7 @@ maybe_report_no_tail_or_nontail_recursive_calls(PredInfo, ProcInfo, MaybeRequireTailRec = no ; MaybeRequireTailRec = yes(RequireTailRecInfo), - ( RequireTailRecInfo = enable_tailrec_warnings(_, _, Context) + ( RequireTailRecInfo = enable_tailrec_warnings(_, _, _, Context) ; RequireTailRecInfo = suppress_tailrec_warnings(Context) ), pred_info_get_is_pred_or_func(PredInfo, PredOrFunc), diff --git a/compiler/parse_pragma.m b/compiler/parse_pragma.m index 71c1db51c..92b51fc79 100644 --- a/compiler/parse_pragma.m +++ b/compiler/parse_pragma.m @@ -983,13 +983,13 @@ parse_pragma_require_tail_recursion(ModuleName, PragmaName, PragmaTerms, pragma_decl(PragmaName), words("declaration:"), nl]), parse_pred_pfu_name_arity_maybe_modes(ModuleName, ContextPieces, VarSet, PredOrProcSpecTerm, MaybePredOrProcSpec), - % Parse the options. + % Parse the options, if any. ( MaybeOptionsTerm = yes(OptionsTerm), ( if list_term_to_term_list(OptionsTerm, OptionsTerms) then - parse_pragma_require_tail_recursion_options(VarSet, - OptionsTerms, have_not_seen_none, no, no, [], - Context, MaybeOptions) + parse_pragma_require_tail_recursion_options(VarSet, Context, + OptionsTerms, have_not_seen_none, no, no, no, + [], MaybeOptions) else OptionsContext = get_term_context(OptionsTerm), OptionsTermStr = describe_error_term(VarSet, OptionsTerm), @@ -1007,8 +1007,11 @@ parse_pragma_require_tail_recursion(ModuleName, PragmaName, PragmaTerms, ) ; MaybeOptionsTerm = no, - MaybeOptions = ok1(enable_tailrec_warnings(we_warning, - both_self_and_mutual_recursion_must_be_tail, Context)) + Severity = we_warning, + Kind = both_self_and_mutual_recursion_must_be_tail, + Grades = in_tailrec_grades_only, + Enable = enable_tailrec_warnings(Severity, Kind, Grades, Context), + MaybeOptions = ok1(Enable) ), ( if MaybePredOrProcSpec = ok1(PredOrProcSpec), @@ -1036,36 +1039,47 @@ parse_pragma_require_tail_recursion(ModuleName, PragmaName, PragmaTerms, ---> seen_none ; have_not_seen_none. -:- pred parse_pragma_require_tail_recursion_options(varset::in, list(term)::in, - seen_none::in, maybe(warning_or_error)::in, - maybe(require_tail_recursion_type)::in, list(error_spec)::in, - prog_context::in, maybe1(require_tail_recursion)::out) is det. +:- pred parse_pragma_require_tail_recursion_options(varset::in, + prog_context::in, list(term)::in, seen_none::in, + maybe(warning_or_error)::in, maybe(require_tail_recursion_type)::in, + maybe(report_in_which_grades)::in, list(error_spec)::in, + maybe1(require_tail_recursion)::out) is det. -parse_pragma_require_tail_recursion_options(_VarSet, [], SeenNone, - MaybeWarnOrError, MaybeType, !.Specs, Context, MaybeRTR) :- +parse_pragma_require_tail_recursion_options(_VarSet, PragmaContext, [], + !.SeenNone, !.MaybeWarnOrError, !.MaybeType, !.MaybeGrades, + !.Specs, MaybeRTR) :- ( - SeenNone = seen_none, + !.SeenNone = seen_none, % Check for conflicts with "none" option. ( - MaybeWarnOrError = yes(WarnOrError0), + !.MaybeWarnOrError = yes(WarnOrError0), warning_or_error_string(WarnOrError0, WarnOrErrorString), SpecA = conflicting_attributes_error("none", WarnOrErrorString, - Context), + PragmaContext), !:Specs = [SpecA | !.Specs] ; - MaybeWarnOrError = no + !.MaybeWarnOrError = no ), ( - MaybeType = yes(Type0), + !.MaybeType = yes(Type0), require_tailrec_type_string(Type0, TypeString), SpecB = conflicting_attributes_error("none", TypeString, - Context), + PragmaContext), !:Specs = [SpecB | !.Specs] ; - MaybeType = no + !.MaybeType = no + ), + ( + !.MaybeGrades = yes(Grades0), + require_tailrec_grades_string(Grades0, GradesString), + SpecC = conflicting_attributes_error("none", GradesString, + PragmaContext), + !:Specs = [SpecC | !.Specs] + ; + !.MaybeGrades = no ) ; - SeenNone = have_not_seen_none + !.SeenNone = have_not_seen_none ), ( !.Specs = [_ | _], @@ -1073,29 +1087,37 @@ parse_pragma_require_tail_recursion_options(_VarSet, [], SeenNone, ; !.Specs = [], ( - SeenNone = seen_none, - MaybeRTR = ok1(suppress_tailrec_warnings(Context)) + !.SeenNone = seen_none, + MaybeRTR = ok1(suppress_tailrec_warnings(PragmaContext)) ; - SeenNone = have_not_seen_none, - % If these values were not set then use the defaults. + !.SeenNone = have_not_seen_none, + % If these values were not set, then use the defaults. ( - MaybeWarnOrError = yes(WarnOrError) + !.MaybeWarnOrError = yes(WarnOrError) ; - MaybeWarnOrError = no, + !.MaybeWarnOrError = no, WarnOrError = we_warning ), ( - MaybeType = yes(Type) + !.MaybeType = yes(Type) ; - MaybeType = no, + !.MaybeType = no, Type = both_self_and_mutual_recursion_must_be_tail ), - RTR = enable_tailrec_warnings(WarnOrError, Type, Context), + ( + !.MaybeGrades = yes(Grades) + ; + !.MaybeGrades = no, + Grades = in_tailrec_grades_only + ), + RTR = enable_tailrec_warnings(WarnOrError, Type, Grades, + PragmaContext), MaybeRTR = ok1(RTR) ) ). -parse_pragma_require_tail_recursion_options(VarSet, [Term | Terms], SeenNone0, - MaybeWarnOrError0, MaybeType0, !.Specs, PragmaContext, MaybeRTR) :- +parse_pragma_require_tail_recursion_options(VarSet, PragmaContext, + [Term | Terms], !.SeenNone, !.MaybeWarnOrError, !.MaybeType, + !.MaybeGrades, !.Specs, MaybeRTR) :- ( Term = functor(Functor, _Args, Context), ( if @@ -1103,61 +1125,61 @@ parse_pragma_require_tail_recursion_options(VarSet, [Term | Terms], SeenNone0, warning_or_error_string(WarnOrError, Name) then ( - MaybeWarnOrError0 = no, - MaybeWarnOrError = yes(WarnOrError) + !.MaybeWarnOrError = no, + !:MaybeWarnOrError = yes(WarnOrError) ; - MaybeWarnOrError0 = yes(WarnOrErrorFirst), - warning_or_error_string(WarnOrErrorFirst, - WarnOrErrorFirstString), + !.MaybeWarnOrError = yes(OldWarnOrError), + warning_or_error_string(OldWarnOrError, OldWarnOrErrorString), Spec = conflicting_attributes_error(Name, - WarnOrErrorFirstString, Context), - MaybeWarnOrError = MaybeWarnOrError0, + OldWarnOrErrorString, Context), !:Specs = [Spec | !.Specs] - ), - MaybeType = MaybeType0, - SeenNone = SeenNone0 + ) else if Functor = atom(Name), require_tailrec_type_string(Type, Name) then ( - MaybeType0 = no, - MaybeType = yes(Type) + !.MaybeType = no, + !:MaybeType = yes(Type) ; - MaybeType0 = yes(TypeFirst), - require_tailrec_type_string(TypeFirst, TypeFirstString), + !.MaybeType = yes(OldType), + require_tailrec_type_string(OldType, OldTypeString), Spec = conflicting_attributes_error(Name, - TypeFirstString, Context), - MaybeType = MaybeType0, + OldTypeString, Context), !:Specs = [Spec | !.Specs] - ), - MaybeWarnOrError = MaybeWarnOrError0, - SeenNone = SeenNone0 + ) + else if + Functor = atom(Name), + require_tailrec_grades_string(Grades, Name) + then + ( + !.MaybeGrades = no, + !:MaybeGrades = yes(Grades) + ; + !.MaybeGrades = yes(OldGrades), + require_tailrec_grades_string(OldGrades, OldGradesString), + Spec = conflicting_attributes_error(Name, + OldGradesString, Context), + !:Specs = [Spec | !.Specs] + ) else if Functor = atom("none") then - SeenNone = seen_none, - MaybeWarnOrError = MaybeWarnOrError0, - MaybeType = MaybeType0 + !:SeenNone = seen_none else Spec = pragma_require_tailrec_unknown_term_error(VarSet, Term, Context), - !:Specs = [Spec | !.Specs], - SeenNone = SeenNone0, - MaybeType = MaybeType0, - MaybeWarnOrError = MaybeWarnOrError0 + !:Specs = [Spec | !.Specs] ) ; Term = variable(_, Context), Spec = pragma_require_tailrec_unknown_term_error(VarSet, Term, Context), - !:Specs = [Spec | !.Specs], - SeenNone = SeenNone0, - MaybeType = MaybeType0, - MaybeWarnOrError = MaybeWarnOrError0 + !:Specs = [Spec | !.Specs] ), - parse_pragma_require_tail_recursion_options(VarSet, Terms, SeenNone, - MaybeWarnOrError, MaybeType, !.Specs, PragmaContext, MaybeRTR). + parse_pragma_require_tail_recursion_options(VarSet, PragmaContext, Terms, + !.SeenNone, !.MaybeWarnOrError, !.MaybeType, !.MaybeGrades, + !.Specs, MaybeRTR). :- func conflicting_attributes_error(string, string, prog_context) = error_spec. diff --git a/compiler/parse_tree_out_pragma.m b/compiler/parse_tree_out_pragma.m index dbb767029..c26cb2817 100644 --- a/compiler/parse_tree_out_pragma.m +++ b/compiler/parse_tree_out_pragma.m @@ -1268,11 +1268,13 @@ mercury_format_pragma_require_tail_rec(Lang, RequireTR, S, !U) :- string.format(":- pragma warn_tail_recursion(%s, [none]).\n", [s(ProcSpecStr)], DeclStr) ; - Warn = enable_tailrec_warnings(WarnOrError, Type, _), + Warn = enable_tailrec_warnings(WarnOrError, Type, Grades, _), warning_or_error_string(WarnOrError, WarnOrErrorStr), require_tailrec_type_string(Type, TypeStr), - string.format(":- pragma warn_tail_recursion(%s, [%s, %s]).\n", - [s(ProcSpecStr), s(WarnOrErrorStr), s(TypeStr)], DeclStr) + require_tailrec_grades_string(Grades, GradesStr), + string.format(":- pragma warn_tail_recursion(%s, [%s, %s, %s]).\n", + [s(ProcSpecStr), s(WarnOrErrorStr), s(TypeStr), s(GradesStr)], + DeclStr) ), add_string(DeclStr, S, !U). diff --git a/compiler/prog_data_pragma.m b/compiler/prog_data_pragma.m index 808ea38e8..5a6aa9e80 100644 --- a/compiler/prog_data_pragma.m +++ b/compiler/prog_data_pragma.m @@ -509,9 +509,17 @@ tabled_eval_method_to_table_type(EvalMethod) = TableTypeStr :- ; enable_tailrec_warnings( rtre_warn_or_error :: warning_or_error, rtre_recursion_type :: require_tail_recursion_type, + rtre_grades :: report_in_which_grades, rtre_context :: prog_context ). + % Should we report violations of the required level of tail recursion ... +:- type report_in_which_grades + ---> in_tailrec_grades_only + % ... only in grades that support tail recursion, or ... + ; in_all_grades. + % ... in all grades. + :- type require_tail_recursion_type ---> only_self_recursion_must_be_tail ; both_self_and_mutual_recursion_must_be_tail. @@ -520,6 +528,10 @@ tabled_eval_method_to_table_type(EvalMethod) = TableTypeStr :- :- mode require_tailrec_type_string(in, out) is det. :- mode require_tailrec_type_string(out, in) is semidet. +:- pred require_tailrec_grades_string(report_in_which_grades, string). +:- mode require_tailrec_grades_string(in, out) is det. +:- mode require_tailrec_grades_string(out, in) is semidet. + :- implementation. require_tailrec_type_string(only_self_recursion_must_be_tail, @@ -527,6 +539,11 @@ require_tailrec_type_string(only_self_recursion_must_be_tail, require_tailrec_type_string(both_self_and_mutual_recursion_must_be_tail, "self_or_mutual_recursion"). +require_tailrec_grades_string(in_tailrec_grades_only, + "in_tailrec_grades_only"). +require_tailrec_grades_string(in_all_grades, + "in_all_grades"). + %---------------------------------------------------------------------------% :- end_module parse_tree.prog_data_pragma. %---------------------------------------------------------------------------% diff --git a/tests/valid/require_tailrec_1.m b/tests/valid/require_tailrec_1.m index 9eff26bdc..e9082b540 100644 --- a/tests/valid/require_tailrec_1.m +++ b/tests/valid/require_tailrec_1.m @@ -1,7 +1,10 @@ +%---------------------------------------------------------------------------% +% vim: ts=4 sw=4 et ft=mercury +%---------------------------------------------------------------------------% % % Test the require tail recursion pragma with the -% --warn-non-tail-recursion-self option. These tests do not raise an error, -% the tests that do raise errors are in invalid/ +% --warn-non-tail-recursion-self option, and with pred()/func() wrappers +% around all name/arity pairs. % :- module require_tailrec_1. @@ -40,7 +43,7 @@ foldl1(P, [X | Xs], !Acc) :- foldl1(P, Xs, !Acc). % self non-tail recursive code with none pragma. -:- pragma require_tail_recursion(map1/3, [none]). +:- pragma require_tail_recursion(pred(map1/3), [none]). map1(_, [], []). map1(P, [X | Xs], [Y | Ys]) :- P(X, Y), @@ -62,7 +65,7 @@ odd1(N) = ). % mutual non-tail recursion with none pragma. -:- pragma require_tail_recursion(odd2/1, [none]). +:- pragma require_tail_recursion(func(odd2/1), [none]). even2(N) = ( if N = 0 then yes @@ -70,7 +73,7 @@ even2(N) = odd2(N - 1) ). -:- pragma require_tail_recursion(odd3/1, [self_recursion_only]). +:- pragma require_tail_recursion(func(odd3/1), [self_recursion_only]). odd2(N) = ( if N = 0 then no @@ -94,7 +97,7 @@ odd3(N) = %---------------------------------------------------------------------------% -:- pragma require_tail_recursion(qsortapp/2, [none]). +:- pragma require_tail_recursion(pred(qsortapp/2), [none]). qsortapp([], []). qsortapp([Pivot | T], List) :- @@ -105,7 +108,7 @@ qsortapp([Pivot | T], List) :- :- pred partition(int::in, list(int)::in, list(int)::in, list(int)::out, list(int)::in, list(int)::out) is det. -:- pragma require_tail_recursion(partition/6). +:- pragma require_tail_recursion(pred(partition/6)). partition(_Pivot, [], Left, Left, Right, Right). partition(Pivot, [H | T], Left0, Left, Right0, Right) :- @@ -114,4 +117,3 @@ partition(Pivot, [H | T], Left0, Left, Right0, Right) :- else partition(Pivot, T, Left0, Left, [H | Right0], Right) ). - diff --git a/tests/valid/require_tailrec_2.m b/tests/valid/require_tailrec_2.m index 72efcfdd7..2c6b815a9 100644 --- a/tests/valid/require_tailrec_2.m +++ b/tests/valid/require_tailrec_2.m @@ -1,7 +1,9 @@ +%---------------------------------------------------------------------------% +% vim: ts=4 sw=4 et ft=mercury +%---------------------------------------------------------------------------% % % Test the require tail recursion pragma with the -% --no-warn-non-tail-recursion option. These tests do not raise an error, -% the tests that do raise errors are in invalid/ +% --no-warn-non-tail-recursion option. % :- module require_tailrec_2. @@ -212,4 +214,3 @@ partition(Pivot, [H | T], Left0, Left, Right0, Right) :- else partition(Pivot, T, Left0, Left, [H | Right0], Right) ). - diff --git a/tests/valid/require_tailrec_3.m b/tests/valid/require_tailrec_3.m index 35d771099..d674e7b1a 100644 --- a/tests/valid/require_tailrec_3.m +++ b/tests/valid/require_tailrec_3.m @@ -1,7 +1,9 @@ +%---------------------------------------------------------------------------% +% vim: ts=4 sw=4 et ft=mercury +%---------------------------------------------------------------------------% % % Test the require tail recursion pragma with the -% --warn-non-tail-recursion option. These tests do not raise an error, -% the tests that do raise errors are in invalid/ +% --warn-non-tail-recursion option. % :- module require_tailrec_3. @@ -102,4 +104,3 @@ odd4(N) = else bool.not(even4(N)) ). -