# Weird error: nonoverridable aspect "String\_Literal"

**URL:** https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603
**Category:** General
**Created:** [August 1, 2026, 8:54am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603 "2026-08-01T08:54:31Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Blady](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/b/e9bcb4/32.png) [@Blady](https://forum.ada-lang.io/u/Blady)
#### Post date: [August 1, 2026, 8:54am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/1 "2026-08-01T08:54:31Z")

</div>

Consider this code:  
(from AARM 4.2.1 User-Defined Literals)

```ada
13. Max_Roman_Number : constant := 3_999; -- MMMCMXCIX
14. 
15. type Roman_Number is range 1 .. Max_Roman_Number
16. with String_Literal => To_Roman_Number;
17. 
18. function To_Roman_Number (S : Wide_Wide_String) return Roman_Number;

```

I got:  
`error: nonoverridable aspect "String_Literal" of type "Roman_Number" requires "To_Roman_Number" declared at line 18 to be a primitive operation`

What could its meaning possibly be?

---

<div class="post-metadata">

### Author: ![Irvise](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/i/7ba0ec/32.png) [@Irvise](https://forum.ada-lang.io/u/Irvise)
#### Post date: [August 1, 2026, 9:14am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/2 "2026-08-01T09:14:12Z")

</div>

Are you compiling with Ada 2022 enabled? `-gnat2022`

IIRC `String_Literal` is Ada 2022 only. The error may come from an issue in the compiler not detecting correctly the function.

---

<div class="post-metadata">

### Author: ![liampwll](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/l/b19c9b/32.png) [@liampwll](https://forum.ada-lang.io/u/liampwll)
#### Post date: [August 1, 2026, 9:30am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/3 "2026-08-01T09:30:05Z")

</div>

The error is correct but not useful if you’re doing what I think you’re doing. Put your declarations inside of a package and it should work. I don’t remember off the top of my head why a package is required, however I do remember that that RM is very clear about the fact that it is.

---

<div class="post-metadata">

### Author: ![liampwll](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/l/b19c9b/32.png) [@liampwll](https://forum.ada-lang.io/u/liampwll)
#### Post date: [August 1, 2026, 9:48am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/4 "2026-08-01T09:48:39Z")

</div>

It comes from the definition of primitives in 3.2.3, specifically the fact that there’s no equivalent of this for declarative regions:

> For a specific type declared immediately within a package\_specification, any subprograms (in addition to the enumeration literals) that are explicitly declared immediately within the same package\_specification and that operate on the type

---

<div class="post-metadata">

### Author: ![Blady](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/b/e9bcb4/32.png) [@Blady](https://forum.ada-lang.io/u/Blady)
#### Post date: [August 1, 2026, 10:01am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/5 "2026-08-01T10:01:39Z")

</div>

Thanks for quoting that!

It’s not very clear to me why operations are not primitive in a procedure declaration part.

Note: declaring a package in the procedure declaration part solve the issue!

```ada
procedure Test_SL_decl is
   package Roman is
   Max_Roman_Number : constant := 3_999; -- MMMCMXCIX
   type Roman_Number is range 1 .. Max_Roman_Number
     with String_Literal => To_Roman_Number;
   function To_Roman_Number (S : Wide_Wide_String) return Roman_Number;
   end;
...
 X : Roman.Roman_Number;
...

```

Both RM and GNAT compiler messages should be clearer on this topic.

@Irvise Yes with -gnat2022, I hadn’t mentioned it.

---

<div class="post-metadata">

### Author: ![pmnw](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/p/c37758/32.png) [@pmnw](https://forum.ada-lang.io/u/pmnw)
#### Post date: [August 1, 2026, 9:38pm UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/6 "2026-08-01T21:38:01Z")

</div>

I encountered something similar when playing with the Put\_Image aspect, but I cannot reproduce it with your code.  
It would be better if you provided a reproducible example.

The following compiles with `$ gnatmake test_sl_decl.adb` and GCC 14.3.1 and with 16.1.0 (no -gnat2022 needed).

```ada
with Ada.Text_IO;
procedure Test_SL_decl is

   Max_Roman_Number : constant := 3_999; -- MMMCMXCIX
   type Roman_Number is range 1 .. Max_Roman_Number
     with String_Literal => To_Roman_Number;
   function To_Roman_Number (S : Wide_Wide_String) return Roman_Number is (1);

   X : constant Roman_Number := "I";
begin
   Ada.Text_IO.Put_Line (X'Image);
end Test_SL_decl;

```

---

<div class="post-metadata">

### Author: ![Blady](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/b/e9bcb4/32.png) [@Blady](https://forum.ada-lang.io/u/Blady)
#### Post date: [August 2, 2026, 7:47am UTC](https://forum.ada-lang.io/t/weird-error-nonoverridable-aspect-string-literal/4603/7 "2026-08-02T07:47:42Z")

</div>

> [@pmnw](#):
>
> It would be better if you provided a reproducible example.

Full code:

```ada
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_20200613_decl is
   type Roman_Digit is ('I', 'V', 'X', 'L', 'C', 'D', 'M');
   for Roman_Digit use ('I' => 1, 'V' => 5, 'X' => 10, 'L' => 50, 'C' => 100, 'D' => 500, 'M' => 1000);
   subtype Roman_Character is Wide_Wide_Character with
     Static_Predicate => Roman_Character in 'I' | 'V' | 'X' | 'L' | 'C' | 'D' | 'M';
   Max_Roman_Number : constant := 3_999; -- MMMCMXCIX

   type Roman_Number is range 1 .. Max_Roman_Number
     with String_Literal => To_Roman_Number;

   function To_Roman_Number (S : Wide_Wide_String) return Roman_Number
     with Pre => S'Length > 0 and then
     (for all Char of S => Char in Roman_Character);

   function To_Roman_Number (S : Wide_Wide_String) return Roman_Number is
     (declare
      R : constant array (Integer range <>) of Roman_Number :=
      (for D in S'Range => Roman_Digit'Enum_Rep
       (Roman_Digit'Wide_Wide_Value (''' & S(D) & '''))); -- See 3.5.2 and 13.4
      begin
      [for I in R'Range =>
        (if I < R'Last and then R(I) < R(I + 1) then -1 else 1) * R(I)]
                          'Reduce("+", 0) );

      X : Roman_Number := "III" * "IV" * "XII"; -- 144 (that is, CXLIV)
   begin
      Put_Line ("III * IV * XII is " & X'Image);
   end;

```
