I get Subtype mark required in this context
at (*)
. What exactly is subtype mask and why is it complaining here?
main.adb
(*)Open_Route : Route(1..3) := (others => new Location(X=>1.0,Y=>1.0, id=>1));
-- Closed_Route : Route (Open_Route'First .. Open_Route'Last + 1);
-- P1 : Population (1..2);
Location.ads package spec
type Location is record
Id : Positive;
X : Float;
Y : Float;
end record;
type Location_Acess is access all Location;
type Route is array (Positive range<>) of Location_Acess;
type Route_Acess is access all Route;
type Population is array (Positive range<>) of Route_Acess;
A subtype_mark is basically a name that denotes a type or subtype (ARM 3.2.2(4)). The reason why the ARM uses subtype_mark throughout is to do with some arcane distinction (ARM 3.2.1); when you say type Foo is
you are declaring both a type and its first subtype, and the name Foo
refers to the first subtype.
I think your problem is that you have a package Location
containing an entity of the same name, and that this has confused the compiler.
You haven’t supplied a complete compilable code example, but reading between the lines I think it’d be something like this, after applying @ajb’s suggestion:
package Location is
type Location is record
Id : Positive;
X : Float;
Y : Float;
end record;
type Location_Acess is access all Location;
type Route is array (Positive range<>) of Location_Acess;
type Route_Acess is access all Route;
type Population is array (Positive range<>) of Route_Acess;
end Location;
with Location; use Location;
package Location_User is
Open_Route : Route(1..3) := (others => new Location'(X=>1.0,Y=>1.0, id=>1));
end Location_User;
and the compiler error message would be
location_user.ads:3:47: subtype mark required in this context
location_user.ads:3:47: found "Location" declared at location.ads:1
(see how it’s telling you to look at line 1 of location.ads
, the package name?)
You could work round this by saying new Location.Location
, but then you’d need to say it everywhere.
There are two canonical solutions, and there is a religious divide between the supporters of the two camps.
The first (my preferred one) would be to call the package Locations
and leave the types Location
, Route
, Population
as they are.
The second (which I consider ugly and would only use in dire need) would be to decorate type names with a suffix:
type Location_Type is
or
type Location_T is
The source code given in the question is not complete (you did not state whether you used or merely withed the Location package. I assume the latter since (at least with the compiler I have installed) the error message given is invalid constraint: type has no discriminant.
@ajb has already pointed out the solution to that problem: without the quote mark, the compiler looks for a type with a discriminant (a type parameterised by another type), but Location does not have a discriminant.
Moreover, unless you used the Location package, new Location
does not actually refer to a type (or subtype), but to a package. If you do not want to use Location, type
new Location.Location'(…
here. One way to avoid such errors (and get better error messages) is to use different names for packages and type: when both have the same name, it is not always intuitively clear how the compiler interprets the occurrence of the name, and when the opinions of compiler and programmer differ, confusion ensues.
Personally, I like to use the plural for for the package, so in this case, there would be a package Locations containing the type Location, but there are other possibilities.