# Visibility rules. Variables against procedures (functions, literals, packages)

**URL:** https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573
**Category:** General
**Created:** [July 13, 2026, 3:51pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573 "2026-07-13T15:51:00Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [July 13, 2026, 3:51pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/1 "2026-07-13T15:51:00Z")

</div>

Consider the following:

```ada
procedure Test is
   package P1 is
      procedure F;
   end P1;
   package body P1 is
      procedure F is
      begin
         null;
      end F;
   end P1;
   package P2 is
      F : Boolean := False;
   end P2;
   use P1, P2;
begin
   F; -- GNAT: Multiple use clauses cause hiding
end Test;

```

Is this correct? Subprograms are overloaded. Objects hide each other. The latter wins over the former, at least according to GNAT.

I suppose that the relevant text why one F hides another is hidden somewhere in [ARM 8.3](https://www.adaic.org/resources/add_content/standards/22aarm/html/AA-8-3.html). Can anybody find it?

---

<div class="post-metadata">

### Author: ![OneWingedShark](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/onewingedshark/32/305_2.png) [@OneWingedShark](https://forum.ada-lang.io/u/OneWingedShark)
#### Post date: [July 13, 2026, 4:02pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/2 "2026-07-13T16:02:49Z")

</div>

The trivial workaround is, of course, `renames` — but for this particular instance, I think its overloading resolution disambiguating: the procedure has no return, the object is `Boolean`, since there is no value-handling it must be the procedure-call. Absent this, I’m pretty sure this would be in error: ambiguous names.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [July 13, 2026, 4:21pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/3 "2026-07-13T16:21:49Z")

</div>

There is nothing to resolve here, I mean it is unambiguous on the syntax level. `F;` is a call statement.

But my question was what sentence of the ARM mandated this behaviour?

---

<div class="post-metadata">

### Author: ![OneWingedShark](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/onewingedshark/32/305_2.png) [@OneWingedShark](https://forum.ada-lang.io/u/OneWingedShark)
#### Post date: [July 13, 2026, 4:36pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/4 "2026-07-13T16:36:54Z")

</div>

…you just did the resolution, saying “it’s a call statement” _ **is** _ the disambiguation’s result.

As to which rule; try changing `F` to `Function F return Boolean;`, updating the call to an assignment to local variable, and noting the error message which you should get: often there’s an RM rule attached to errors. (It would be nice if there was an RM note/link for each error; I think there were other [non-GNAT] compilers that did that.)

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [July 13, 2026, 5:03pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/5 "2026-07-13T17:03:01Z")

</div>

> [@OneWingedShark](#):
>
> …you just did the resolution, saying “it’s a call statement” _ **is** _ the disambiguation’s result.

No, **hiding** does not work this way. In order to disambiguate, resolve whatever you name it, you must have the symbol **visible** in the context. Hiding makes the symbol **invisible**. There is no any F whatsoever. This what hiding is. F is nuked, gone.

My question is where ARM mandates that an **object** declaration attempted to be made visible must hide everything rather than only objects. Does it?

---

<div class="post-metadata">

### Author: ![Nordic\_Dogsledding](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/nordic_dogsledding/32/547_2.png) [@Nordic\_Dogsledding](https://forum.ada-lang.io/u/Nordic_Dogsledding)
#### Post date: [July 14, 2026, 9:20am UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/6 "2026-07-14T09:20:56Z")

</div>

\*\* See **RM Index**

visibility  
direct 8.3(2), 8.3(21)  
immediate 8.3(4), 8.3(21)  
use clause 8.3(4), 8.4(9)

**RM 8.3 Visibility**

(2) _directly visible_

(4) _immediate visibility_ vs. _use-visibility_

Your **F** declarations are **use-visibile**.

(6) _overloaded_

Your **F** declarations are **not overloaded** since they are **not directly visible**.

(8) _homographs_

Your **F** declarations are **homographs** but only one of them is _overloadable_.

**RM 8.4 Use Clauses**

(11) Potentially use-visible declarations that have the same identifier are not use-visible unless each of them is an overloadable declaration.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [July 14, 2026, 9:49am UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/7 "2026-07-14T09:49:12Z")

</div>

Thanks! 8.4(11) does it.

A good candidate for an AI, IMO: _overloadable declarations cannot be hidden unless made abstract_.

---

<div class="post-metadata">

### Author: ![Nordic\_Dogsledding](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/nordic_dogsledding/32/547_2.png) [@Nordic\_Dogsledding](https://forum.ada-lang.io/u/Nordic_Dogsledding)
#### Post date: [July 14, 2026, 1:45pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/8 "2026-07-14T13:45:52Z")

</div>

> [@dmitry-kazakov](#):
>
> ```ada
> procedure Test is
> package P1 is
> function F return Boolean;
> end P1;
> package body P1 is
> function F is
> begin
> return True;
> end F;
> end P1;
> package P2 is
> F: Boolean := False;
> end P2;
> use P1, P2;
> begin
> if F then ...; 
> end Test;
> 
> ```

How to resolve this with your proposed new rule?

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [July 14, 2026, 3:08pm UTC](https://forum.ada-lang.io/t/visibility-rules-variables-against-procedures-functions-literals-packages/4573/9 "2026-07-14T15:08:20Z")

</div>

> [@Nordic\_Dogsledding](#):
>
> How to resolve this with your proposed new rule?

As always: P1.F, P2.F.

After all without objects involved anything goes:

```ada
procedure Test is
  package P1 is
    type X is ('F');
  end P1;
  package P2 is
    type Y is ('F');
  end P2;
  use P1, P2;
  Z : X;
begin
   if 'F' = Z then -- This is perfectly OK
      null;
   end if; 
end Test;

```

P.S. I do not understand the reason why is necessary in case of use-clauses and just leaving it ambiguous were not enough. (Nesting scopes + objects is a different case.)

If one really wanted being that rigorous, then one could rather make the conflicting use-clause illegal.
