[m-rev.] for review: improved error messages for unexpected ::mode suffixes
Mark Brown
mark at mercurylang.org
Sun May 22 20:30:28 AEST 2016
Hi,
This is for review by anyone.
Mark.
-------------- next part --------------
commit 23e51121e7bdf0bba6dd4c684fe235668aea7f8c
Author: Mark Brown <mark at mercurylang.org>
Date: Sun May 22 20:18:27 2016 +1000
Improve error messages for unexpected ::mode suffixes.
compiler/parse_type_name.m:
In the arguments of pred and func types where we haven't
seen a determinism suffix, assume that uses of '::'/2
are mode suffixes and report them as being unexpected.
Previously we would typically end up reporting that '::'/2,
'in'/0 and 'out'/0 are undefined types.
tests/invalid/combined_ho_type_inst.err_exp:
tests/invalid/combined_ho_type_inst_2.err_exp:
Update expected outputs.
diff --git a/compiler/parse_type_name.m b/compiler/parse_type_name.m
index 02b1c48..8ab170f 100644
--- a/compiler/parse_type_name.m
+++ b/compiler/parse_type_name.m
@@ -216,36 +216,35 @@ parse_compound_type(AllowHOInstInfo, Term, VarSet, ContextPieces,
Result = error1([Spec])
;
CompoundTypeKind = kctk_pure_pred(Args),
- % XXX We should update ContextPieces.
- parse_types(no_allow_ho_inst_info(wnhii_pred_arg),
- VarSet, ContextPieces, Args, MaybeArgTypes),
+ parse_types_no_modes(no_allow_ho_inst_info(wnhii_pred_arg),
+ VarSet, ContextPieces, Args, 1, ArgTypes, [], Specs),
(
- MaybeArgTypes = ok1(ArgTypes),
+ Specs = [],
construct_higher_order_pred_type(purity_pure, lambda_normal,
ArgTypes, PredType),
Result = ok1(PredType)
;
- MaybeArgTypes = error1(Specs),
+ Specs = [_ | _],
Result = error1(Specs)
)
;
CompoundTypeKind = kctk_pure_func(BeforeEqTerm, AfterEqTerm),
( if BeforeEqTerm = term.functor(term.atom("func"), FuncArgs, _) then
- % XXX We should update ContextPieces.
- parse_types(no_allow_ho_inst_info(wnhii_func_arg),
- VarSet, ContextPieces, FuncArgs, MaybeArgTypes),
- parse_type(no_allow_ho_inst_info(wnhii_func_return_arg),
- VarSet, ContextPieces, AfterEqTerm, MaybeRetType),
+ parse_types_no_modes(no_allow_ho_inst_info(wnhii_func_arg),
+ VarSet, ContextPieces, FuncArgs, 1, ArgTypes, [], ArgSpecs),
+ RetContextPieces = ContextPieces ++
+ cord.from_list([words("in the return value:"), nl]),
+ parse_type_no_mode(no_allow_ho_inst_info(wnhii_func_return_arg),
+ VarSet, RetContextPieces, AfterEqTerm, MaybeRetType),
( if
- MaybeArgTypes = ok1(ArgTypes),
+ ArgSpecs = [],
MaybeRetType = ok1(RetType)
then
construct_higher_order_func_type(purity_pure, lambda_normal,
ArgTypes, RetType, FuncType),
Result = ok1(FuncType)
else
- Specs = get_any_errors1(MaybeArgTypes)
- ++ get_any_errors1(MaybeRetType),
+ Specs = ArgSpecs ++ get_any_errors1(MaybeRetType),
Result = error1(Specs)
)
else
@@ -285,37 +284,36 @@ parse_compound_type(AllowHOInstInfo, Term, VarSet, ContextPieces,
Args = [BeforeEqTerm, AfterEqTerm],
BeforeEqTerm = term.functor(term.atom("func"), FuncArgs, _)
then
- % XXX We should update ContextPieces.
- parse_types(no_allow_ho_inst_info(wnhii_func_arg),
- VarSet, ContextPieces, FuncArgs, MaybeArgTypes),
- parse_type(no_allow_ho_inst_info(wnhii_func_return_arg),
- VarSet, ContextPieces, AfterEqTerm, MaybeRetType),
+ parse_types_no_modes(no_allow_ho_inst_info(wnhii_func_arg),
+ VarSet, ContextPieces, FuncArgs, 1, ArgTypes, [], ArgSpecs),
+ RetContextPieces = ContextPieces ++
+ cord.from_list([words("in the return value:"), nl]),
+ parse_type_no_mode(no_allow_ho_inst_info(wnhii_func_return_arg),
+ VarSet, RetContextPieces, AfterEqTerm, MaybeRetType),
( if
- MaybeArgTypes = ok1(ArgTypes),
+ ArgSpecs = [],
MaybeRetType = ok1(RetType)
then
construct_higher_order_func_type(Purity, lambda_normal,
ArgTypes, RetType, Type),
Result = ok1(Type)
else
- Specs = get_any_errors1(MaybeArgTypes)
- ++ get_any_errors1(MaybeRetType),
+ Specs = ArgSpecs ++ get_any_errors1(MaybeRetType),
Result = error1(Specs)
)
else if
SubTerm = term.functor(term.atom(Name), Args, _),
Name = "pred"
then
- % XXX We should update ContextPieces.
- parse_types(no_allow_ho_inst_info(wnhii_pred_arg),
- VarSet, ContextPieces, Args, MaybeArgTypes),
+ parse_types_no_modes(no_allow_ho_inst_info(wnhii_pred_arg),
+ VarSet, ContextPieces, Args, 1, ArgTypes, [], Specs),
(
- MaybeArgTypes = ok1(ArgTypes),
+ Specs = [],
construct_higher_order_pred_type(Purity, lambda_normal,
ArgTypes, Type),
Result = ok1(Type)
;
- MaybeArgTypes = error1(Specs),
+ Specs = [_ | _],
Result = error1(Specs)
)
else if
@@ -466,6 +464,47 @@ project_tm_type_and_mode(type_only(_), _, _) :-
%---------------------------------------------------------------------------%
+:- pred parse_types_no_modes(allow_ho_inst_info::in, varset::in,
+ cord(format_component)::in, list(term)::in, int::in, list(mer_type)::out,
+ list(error_spec)::in, list(error_spec)::out) is det.
+
+parse_types_no_modes(_, _, _, [], _, [], !Specs).
+parse_types_no_modes(AllowHOInstInfo, Varset, ContextPieces, [Term | Terms],
+ ArgNum, Types, !Specs) :-
+ parse_types_no_modes(AllowHOInstInfo, Varset, ContextPieces, Terms,
+ ArgNum + 1, TypesTail, !Specs),
+ ArgContextPieces = ContextPieces ++
+ cord.from_list([words("in the"), nth_fixed(ArgNum),
+ words("argument:"), nl]),
+ parse_type_no_mode(AllowHOInstInfo, Varset, ArgContextPieces, Term,
+ MaybeType),
+ (
+ MaybeType = ok1(Type),
+ Types = [Type | TypesTail]
+ ;
+ MaybeType = error1(TSpecs),
+ Types = TypesTail,
+ !:Specs = TSpecs ++ !.Specs
+ ).
+
+:- pred parse_type_no_mode(allow_ho_inst_info::in, varset::in,
+ cord(format_component)::in, term::in, maybe1(mer_type)::out) is det.
+
+parse_type_no_mode(AllowHOInstInfo, Varset, ContextPieces, Term, MaybeType) :-
+ ( if Term = term.functor(term.atom("::"), [_, _], _) then
+ ErrorPieces = [lower_case_next_if_not_first,
+ words("Error: unexpected"), quote("::mode"),
+ words("suffix."), nl],
+ Pieces = cord.list(ContextPieces ++ cord.from_list(ErrorPieces)),
+ Spec = error_spec(severity_error, phase_term_to_parse_tree,
+ [simple_msg(get_term_context(Term), [always(Pieces)])]),
+ MaybeType = error1([Spec])
+ else
+ parse_type(AllowHOInstInfo, Varset, ContextPieces, Term, MaybeType)
+ ).
+
+%---------------------------------------------------------------------------%
+
parse_type_and_modes(_, _, _, _, _, [], _, [], !Specs).
parse_type_and_modes(MaybeInstConstraints, MaybeRequireMode, Why, VarSet,
ContextPieces, [Term | Terms], ArgNum, TypesAndModes, !Specs) :-
diff --git a/tests/invalid/combined_ho_type_inst.err_exp b/tests/invalid/combined_ho_type_inst.err_exp
index dcff7f8..07328dd 100644
--- a/tests/invalid/combined_ho_type_inst.err_exp
+++ b/tests/invalid/combined_ho_type_inst.err_exp
@@ -16,7 +16,8 @@ combined_ho_type_inst.m:021: In type definition: error: the type
combined_ho_type_inst.m:021: `(((func (int :: in)) = (int :: out)) is semidet)'
combined_ho_type_inst.m:021: contains higher order inst information, but this
combined_ho_type_inst.m:021: is not allowed in a type constructor's argument.
-combined_ho_type_inst.m:024: In type definition: error: the type
+combined_ho_type_inst.m:024: In type definition: in the first argument:
+combined_ho_type_inst.m:024: error: the type
combined_ho_type_inst.m:024: `(pred((int :: in), (int :: out)) is det)'
combined_ho_type_inst.m:024: contains higher order inst information, but this
combined_ho_type_inst.m:024: is not allowed in a predicate's argument.
@@ -25,7 +26,8 @@ combined_ho_type_inst.m:026: error: the type
combined_ho_type_inst.m:026: `(pred((int :: in), (int :: out)) is det)'
combined_ho_type_inst.m:026: contains higher order inst information, but this
combined_ho_type_inst.m:026: is not allowed in a predicate's argument.
-combined_ho_type_inst.m:028: In type definition: error: the type
+combined_ho_type_inst.m:028: In type definition: in the first argument:
+combined_ho_type_inst.m:028: error: the type
combined_ho_type_inst.m:028: `(((func (int :: in)) = (int :: out)) is semidet)'
combined_ho_type_inst.m:028: contains higher order inst information, but this
combined_ho_type_inst.m:028: is not allowed in a function's argument.
diff --git a/tests/invalid/combined_ho_type_inst_2.err_exp b/tests/invalid/combined_ho_type_inst_2.err_exp
index 2fcb440..20c620d 100644
--- a/tests/invalid/combined_ho_type_inst_2.err_exp
+++ b/tests/invalid/combined_ho_type_inst_2.err_exp
@@ -8,23 +8,9 @@ combined_ho_type_inst_2.m:024: In type definition: in the first argument:
combined_ho_type_inst_2.m:024: error: missing `::mode' suffix.
combined_ho_type_inst_2.m:024: In type definition: in the return value:
combined_ho_type_inst_2.m:024: error: missing `::mode' suffix.
-combined_ho_type_inst_2.m:027: In the first argument of function symbol
-combined_ho_type_inst_2.m:027: `missing_detism_p' of the type
-combined_ho_type_inst_2.m:027: `combined_ho_type_inst_2.missing_detism_p'/0:
-combined_ho_type_inst_2.m:027: error: undefined type `::'/2.
-combined_ho_type_inst_2.m:027: In the first argument of function symbol
-combined_ho_type_inst_2.m:027: `missing_detism_p' of the type
-combined_ho_type_inst_2.m:027: `combined_ho_type_inst_2.missing_detism_p'/0:
-combined_ho_type_inst_2.m:027: error: undefined type `in'/0.
-combined_ho_type_inst_2.m:030: In the first argument of function symbol
-combined_ho_type_inst_2.m:030: `missing_detism_f' of the type
-combined_ho_type_inst_2.m:030: `combined_ho_type_inst_2.missing_detism_f'/0:
-combined_ho_type_inst_2.m:030: error: undefined type `::'/2.
-combined_ho_type_inst_2.m:030: In the first argument of function symbol
-combined_ho_type_inst_2.m:030: `missing_detism_f' of the type
-combined_ho_type_inst_2.m:030: `combined_ho_type_inst_2.missing_detism_f'/0:
-combined_ho_type_inst_2.m:030: error: undefined type `in'/0.
-combined_ho_type_inst_2.m:030: In the first argument of function symbol
-combined_ho_type_inst_2.m:030: `missing_detism_f' of the type
-combined_ho_type_inst_2.m:030: `combined_ho_type_inst_2.missing_detism_f'/0:
-combined_ho_type_inst_2.m:030: error: undefined type `out'/0.
+combined_ho_type_inst_2.m:027: In type definition: in the first argument:
+combined_ho_type_inst_2.m:027: error: unexpected `::mode' suffix.
+combined_ho_type_inst_2.m:030: In type definition: in the first argument:
+combined_ho_type_inst_2.m:030: error: unexpected `::mode' suffix.
+combined_ho_type_inst_2.m:030: In type definition: in the return value:
+combined_ho_type_inst_2.m:030: error: unexpected `::mode' suffix.
More information about the reviews
mailing list