Ada Reference Manual (Ada 2022)
4.5.9 Declare Expressions
Declare expressions provide a way to declare local constants and object renamings in an expression context.
Syntax
Wherever the Syntax Rules allow an expression, a declare_expression may be used in place of the expression, so long as it is immediately surrounded by parentheses.
Legality Rules
A declare_item that is an object_declaration shall declare a constant of a nonlimited type.
A declare_item that is an object_renaming_declaration (see 8.5.1) shall not rename an object of a limited type if any operative constituent of the object_name is a value conversion or is newly constructed (see 4.4).
The following are not allowed within a declare_expression: a declaration containing the reserved word aliased; the attribute_designator Access or Unchecked_Access; or an anonymous access type.
Name Resolution Rules
If a declare_expression is expected to be of a type T, then the body_expression is expected to be of type T. Similarly, if a declare_expression is expected to be of some class of types, then the body_expression is subject to the same expectation. If a declare_expression shall resolve to be of a type T, then the body_expression shall resolve to be of type T.
The type of a declare_expression is the type of the body_expression.
Dynamic Semantics
For the evaluation of a declare_expression, the declare_items are elaborated in order, and then the body_expression is evaluated. The value of the declare_expression is that of the body_expression.
Examples
Example of use of a declare expression as a replacement postcondition for Ada.Containers.Vectors."&" (see A.18.2):
with Post =>
(declare
Result renames Vectors."&"'Result;
Length : constant Count_Type := Left.Length + Right.Length;
begin
Result.Length = Length and then
not Tampering_With_Elements_Prohibited (Result) and then
not Tampering_With_Cursors_Prohibited (Result) and then
Result.Capacity >= Length)
(declare
Result renames Vectors."&"'Result;
Length : constant Count_Type := Left.Length + Right.Length;
begin
Result.Length = Length and then
not Tampering_With_Elements_Prohibited (Result) and then
not Tampering_With_Cursors_Prohibited (Result) and then
Result.Capacity >= Length)