From 4a1d2ff3e324cc0b48c12d2923c3469e216ecbe1 Mon Sep 17 00:00:00 2001 From: Romain Beguet Date: Fri, 17 Nov 2023 09:35:11 +0100 Subject: [PATCH] Introduce dedicated ForLoopIterFilter node to fix their name resolution. --- ada/ast.py | 47 +- ada/grammar.py | 2 +- .../container_aggregate/pkg.adb | 4 +- .../container_aggregate/test.out | 108 +++-- .../tests/name_resolution/for_loop_6/test.adb | 17 + .../tests/name_resolution/for_loop_6/test.out | 52 +++ .../name_resolution/for_loop_6/test.yaml | 2 + .../iterassoc_filter.adb | 20 +- .../iterated_component_association/test.out | 440 ++++++++++++------ .../tests/name_resolution/reduce_attr/acc.adb | 2 +- .../name_resolution/reduce_attr/test.out | 105 ++++- 11 files changed, 558 insertions(+), 241 deletions(-) create mode 100644 testsuite/tests/name_resolution/for_loop_6/test.adb create mode 100644 testsuite/tests/name_resolution/for_loop_6/test.out create mode 100644 testsuite/tests/name_resolution/for_loop_6/test.yaml diff --git a/ada/ast.py b/ada/ast.py index 09ca316a8..7a637d562 100644 --- a/ada/ast.py +++ b/ada/ast.py @@ -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(): """ @@ -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(): @@ -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 @@ -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`). diff --git a/ada/grammar.py b/ada/grammar.py index 33f443a97..c84871835 100644 --- a/ada/grammar.py +++ b/ada/grammar.py @@ -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( diff --git a/testsuite/tests/name_resolution/container_aggregate/pkg.adb b/testsuite/tests/name_resolution/container_aggregate/pkg.adb index 21e1d3688..aae3128c5 100644 --- a/testsuite/tests/name_resolution/container_aggregate/pkg.adb +++ b/testsuite/tests/name_resolution/container_aggregate/pkg.adb @@ -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; diff --git a/testsuite/tests/name_resolution/container_aggregate/test.out b/testsuite/tests/name_resolution/container_aggregate/test.out index 6017dd905..bad179621 100644 --- a/testsuite/tests/name_resolution/container_aggregate/test.out +++ b/testsuite/tests/name_resolution/container_aggregate/test.out @@ -233,6 +233,18 @@ Expr: Analyzing pkg.adb ################# +Resolving xrefs for node +****************************************************** + + +Resolving xrefs for node +**************************************************************** + +Expr: + references: + type: None + expected type: None + Resolving xrefs for node ***************************************************************** @@ -247,6 +259,14 @@ Expr: references: type: expected type: None +Expr: + references: + type: + expected type: + +Resolving xrefs for node +**************************************************************** + Expr: type: expected type: @@ -262,108 +282,124 @@ Expr: references: None type: expected type: -Expr: - references: - type: - expected type: -Resolving xrefs for node +Resolving xrefs for node ***************************************************************** -Expr: +Expr: references: type: None expected type: None -Expr: +Expr: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: +Expr: + references: + type: + expected type: + +Resolving xrefs for node +**************************************************************** + +Expr: type: expected type: -Expr: +Expr: type: expected type: -Expr: - references: +Expr: + references: type: expected type: -Expr: +Expr: references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Expr: +Expr: references: None type: None expected type: None -Expr: +Expr: type: expected type: -Expr: - references: +Expr: + references: type: expected type: -Expr: " pkg.adb:13:56-13:57> +Expr: " pkg.adb:12:56-12:57> references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Expr: - references: - type: - expected type: -Resolving xrefs for node +Resolving xrefs for node ***************************************************************** -Expr: +Expr: references: type: None expected type: None -Expr: +Expr: type: expected type: -Expr: +Expr: type: expected type: -Expr: +Expr: references: None type: expected type: -Expr: +Expr: references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Expr: +Expr: type: expected type: -Expr: - references: +Expr: + references: type: expected type: -Expr: +Expr: references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: +Resolving xrefs for node +****************************************************** + + +Resolving xrefs for node +**************************************************** + +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None + Analyzing ai12_0212.adb ####################### diff --git a/testsuite/tests/name_resolution/for_loop_6/test.adb b/testsuite/tests/name_resolution/for_loop_6/test.adb new file mode 100644 index 000000000..f13a94649 --- /dev/null +++ b/testsuite/tests/name_resolution/for_loop_6/test.adb @@ -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; diff --git a/testsuite/tests/name_resolution/for_loop_6/test.out b/testsuite/tests/name_resolution/for_loop_6/test.out new file mode 100644 index 000000000..8250b683a --- /dev/null +++ b/testsuite/tests/name_resolution/for_loop_6/test.out @@ -0,0 +1,52 @@ +Analyzing test.adb +################## + +Resolving xrefs for node +********************************************************** + +Expr: + 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: + references: + 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: + 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 +***************************************************************** + +Expr: + type: + expected type: +Expr: + references: <| DefiningName "Key" a-cohama.ads:177:13-177:16 [test.adb:6:4] |> + type: + expected type: +Expr: + references: <| DefiningName "Key" a-cohama.ads:177:13-177:16 [test.adb:6:4] |> + type: + expected type: None +Expr: + references: + 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: " test.adb:13:38-13:39> + references: None + type: None + expected type: None +Expr: + references: None + type: + expected type: + +Resolving xrefs for node +******************************************************* + + + +Done. diff --git a/testsuite/tests/name_resolution/for_loop_6/test.yaml b/testsuite/tests/name_resolution/for_loop_6/test.yaml new file mode 100644 index 000000000..173e325ff --- /dev/null +++ b/testsuite/tests/name_resolution/for_loop_6/test.yaml @@ -0,0 +1,2 @@ +driver: name-resolution +input_sources: [test.adb] diff --git a/testsuite/tests/name_resolution/iterated_component_association/iterassoc_filter.adb b/testsuite/tests/name_resolution/iterated_component_association/iterassoc_filter.adb index 13370be15..51f847a5e 100644 --- a/testsuite/tests/name_resolution/iterated_component_association/iterassoc_filter.adb +++ b/testsuite/tests/name_resolution/iterated_component_association/iterassoc_filter.adb @@ -5,13 +5,10 @@ procedure Iterassoc_Filter is X : A := (1.0, 2.0, 3.0, 4.0, 5.0); M : A := (for I in R when X (I) >= 3.0 => X (I) * X (I)); - pragma Test_Statement; O : A := (for F : Float of X when F >= 3.0 => F * F); - pragma Test_Statement; P : A := (for F of X when F >= 3.0 => F * F); - pragma Test_Statement; type AA is array (R, R) of Float; @@ -19,14 +16,13 @@ procedure Iterassoc_Filter is Q : AA := (for I in R when X (I) >= 3.0 => (for J in R when X (J) >= 3.0 => X (I) * X (J))); - pragma Test_Statement; + + R : Boolean := (for all F of X when F >= 3.0 => F > 4.0); + + S : Boolean := (for some I in 1 .. 5 when X (I) >= 3.0 => X (I) > 4.0); begin - declare - B : Boolean := (for all F of X when F >= 3.0 => F > 4.0); - C : Boolean := (for some I in 1 .. 5 when X (I) >= 3.0 => X (I) > 4.0); - begin - null; - end; - pragma Test_Block; - -- We use Test_Block so that inner ForLoopSpec nodes are also resolved + null; end Iterassoc_Filter; +pragma Test_Block; +-- We use Test_Block so that inner ForLoopSpec and ForLoopIterFilter nodes +-- are also resolved. diff --git a/testsuite/tests/name_resolution/iterated_component_association/test.out b/testsuite/tests/name_resolution/iterated_component_association/test.out index fdb449749..a17bd3d99 100644 --- a/testsuite/tests/name_resolution/iterated_component_association/test.out +++ b/testsuite/tests/name_resolution/iterated_component_association/test.out @@ -308,6 +308,76 @@ Expr: Analyzing iterassoc_filter.adb ############################## +Resolving xrefs for node +***************************************************************** + + +Resolving xrefs for node +******************************************************************************* + +Expr: + type: + expected type: +Expr: + references: None + type: + expected type: +Expr: + references: None + type: None + expected type: None +Expr: + references: None + type: + expected type: + +Resolving xrefs for node +******************************************************************************* + + +Resolving xrefs for node +********************************************************************** + +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None + +Resolving xrefs for node +************************************************************************* + +Expr: + references: + type: None + expected type: None +Expr: + type: + expected type: +Expr: + references: None + type: + expected type: +Expr: + references: None + type: + expected type: +Expr: + references: None + type: + expected type: +Expr: + references: None + type: + expected type: +Expr: + references: None + type: + expected type: + Resolving xrefs for node ************************************************************************* @@ -322,29 +392,6 @@ Expr: references: type: expected type: -Expr: - type: - expected type: -Expr: - references: - type: - expected type: -Expr: - references: - type: - expected type: None -Expr: - references: - type: - expected type: -Expr: =" iterassoc_filter.adb:7:36-7:38> - references: None - type: None - expected type: None -Expr: - references: None - type: - expected type: Expr: type: expected type: @@ -377,333 +424,416 @@ Expr: type: expected type: -Resolving xrefs for node +Resolving xrefs for node *************************************************************************** -Expr: +Expr: + type: + expected type: +Expr: + references: + type: + expected type: +Expr: + references: + type: + expected type: None +Expr: + references: + type: + expected type: +Expr: =" iterassoc_filter.adb:7:36-7:38> + references: None + type: None + expected type: None +Expr: + references: None + type: + expected type: + +Resolving xrefs for node +************************************************************************* + +Expr: references: type: None expected type: None -Expr: +Expr: type: expected type: -Expr: +Expr: references: type: None expected type: None -Expr: +Expr: references: type: expected type: -Expr: - type: - expected type: -Expr: - references: +Expr: + type: + expected type: +Expr: + references: type: expected type: -Expr: =" iterassoc_filter.adb:10:40-10:42> +Expr: references: None type: None expected type: None -Expr: - references: None - type: - expected type: -Expr: +Expr: + references: type: expected type: -Expr: - references: + +Resolving xrefs for node +*************************************************************************** + +Expr: + type: + expected type: +Expr: + references: type: expected type: -Expr: +Expr: =" iterassoc_filter.adb:9:40-9:42> references: None type: None expected type: None -Expr: - references: - type: +Expr: + references: None + type: expected type: -Resolving xrefs for node +Resolving xrefs for node *************************************************************************** -Expr: +Expr: references: type: None expected type: None -Expr: +Expr: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: - type: - expected type: -Expr: - references: +Expr: type: expected type: -Expr: =" iterassoc_filter.adb:13:32-13:34> +Expr: + references: + type: + expected type: +Expr: references: None type: None expected type: None -Expr: - references: None - type: - expected type: -Expr: +Expr: + references: type: expected type: -Expr: - references: + +Resolving xrefs for node +***************************************************************************** + +Expr: + type: + expected type: +Expr: + references: type: expected type: -Expr: +Expr: =" iterassoc_filter.adb:11:32-11:34> references: None type: None expected type: None -Expr: - references: - type: +Expr: + references: None + type: expected type: -Resolving xrefs for node +Resolving xrefs for node +********************************************************************************** + + +Resolving xrefs for node +************************************************************************ + +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None + +Resolving xrefs for node *************************************************************************** -Expr: - references: +Expr: + references: type: None expected type: None -Expr: - type: - expected type: -Expr: +Expr: + type: + expected type: +Expr: references: type: expected type: -Expr: - type: - expected type: -Expr: +Expr: + type: None + expected type: None +Expr: + references: + type: + expected type: +Expr: + type: + expected type: +Expr: references: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: - references: +Expr: + references: type: expected type: -Expr: =" iterassoc_filter.adb:20:29-20:31> +Expr: references: None type: None expected type: None -Expr: - references: None - type: +Expr: + references: + type: expected type: -Expr: - type: None +Expr: + references: + type: expected type: None -Expr: - references: +Expr: + references: type: expected type: -Expr: + +Resolving xrefs for node +***************************************************************************** + +Expr: type: expected type: -Expr: +Expr: references: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: - references: +Expr: + references: type: expected type: -Expr: =" iterassoc_filter.adb:21:31-21:33> +Expr: =" iterassoc_filter.adb:17:29-17:31> references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Expr: - type: - expected type: -Expr: + +Resolving xrefs for node +***************************************************************************** + +Expr: + type: + expected type: +Expr: references: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: - references: +Expr: + references: type: expected type: -Expr: +Expr: =" iterassoc_filter.adb:18:31-18:33> references: None type: None expected type: None -Expr: - references: - type: +Expr: + references: None + type: expected type: -Expr: - references: - type: - expected type: None -Expr: - references: - type: - expected type: -Resolving xrefs for node +Resolving xrefs for node *************************************************************************** -Expr: +Expr: references: type: None expected type: None -Expr: +Expr: type: expected type: -Expr: +Expr: type: expected type: -Expr: +Expr: type: expected type: -Expr: - references: +Expr: + references: type: expected type: -Expr: " iterassoc_filter.adb:25:57-25:58> +Expr: " iterassoc_filter.adb:20:54-20:55> references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Resolving xrefs for node +Resolving xrefs for node *********************************************************************** -Expr: +Expr: references: type: expected type: None -Expr: + +Resolving xrefs for node +***************************************************************************** + +Expr: type: expected type: -Expr: - references: +Expr: + references: type: expected type: -Expr: =" iterassoc_filter.adb:25:45-25:47> +Expr: =" iterassoc_filter.adb:20:42-20:44> references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Resolving xrefs for node +Resolving xrefs for node *************************************************************************** -Expr: +Expr: references: type: None expected type: None -Expr: +Expr: type: expected type: -Expr: +Expr: type: expected type: -Expr: +Expr: type: expected type: -Expr: +Expr: references: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: - references: +Expr: + references: type: expected type: -Expr: " iterassoc_filter.adb:26:71-26:72> +Expr: " iterassoc_filter.adb:22:68-22:69> references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Resolving xrefs for node +Resolving xrefs for node *********************************************************************** -Expr: +Expr: type: expected type: -Expr: +Expr: references: None type: expected type: -Expr: +Expr: references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Expr: + +Resolving xrefs for node +***************************************************************************** + +Expr: type: expected type: -Expr: +Expr: references: type: expected type: -Expr: +Expr: references: type: expected type: None -Expr: - references: +Expr: + references: type: expected type: -Expr: =" iterassoc_filter.adb:26:55-26:57> +Expr: =" iterassoc_filter.adb:22:52-22:54> references: None type: None expected type: None -Expr: +Expr: references: None type: expected type: -Resolving xrefs for node -******************************************************************* +Resolving xrefs for node +****************************************************************** + +Resolving xrefs for node +****************************************************************** + +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None Done. diff --git a/testsuite/tests/name_resolution/reduce_attr/acc.adb b/testsuite/tests/name_resolution/reduce_attr/acc.adb index 741e205db..b507fab19 100644 --- a/testsuite/tests/name_resolution/reduce_attr/acc.adb +++ b/testsuite/tests/name_resolution/reduce_attr/acc.adb @@ -16,10 +16,10 @@ procedure Acc is Acc : constant Accumulator := [for Val of M when Val > 100.0 => (Val, 1)] 'Reduce(Accumulate, (Sum => 0.0, Count => 0)); - pragma Test_Statement; begin return Acc.Sum / Real(Acc.Count); end Average_of_Values_Greater_Than_100; + pragma Test_Block; begin null; end Acc; diff --git a/testsuite/tests/name_resolution/reduce_attr/test.out b/testsuite/tests/name_resolution/reduce_attr/test.out index c08a4bdab..fdb7c1360 100644 --- a/testsuite/tests/name_resolution/reduce_attr/test.out +++ b/testsuite/tests/name_resolution/reduce_attr/test.out @@ -260,6 +260,22 @@ Expr: Analyzing acc.adb ################# +Resolving xrefs for node +****************************************************** + +Expr: + references: + type: None + expected type: None + +Resolving xrefs for node +************************************************************** + +Expr: + references: + type: None + expected type: None + Resolving xrefs for node **************************************************************** @@ -275,21 +291,6 @@ Expr: references: type: expected type: None -Expr: - type: - expected type: -Expr: - references: - type: - expected type: -Expr: " acc.adb:17:32-17:33> - references: None - type: None - expected type: None -Expr: - references: None - type: - expected type: Expr: type: expected type: @@ -329,6 +330,80 @@ Expr: type: expected type: +Resolving xrefs for node +**************************************************************** + +Expr: + type: + expected type: +Expr: + references: + type: + expected type: +Expr: " acc.adb:17:32-17:33> + references: None + type: None + expected type: None +Expr: + references: None + type: + expected type: + +Resolving xrefs for node +******************************************************** + +Expr: + type: + expected type: +Expr: + references: + type: + expected type: +Expr: + references: + type: + expected type: +Expr: + references: + type: + expected type: +Expr: + references: None + type: None + expected type: None +Expr: + references: + type: + expected type: +Expr: + references: + type: + expected type: None +Expr: + references: + type: + expected type: None +Expr: + references: + type: + expected type: +Expr: + references: + type: + expected type: None + +Resolving xrefs for node +***************************************************** + +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None + Analyzing countc.adb ####################