the container type is a derived type, the value of the inherited aspect is the Reference (or Constant_Reference) operation declared for the parent type. However, Reference is also a primitive operation of the new type, and the inherited operation has a different signature. It is necessary to retrieve the right operation from the list of primitive operations of the derived type.
Compiling and executing the following must yield: 2 10 111 1 --- with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Containers.Doubly_Linked_Lists; with Ada.Containers.Indefinite_Hashed_Maps; with Ada.Strings.Hash; use Ada.Containers; with Text_IO; use Text_IO; procedure Derived_Container is function Same_Strings (S, T : String) return Boolean is begin return To_Lower (S) = To_Lower (T); end Same_Strings; type Place is record Page : Positive; Line : Positive; Col : Positive; end record; package Places is new Doubly_Linked_Lists (Place); package Indexes is new Indefinite_Hashed_Maps (Key_Type => String, Element_Type => Places.List, Hash => Ada.Strings.Hash, Equivalent_Keys => Same_Strings, "=" => Places."="); type Text_Map is new Indexes.Map with null record; -- with Variable_Indexing => Reference; -- Without aspect, indexing gives -- "container cannot be indexed with "Cursor"" My_Index : Text_Map; My_Place : constant Place := (1, 2, 3); use type Indexes.Cursor; procedure Add_Entry (The_Index : in out Text_Map; Word : String; P : Place) is M_Cursor : Indexes.Cursor; New_List : Places.List := Places.Empty_List; begin M_Cursor := The_Index.Find (Word); if M_Cursor /= Indexes.No_Element then The_Index (M_Cursor).Append (P); else New_List.Append (P); The_Index.Include (Word, New_List); end if; end Add_Entry; begin Add_Entry (The_Index => My_Index, Word => "bill", P => My_Place); Add_Entry (The_Index => My_Index, Word => "John", P => (10, 10, 10)); Add_Entry (The_Index => My_Index, Word => "John", P => (111, 333, 999)); Put_Line (Integer'Image (Integer (My_Index.Length))); for Datum of My_Index loop for Location of Datum loop Put_Line (Integer'Image (Location.Page)); end loop; end loop; end Derived_Container; Tested on x86_64-pc-linux-gnu, committed on trunk 2014-07-18 Ed Schonberg <schonb...@adacore.com> * sem_ch4.adb (Try_Container_Indexing): If the container type is a derived type, the value of the inherited aspect is the Reference operation declared for the parent type. However, Reference is also a primitive operation of the new type, and the inherited operation has a different signature. We retrieve the right one from the list of primitive operations of the derived type.
Index: sem_ch4.adb =================================================================== --- sem_ch4.adb (revision 212779) +++ sem_ch4.adb (working copy) @@ -7020,6 +7020,16 @@ else return False; end if; + + -- If the container type is a derived type, the value of the inherited + -- aspect is the Reference operation declared for the parent type. + -- However, Reference is also a primitive operation of the type, and + -- the inherited operation has a different signature. We retrieve the + -- right one from the list of primitive operations of the derived type. + + elsif Is_Derived_Type (Etype (Prefix)) then + Func := Find_Prim_Op (Etype (Prefix), Chars (Func_Name)); + Func_Name := New_Occurrence_Of (Func, Loc); end if; Assoc := New_List (Relocate_Node (Prefix));