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 <schonb...@adacore.com> * 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-