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

Consider the following:

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. Can anybody find it?

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.

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?

…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.)

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?

** 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.

Thanks! 8.4(11) does it.

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

How to resolve this with your proposed new rule?

As always: P1.F, P2.F.

After all without objects involved anything goes:

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.