diff --git a/compiler/error_util.m b/compiler/error_util.m index 4eb4177ee..9accaa985 100644 --- a/compiler/error_util.m +++ b/compiler/error_util.m @@ -93,36 +93,31 @@ %---------------------------------------------------------------------------% -:- type maybe_written_spec - ---> to_be_written_spec(error_spec) - ; already_written_spec(std_error_spec). - % Sometimes we want to both - % - % - print an error_spec just after it is generated, and - % - also return it to inform decisions about the presence - % of errors. - % - % To prevent the caller from writing out a duplicate copy - % of the error_spec, we can return it wrapped up - % in this function symbol, which - % - % - preserves its severity (for decisions), - % - preserves its text (which may be helpful when debugging - % the code that makes those decision), - % - but which write_error_spec.m knows to ignore. - % - % An alternative design would create a new type, called maybe - % gen_error_spec, which contains error_spec's three function - % symbols *and* already_printed_spec, and make error_spec - % a subtype of this new type. This design works (I, zs, have - % tested it), but it makes references to error_spec's three - % function symbols ambiguous, since their type can be either - % error_spec or gen_error_spec. In most cases, the surrounding - % context resolves the ambiguity, but in some cases, it does not. + % Sometimes we want to both + % + % - print an error_spec just after it is generated, and + % - also return it to inform decisions about the presence of errors. + % + % To prevent the caller from writing out a duplicate copy of an + % error_spec, we can move it to the already_written field. This + % + % - preserves its severity (for decisions), + % - preserves its text (which may be helpful when debugging + % the code that makes those decision), + % - but which write_error_spec.m knows to ignore. + % +:- type maybe_written_specs + ---> maybe_written_specs( + to_be_written :: list(error_spec), + already_written :: list(error_spec) + ). -:- func maybe_written_spec_to_spec(maybe_written_spec) = error_spec. -:- func maybe_written_specs_to_specs(list(maybe_written_spec)) - = list(error_spec). +:- func init_maybe_written_specs = maybe_written_specs. + +:- pred add_to_be_written_specs(list(error_spec)::in, + maybe_written_specs::in, maybe_written_specs::out) is det. + +:- func maybe_written_specs_to_specs(maybe_written_specs) = list(error_spec). %---------------------------------------------------------------------------% @@ -436,16 +431,16 @@ contains_errors_or_warnings_treated_as_errors_opt_table(OptionTable, Specs) %---------------------------------------------------------------------------% -maybe_written_spec_to_spec(MaybeWrittenSpec) = Spec :- - ( - MaybeWrittenSpec = to_be_written_spec(Spec) - ; - MaybeWrittenSpec = already_written_spec(StdSpec), - Spec = coerce(StdSpec) - ). +init_maybe_written_specs = maybe_written_specs([], []). + +add_to_be_written_specs(Specs, !MaybeWrittenSpecs) :- + !.MaybeWrittenSpecs = maybe_written_specs(ToBeWritten0, AlreadyWritten), + ToBeWritten = Specs ++ ToBeWritten0, + !:MaybeWrittenSpecs = maybe_written_specs(ToBeWritten, AlreadyWritten). maybe_written_specs_to_specs(MaybeWrittenSpecs) = Specs :- - Specs = list.map(maybe_written_spec_to_spec, MaybeWrittenSpecs). + MaybeWrittenSpecs = maybe_written_specs(ToBeWritten, AlreadyWritten), + Specs = ToBeWritten ++ AlreadyWritten. %---------------------------------------------------------------------------% diff --git a/compiler/write_error_spec.m b/compiler/write_error_spec.m index 9d921c703..8fa3d749f 100644 --- a/compiler/write_error_spec.m +++ b/compiler/write_error_spec.m @@ -96,8 +96,7 @@ % add them back to !:MaybeWrittenSpecs as already_written specs. % :- pred write_not_yet_written_specs(io.text_output_stream::in, globals::in, - list(maybe_written_spec)::in, list(maybe_written_spec)::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% @@ -270,44 +269,17 @@ maybe_write_out_errors(Stream, Verbose, Globals, !Specs, !IO) :- %---------------------------------------------------------------------------% write_not_yet_written_specs(Stream, Globals, !MaybeWrittenSpecs, !IO) :- - categorize_maybe_written_specs(!.MaybeWrittenSpecs, - [], AlreadyWritten0, [], ToBeWritten0), - write_error_specs_return_std(Stream, Globals, - ToBeWritten0, NowWrittenStd, !IO), - NowWritten = list.map((func(S) = already_written_spec(S)), NowWrittenStd), - !:MaybeWrittenSpecs = AlreadyWritten0 ++ NowWritten. - -:- pred categorize_maybe_written_specs(list(maybe_written_spec)::in, - list(maybe_written_spec)::in, list(maybe_written_spec)::out, - list(error_spec)::in, list(error_spec)::out) is det. - -categorize_maybe_written_specs([], !AlreadyWritten, !ToBeWritten). -categorize_maybe_written_specs([MaybeWritten | MaybeWrittens], - !AlreadyWritten, !ToBeWritten) :- - ( - MaybeWritten = already_written_spec(_StdSpec), - !:AlreadyWritten = [MaybeWritten | !.AlreadyWritten] - ; - MaybeWritten = to_be_written_spec(Spec), - !:ToBeWritten = [Spec | !.ToBeWritten] - ), - categorize_maybe_written_specs(MaybeWrittens, - !AlreadyWritten, !ToBeWritten). + !.MaybeWrittenSpecs = maybe_written_specs(ToBeWritten0, AlreadyWritten0), + write_error_specs(Stream, Globals, ToBeWritten0, !IO), + AlreadyWritten = ToBeWritten0 ++ AlreadyWritten0, + !:MaybeWrittenSpecs = maybe_written_specs([], AlreadyWritten). %---------------------------------------------------------------------------% write_error_spec(Stream, Globals, Spec, !IO) :- - write_error_specs_return_std(Stream, Globals, [Spec], _StdSpecs, !IO). + write_error_specs(Stream, Globals, [Spec], !IO). write_error_specs(Stream, Globals, Specs0, !IO) :- - write_error_specs_return_std(Stream, Globals, Specs0, _StdSpecs, !IO). - -%---------------------% - -:- pred write_error_specs_return_std(io.text_output_stream::in, globals::in, - list(error_spec)::in, list(std_error_spec)::out, io::di, io::uo) is det. - -write_error_specs_return_std(Stream, Globals, Specs0, StdSpecs, !IO) :- standardize_error_specs(Specs0, StdSpecs), globals.get_options(Globals, OptionTable), globals.get_limit_error_contexts_map(Globals, LimitErrorContextsMap),