Skip to content

Commit

Permalink
U918-003: Fix name resolution of implicit /= operator.
Browse files Browse the repository at this point in the history
This is done by reworking how implicit `/=` operators are handled. In particular,
we remove the special casing done it operator name resolution and instead rely and
lexical environments only, by adding an entry for the `/=` operator whenever we
have to add an entry for a user-defined `=` operator.

This is therefore a nice cleanup.
  • Loading branch information
Roldak committed Oct 1, 2021
1 parent 7973600 commit 4036873
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 41 deletions.
93 changes: 52 additions & 41 deletions ada/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -1672,21 +1672,54 @@ def child_decl_initial_env(private_part=(T.Bool, False)):
default_val=direct_env(Self.default_initial_env)
)

@langkit_property(return_type=T.env_assoc)
def child_decl_env_assoc():
@langkit_property(return_type=T.env_assoc.array)
def basic_decl_env_assocs(dest_env=T.DesignatedEnv):
"""
Return an array of env assocs that should be added in the environment
designated by ``dest_env``. In the general case, it simply adds an
entry for Self using this declaration's name as key. However, if Self
corresponds to the declaration of a `"="` operator, we also generate
an order to add an entry for the `"/="` operator, as described in
RM 4.5.2 25.a.
"""
name = Var(Entity.name_symbol)

base_assoc = Var(
new_env_assoc(
key=Entity.name_symbol,
val=Self,
dest_env=dest_env
).singleton
)

implicit_neq_assoc = Var(If(
name == '"="',
new_env_assoc(
key='"/="',
val=Self,
dest_env=dest_env
).singleton,
No(T.env_assoc.array)
))

return base_assoc.concat(implicit_neq_assoc)

@langkit_property(return_type=T.env_assoc.array)
def child_decl_env_assocs():
"""
Return the env association that describes where to register this
basic declaration. For a child declaration in particular, this orders
adding itself inside its parent declaration's environment.

.. note::
This intercepts user-defined "=" operators so as to introduce an
implicit "/=" operator, as per RM 4.5.2 25.a.
"""
return new_env_assoc(
key=Entity.name_symbol,
val=Self,
dest_env=named_env(
Self.child_decl_initial_env_name(False),
or_current=True
)
)
dest_env = Var(named_env(
Self.child_decl_initial_env_name(False),
or_current=True
))
return Entity.basic_decl_env_assocs(dest_env)

is_formal = Property(
Self.parent.is_a(T.GenericFormal),
Expand Down Expand Up @@ -7355,7 +7388,7 @@ def env_names():
Self.child_decl_initial_env(True)
),

add_to_env(Entity.child_decl_env_assoc),
add_to_env(Entity.child_decl_env_assocs),

add_env(names=Self.env_names),

Expand Down Expand Up @@ -8228,7 +8261,7 @@ class PackageDecl(BasePackageDecl):
Self.child_decl_initial_env(True)
),

add_to_env(Entity.child_decl_env_assoc),
add_to_env(Entity.child_decl_env_assocs),

add_env(names=Self.env_names),

Expand Down Expand Up @@ -9117,7 +9150,7 @@ def body_part():
Self.child_decl_initial_env(True)
),

add_to_env(Entity.child_decl_env_assoc),
add_to_env(Entity.child_decl_env_assocs),

add_env(),

Expand Down Expand Up @@ -9180,7 +9213,7 @@ class GenericPackageDecl(GenericDecl):
Self.child_decl_initial_env(True)
),

add_to_env(Entity.child_decl_env_assoc),
add_to_env(Entity.child_decl_env_assocs),

add_env(),

Expand Down Expand Up @@ -9749,27 +9782,10 @@ def xref_equation():
lambda s: s.subp_spec_or_null.nb_max_params == 2
))

# When the operator is "/=" and there are no explicit overload, we
# might refer to the implicit declaration of the "/=" operator that
# comes with any overload of "=" that returns a Boolean.
refers_to_synthetic_neq = Var(And(
subps.length == 0,
Self.op.subprogram_symbol == '"/="'
))

# So if that's the case, look for declarations of "="
refined_subps = Var(If(
refers_to_synthetic_neq,
Self.op.subprograms_for_symbol('"="', Entity).filter(
lambda s: s.subp_spec_or_null.nb_max_params == 2
),
subps
))

return (
Entity.left.sub_equation
& Entity.right.sub_equation
) & (refined_subps.logic_any(lambda subp: Let(
) & (subps.logic_any(lambda subp: Let(
lambda ps=subp.subp_spec_or_null.unpacked_formal_params:

# The subprogram's first argument must match Self's left
Expand All @@ -9788,9 +9804,7 @@ def xref_equation():
& Self.type_bind_val(Self.type_var,
subp.subp_spec_or_null.return_type)

# The operator references the subprogram. We decide to make the
# implicitly generated '/=' refer to the '=' subprogram, if it
# exists.
# The operator references the subprogram
& Bind(Self.op.ref_var, subp)
& Bind(Self.op.subp_spec_var, subp.subp_spec_or_null)
)) | Self.no_overload_equation)
Expand Down Expand Up @@ -15370,12 +15384,9 @@ def previous_part_env_name():
)
),

add_to_env_kv(
key=Entity.name_symbol,
val=Self,
dest_env=named_env(
Self.initial_env_name(False),
or_current=True
add_to_env(
Entity.basic_decl_env_assocs(
named_env(Self.initial_env_name(False), or_current=True)
)
),

Expand Down
5 changes: 5 additions & 0 deletions testsuite/tests/name_resolution/synthetic_neq/test.adb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ begin
raise Program_Error;
end if;
pragma Test_Statement;

if "/=" (A, B) then
raise Program_Error;
end if;
pragma Test_Statement;
end Main;
16 changes: 16 additions & 0 deletions testsuite/tests/name_resolution/synthetic_neq/test.out
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,21 @@ Expr: <Id "B" test.adb:12:12-12:13>
references: <DefiningName test.adb:10:7-10:8>
type: <TypeDecl ["T"] test.adb:3:7-3:29>

Resolving xrefs for node <IfStmt test.adb:17:4-19:11>
*****************************************************

Expr: <CallExpr test.adb:17:7-17:18>
references: <DefiningName test.adb:5:16-5:19>
type: <TypeDecl ["Boolean"] __standard:3:3-3:33>
Expr: <Str ""/="" test.adb:17:7-17:11>
references: <DefiningName test.adb:5:16-5:19>
type: <TypeDecl ["Boolean"] __standard:3:3-3:33>
Expr: <Id "A" test.adb:17:13-17:14>
references: <DefiningName test.adb:10:4-10:5>
type: <TypeDecl ["T"] test.adb:3:7-3:29>
Expr: <Id "B" test.adb:17:16-17:17>
references: <DefiningName test.adb:10:7-10:8>
type: <TypeDecl ["T"] test.adb:3:7-3:29>


Done.

0 comments on commit 4036873

Please sign in to comment.