Skip to content

Commit

Permalink
Introduce dedicated ForLoopIterFilter node to fix their name resolution.
Browse files Browse the repository at this point in the history
  • Loading branch information
Roldak committed Nov 21, 2023
1 parent 450b226 commit 4a1d2ff
Show file tree
Hide file tree
Showing 11 changed files with 558 additions and 241 deletions.
47 changes: 29 additions & 18 deletions ada/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -12664,16 +12664,6 @@ def expected_type_var():
"""
)

xref_stop_resolution = Property(
# Pause resolution of ForLoopSpecs' iterator filter expression, so
# that the indexing variable's type can be fully inferred first.
# Otherwise, any reference to the indexing variable appearing in the
# filter expression will cause an infinite xref_equation recursion.
Self.parent.cast(T.ForLoopSpec).then(
lambda spec: spec.iter_filter == Self
)
)

@langkit_property(return_type=T.Bool)
def has_context_free_type():
"""
Expand Down Expand Up @@ -19430,7 +19420,7 @@ class ForLoopSpec(LoopSpec):
loop_type = Field(type=IterType)
has_reverse = Field(type=Reverse)
iter_expr = Field(type=T.AdaNode)
iter_filter = Field(type=T.Expr)
iter_filter = Field(type=T.ForLoopIterFilter)

@langkit_property(return_type=Bool)
def is_iterated_assoc_spec():
Expand Down Expand Up @@ -19499,13 +19489,6 @@ def xref_equation():
conv_prop=BaseTypeDecl.iterable_comp_type_or_null),
default_val=LogicFalse()
)

) & If(
Entity.iter_filter.is_null,
LogicTrue(),
Bind(Self.iter_filter.expected_type_var, Self.bool_type)
& Bind(Self.iter_filter.type_var, Self.bool_type)
& Entity.iter_filter.sub_equation
)

# This spec is not a complete resolution context when part of an iterated
Expand All @@ -19514,6 +19497,34 @@ def xref_equation():
xref_entry_point = Property(Not(Self.is_iterated_assoc_spec))


class ForLoopIterFilter(AdaNode):
"""
Represent the ``when ...`` filter after a for loop specification. This
class has no RM existence, it is used internally to wrap the filtering
expression, so as to have a dedicated name resolution entry point for it
and make sure it is resolved separatly from the ``ForLoopSpec`` itself
(which it cannot influence anyway).
"""
expr = Field(type=T.Expr)

@langkit_property(return_type=Equation)
def xref_equation():
ignore(Var(Entity.parent.cast(ForLoopSpec).then(
lambda spec: If(
spec.is_iterated_assoc_spec,
spec.resolve_names_from_closest_entry_point,
True
)
)))
return And(
Bind(Self.expr.expected_type_var, Self.bool_type),
Entity.expr.sub_equation,
Entity.expr.matches_expected_formal_prim_type
)

xref_entry_point = Property(True)


