An illegal one-element positional aggregate is usually detected as a type
error. If the expected type is a one-component record, it is possible to
indicate what the proper syntax should be. A similar suggestion can be given
if the context specifies a nameable array type or the target of an assignment.
However, the suggestion is not as precise for subaggregates of multidimensional
arrays.
The following displays the improved error messages:
Compiling: p1.adb (source file time stamp: 2011-03-04 16:14:14)
1. procedure P1 is
2. type Sequence is array (integer range <>) of Float;
3.
4. type T_1 is record
5. R_2 : integer;
6. end record;
7.
8. type Table is array (1..2, 1..1) of integer;
9. T : Table := ((0), (0));
|
>>> nested array aggregate expected
>>> if single-component aggregate is intended, write e.g. (1 => ...)
10.
11. V_D4 : array ( 1..1) of T_1 :=
12. (1 => ( 1));
|
>>> positional aggregate cannot have one component
>>> write instead "R_2 => ..."
13.
14. Thing : T_1 := (5);
|
>>> positional aggregate cannot have one component
>>> write instead "R_2 => ..."
15.
16. It : Sequence := (3.1415);
|
>>> positional aggregate cannot have one component
>>> write instead "Sequence'First => ..."
17.
18. subtype Yes is boolean range True .. True;
19. type Vacuous is array (Yes) of Float;
20. Oui : Vacuous := (1.0);
|
>>> positional aggregate cannot have one component
>>> write instead "Vacuous'First => ..."
21.
22. subtype Name is String (1 .. 5);
23. That : name := "That ";
24. type Names is array (1..2, 1..5) of character;
25. Them : Names := ("this ", (that));
|
>>> nested array aggregate expected
>>> if single-component aggregate is intended, write e.g. (1 => ...)
26.
27. Anon : array (1..1) of Boolean;
28.
29. begin
30. It := (2.7179);
|
>>> positional aggregate cannot have one component
>>> write instead "Sequence'First => ..."
31.
32. Anon := (False);
|
>>> positional aggregate cannot have one component
>>> write instead "Anon'First => ..."
33. end P1;
Tested on x86_64-pc-linux-gnu, committed on trunk
2011-08-04 Ed Schonberg <[email protected]>
* sem_util.adb:(Wrong_Type): Improve error message on a one-element
positional aggregate.
Index: sem_util.adb
===================================================================
--- sem_util.adb (revision 177328)
+++ sem_util.adb (working copy)
@@ -12478,9 +12478,13 @@
----------------
procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id) is
- Found_Type : constant Entity_Id := First_Subtype (Etype (Expr));
- Expec_Type : constant Entity_Id := First_Subtype (Expected_Type);
+ Found_Type : constant Entity_Id := First_Subtype (Etype (Expr));
+ Expec_Type : constant Entity_Id := First_Subtype (Expected_Type);
+ Matching_Field : Entity_Id;
+ -- Entity to give a more precise suggestion on how to write a one-
+ -- element positional aggregate.
+
function Has_One_Matching_Field return Boolean;
-- Determines if Expec_Type is a record type with a single component or
-- discriminant whose type matches the found type or is one dimensional
@@ -12494,11 +12498,27 @@
E : Entity_Id;
begin
+ Matching_Field := Empty;
+
if Is_Array_Type (Expec_Type)
and then Number_Dimensions (Expec_Type) = 1
and then
Covers (Etype (Component_Type (Expec_Type)), Found_Type)
then
+ -- Use type name if available. This excludes multidimensional
+ -- arrays and anonymous arrays.
+
+ if Comes_From_Source (Expec_Type) then
+ Matching_Field := Expec_Type;
+
+ -- For an assignment, use name of target.
+
+ elsif Nkind (Parent (Expr)) = N_Assignment_Statement
+ and then Is_Entity_Name (Name (Parent (Expr)))
+ then
+ Matching_Field := Entity (Name (Parent (Expr)));
+ end if;
+
return True;
elsif not Is_Record_Type (Expec_Type) then
@@ -12529,6 +12549,7 @@
return False;
else
+ Matching_Field := E;
return True;
end if;
end if;
@@ -12577,7 +12598,17 @@
and then Has_One_Matching_Field
then
Error_Msg_N ("positional aggregate cannot have one component", Expr);
+ if Present (Matching_Field) then
+ if Is_Array_Type (Expec_Type) then
+ Error_Msg_NE
+ ("\write instead `&''First ='> ...`", Expr, Matching_Field);
+ else
+ Error_Msg_NE
+ ("\write instead `& ='> ...`", Expr, Matching_Field);
+ end if;
+ end if;
+
-- Another special check, if we are looking for a pool-specific access
-- type and we found an E_Access_Attribute_Type, then we have the case
-- of an Access attribute being used in a context which needs a pool-