Version 1.2 of ai12s/ai12-0053-1.txt
!standard 3.2.4(31/3) 12-12-27 AI12-0053-1/02
!standard 4.6(57/3)
!class binding interpretation
!status No Action 10-0-1 12-12-08
!status work item 12-12-08
!status received 12-12-07
!priority High
!difficulty Medium
!qualifier Error
!subject Predicate failure raises Constraint_Error
!summary
Predicate failure raises Constraint_Error, not Assertion_Error.
!question
Should predicates raise Constraint_Error on failure? (Yes.)
!recommendation
See !summary.
!wording
3.2.4(31/3):
31/3 ... {Constraint_Error}[Assertions.Assertion_Error] is raised if any of
these checks fail.
4.6(57/3):
57/3 If an Accessibility_Check fails, Program_Error is raised. If a predicate
check fails, {Constraint_Error}[Assertions.Assertion_Error] is raised. Any other
check associated with a conversion raises Constraint_Error if it fails.
!discussion
Predicates need to be interchangeable with constraints, so one can switch back
and forth between them. Therefore, predicates need to raise Constraint_Error on
failure. Having them raise Assertion_Error was a mistake.
As an example, see AI12-0037-1. The Ada.Locales package was originally designed
to have these types:
type Language_Code is array (1 .. 3) of Character range 'a' .. 'z';
type Country_Code is array (1 .. 2) of Character range 'A' .. 'Z';
However, it was discovered that these types are not convertible to/from String,
which makes it rather inconvenient to do text IO. Therefore, AI12-0037-1 changed
the types to use predicates:
type Language_Code is new String(1 .. 3)
with Dynamic_Predicate => (for all E of Language_Code => (E in 'a' .. 'z'));
type Country_Code is new String(1 .. 2)
with Dynamic_Predicate => (for all E of Country_Code => (E in 'A' .. 'Z'));
Another case comes up when enumeration literals are added to an existing type.
For instance, imagine that a program contains the following declarations:
type Enum is (A, B, C, D);
subtype Sub is Enum range A .. C;
Now, we discover that we need to add a new literal in the middle of the
enumeration, but that Sub should not include that literal. We can use a
static predicate to keep the semantics of Sub the same:
type Enum is (A, B, E, C, D);
subtype Sub is Enum
with Static_Predicate => Sub in A | B | C;
In order to preserve compatibility, it is important that these kinds of changes
be possible without changing the exception that is raised on failure.
!appendix
This AI was created out of discussion on AI12-0037-1 during ARG meeting
#48 in Boston.
****************************************************************
Questions? Ask the ACAA Technical Agent