class QuantifiedExpr(Expr):
"""
Quantified expression (:rmlink:`4.5.8`).
Expand Down
2 changes: 1 addition & 1 deletion ada/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ def end_named_block():
IterType.alt_in("in") | IterType.alt_of("of"),
Reverse("reverse"),
A.discrete_range | A.discrete_subtype_indication | A.name,
Opt("when", A.expr)
Opt(ForLoopIterFilter("when", A.expr))
),

quantified_expr=QuantifiedExpr(
Expand Down
4 changes: 1 addition & 3 deletions testsuite/tests/name_resolution/container_aggregate/pkg.adb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ package body Pkg is

procedure P (Arr : Arr_T) is
Set1 : Set := [for E of Arr when E < 0 => E];
pragma Test_Statement;
Set2 : Set := [for E of Arr when E < 0 or else E > 0 => E];
pragma Test_Statement;
Set3 : Set := [for Item in 1 .. 5 => Item * 2];
pragma Test_Statement;
begin
null;
end P;
pragma Test_Block;
end Pkg;
108 changes: 72 additions & 36 deletions testsuite/tests/name_resolution/container_aggregate/test.out
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@ Expr: <Str ""[email protected]"" test3.adb:70:21-70:38>
Analyzing pkg.adb
#################

Resolving xrefs for node <SubpSpec pkg.adb:10:4-10:29>
******************************************************


Resolving xrefs for node <ParamSpec ["Arr"] pkg.adb:10:17-10:28>
****************************************************************

Expr: <Id "Arr_T" pkg.adb:10:23-10:28>
references: <DefiningName "Arr_T" pkg.ads:2:9-2:14>
type: None
expected type: None

Resolving xrefs for node <ObjectDecl ["Set1"] pkg.adb:11:7-11:52>
*****************************************************************

Expand All @@ -247,6 +259,14 @@ Expr: <Id "Arr" pkg.adb:11:31-11:34>
references: <DefiningName "Arr" pkg.adb:10:17-10:20>
type: <ConcreteTypeDecl ["Arr_T"] pkg.ads:2:4-2:55>
expected type: None
Expr: <Id "E" pkg.adb:11:49-11:50>
references: <DefiningName "E" pkg.adb:11:26-11:27>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Resolving xrefs for node <ForLoopIterFilter pkg.adb:11:35-11:45>
****************************************************************

Expr: <RelationOp pkg.adb:11:40-11:45>
type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
expected type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
Expand All @@ -262,108 +282,124 @@ Expr: <Int pkg.adb:11:44-11:45>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <Id "E" pkg.adb:11:49-11:50>
references: <DefiningName "E" pkg.adb:11:26-11:27>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Resolving xrefs for node <ObjectDecl ["Set2"] pkg.adb:13:7-13:66>
Resolving xrefs for node <ObjectDecl ["Set2"] pkg.adb:12:7-12:66>
*****************************************************************

Expr: <Id "Set" pkg.adb:13:14-13:17>
Expr: <Id "Set" pkg.adb:12:14-12:17>
references: <DefiningName "Set" pkg.adb:8:12-8:15>
type: None
expected type: None
Expr: <BracketAggregate pkg.adb:13:21-13:65>
Expr: <BracketAggregate pkg.adb:12:21-12:65>
type: <SubtypeDecl ["Set"] pkg.adb:8:4-8:32>
expected type: <SubtypeDecl ["Set"] pkg.adb:8:4-8:32>
Expr: <Id "Arr" pkg.adb:13:31-13:34>
Expr: <Id "Arr" pkg.adb:12:31-12:34>
references: <DefiningName "Arr" pkg.adb:10:17-10:20>
type: <ConcreteTypeDecl ["Arr_T"] pkg.ads:2:4-2:55>
expected type: None
Expr: <BinOp pkg.adb:13:40-13:59>
Expr: <Id "E" pkg.adb:12:63-12:64>
references: <DefiningName "E" pkg.adb:12:26-12:27>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Resolving xrefs for node <ForLoopIterFilter pkg.adb:12:35-12:59>
****************************************************************

Expr: <BinOp pkg.adb:12:40-12:59>
type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
expected type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
Expr: <RelationOp pkg.adb:13:40-13:45>
Expr: <RelationOp pkg.adb:12:40-12:45>
type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
expected type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
Expr: <Id "E" pkg.adb:13:40-13:41>
references: <DefiningName "E" pkg.adb:13:26-13:27>
Expr: <Id "E" pkg.adb:12:40-12:41>
references: <DefiningName "E" pkg.adb:12:26-12:27>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <OpLt "<" pkg.adb:13:42-13:43>
Expr: <OpLt "<" pkg.adb:12:42-12:43>
references: None
type: None
expected type: None
Expr: <Int pkg.adb:13:44-13:45>
Expr: <Int pkg.adb:12:44-12:45>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <OpOrElse "or else" pkg.adb:13:46-13:53>
Expr: <OpOrElse "or else" pkg.adb:12:46-12:53>
references: None
type: None
expected type: None
Expr: <RelationOp pkg.adb:13:54-13:59>
Expr: <RelationOp pkg.adb:12:54-12:59>
type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
expected type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
Expr: <Id "E" pkg.adb:13:54-13:55>
references: <DefiningName "E" pkg.adb:13:26-13:27>
Expr: <Id "E" pkg.adb:12:54-12:55>
references: <DefiningName "E" pkg.adb:12:26-12:27>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <OpGt ">" pkg.adb:13:56-13:57>
Expr: <OpGt ">" pkg.adb:12:56-12:57>
references: None
type: None
expected type: None
Expr: <Int pkg.adb:13:58-13:59>
Expr: <Int pkg.adb:12:58-12:59>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <Id "E" pkg.adb:13:63-13:64>
references: <DefiningName "E" pkg.adb:13:26-13:27>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Resolving xrefs for node <ObjectDecl ["Set3"] pkg.adb:15:7-15:54>
Resolving xrefs for node <ObjectDecl ["Set3"] pkg.adb:13:7-13:54>
*****************************************************************

Expr: <Id "Set" pkg.adb:15:14-15:17>
Expr: <Id "Set" pkg.adb:13:14-13:17>
references: <DefiningName "Set" pkg.adb:8:12-8:15>
type: None
expected type: None
Expr: <BracketAggregate pkg.adb:15:21-15:53>
Expr: <BracketAggregate pkg.adb:13:21-13:53>
type: <SubtypeDecl ["Set"] pkg.adb:8:4-8:32>
expected type: <SubtypeDecl ["Set"] pkg.adb:8:4-8:32>
Expr: <BinOp pkg.adb:15:34-15:40>
Expr: <BinOp pkg.adb:13:34-13:40>
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
Expr: <Int pkg.adb:15:34-15:35>
Expr: <Int pkg.adb:13:34-13:35>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
Expr: <OpDoubleDot ".." pkg.adb:15:36-15:38>
Expr: <OpDoubleDot ".." pkg.adb:13:36-13:38>
references: None
type: None
expected type: None
Expr: <Int pkg.adb:15:39-15:40>
Expr: <Int pkg.adb:13:39-13:40>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
Expr: <BinOp pkg.adb:15:44-15:52>
Expr: <BinOp pkg.adb:13:44-13:52>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <Id "Item" pkg.adb:15:44-15:48>
references: <DefiningName "Item" pkg.adb:15:26-15:30>
Expr: <Id "Item" pkg.adb:13:44-13:48>
references: <DefiningName "Item" pkg.adb:13:26-13:30>
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <OpMult "*" pkg.adb:15:49-15:50>
Expr: <OpMult "*" pkg.adb:13:49-13:50>
references: None
type: None
expected type: None
Expr: <Int pkg.adb:15:51-15:52>
Expr: <Int pkg.adb:13:51-13:52>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Resolving xrefs for node <NullStmt pkg.adb:15:7-15:12>
******************************************************


Resolving xrefs for node <EndName pkg.adb:16:8-16:9>
****************************************************

Expr: <EndName pkg.adb:16:8-16:9>
references: <DefiningName "P" pkg.adb:10:14-10:15>
type: None
expected type: None
Expr: <Id "P" pkg.adb:16:8-16:9>
references: <DefiningName "P" pkg.adb:10:14-10:15>
type: None
expected type: None


Analyzing ai12_0212.adb
#######################
Expand Down
17 changes: 17 additions & 0 deletions testsuite/tests/name_resolution/for_loop_6/test.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
with Ada.Containers.Hashed_Maps;

procedure Test is
function Hash (K : Integer) return Ada.Containers.Hash_Type is (0);

package My_Maps is new Ada.Containers.Hashed_Maps
(Integer, Integer, Hash, "=", "=");

use My_Maps;

V : Map;
begin
for It in V.Iterate when Key (It) > 2 loop
null;
end loop;
pragma Test_Block;
end Test;
52 changes: 52 additions & 0 deletions testsuite/tests/name_resolution/for_loop_6/test.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Analyzing test.adb
##################

Resolving xrefs for node <ForLoopSpec test.adb:13:8-13:41>
**********************************************************

Expr: <DottedName test.adb:13:14-13:23>
references: <| DefiningName "Iterate" a-cohama.ads:407:13-407:20 [test.adb:6:4] |>
type: <| ClasswideTypeDecl ["Forward_Iterator"] a-iteint.ads:24:4-24:66 [test.adb:6:4, a-cohama.ads:135:4] |>
expected type: None
Expr: <Id "V" test.adb:13:14-13:15>
references: <DefiningName "V" test.adb:11:4-11:5>
type: <| ConcreteTypeDecl ["Map"] a-cohama.ads:99:4-106:50 [test.adb:6:4] |>
expected type: <| ConcreteTypeDecl ["Map"] a-cohama.ads:99:4-106:50 [test.adb:6:4] |>
Expr: <Id "Iterate" test.adb:13:16-13:23>
references: <| DefiningName "Iterate" a-cohama.ads:407:13-407:20 [test.adb:6:4] |>
type: <| ClasswideTypeDecl ["Forward_Iterator"] a-iteint.ads:24:4-24:66 [test.adb:6:4, a-cohama.ads:135:4] |>
expected type: None

Resolving xrefs for node <ForLoopIterFilter test.adb:13:24-13:41>
*****************************************************************

Expr: <RelationOp test.adb:13:29-13:41>
type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
expected type: <ConcreteTypeDecl ["Boolean"] __standard:3:3-3:33>
Expr: <CallExpr test.adb:13:29-13:37>
references: <| DefiningName "Key" a-cohama.ads:177:13-177:16 [test.adb:6:4] |>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
Expr: <Id "Key" test.adb:13:29-13:32>
references: <| DefiningName "Key" a-cohama.ads:177:13-177:16 [test.adb:6:4] |>
type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>
expected type: None
Expr: <Id "It" test.adb:13:34-13:36>
references: <DefiningName "It" test.adb:13:8-13:10>
type: <| ConcreteTypeDecl ["Cursor"] a-cohama.ads:110:4-110:27 [test.adb:6:4] |>
expected type: <| ConcreteTypeDecl ["Cursor"] a-cohama.ads:110:4-110:27 [test.adb:6:4] |>
Expr: <OpGt ">" test.adb:13:38-13:39>
references: None
type: None
expected type: None
Expr: <Int test.adb:13:40-13:41>
references: None
type: <ConcreteTypeDecl ["Universal_Int_Type_"] __standard:116:3-116:45>
expected type: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Resolving xrefs for node <NullStmt test.adb:14:7-14:12>
*******************************************************



Done.
2 changes: 2 additions & 0 deletions testsuite/tests/name_resolution/for_loop_6/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
driver: name-resolution
input_sources: [test.adb]
Loading

0 comments on commit 4a1d2ff

Please sign in to comment.