Fix range variable name collision check for nested linq queries
authorMarek Safar <marek.safar@gmail.com>
Thu, 19 Jan 2012 11:59:11 +0000 (11:59 +0000)
committerMarek Safar <marek.safar@gmail.com>
Thu, 19 Jan 2012 12:00:05 +0000 (12:00 +0000)
mcs/mcs/linq.cs
mcs/mcs/statement.cs
mcs/tests/gtest-linq-28.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index 3616d11ab6ad4122894e6401164f21661d8efc12..37bf43622ac38702f5ab7b016f15d0893d11cd66 100644 (file)
@@ -825,7 +825,7 @@ namespace Mono.CSharp.Linq
                public void AddRangeVariable (RangeVariable variable)
                {
                        variable.Block = this;
-                       AddLocalName (variable.Name, variable);
+                       TopBlock.AddLocalName (variable.Name, variable, true);
                }
 
                public override void Error_AlreadyDeclared (string name, INamedBlockVariable variable, string reason)
index 199591b89b6b67de6b98e35d313b44e8dd3f5e73..32b7b00168aa44551ce35d8f48a97ff702c8674d 100644 (file)
@@ -2099,9 +2099,9 @@ namespace Mono.CSharp {
                        AddLocalName (li.Name, li);
                }
 
-               public virtual void AddLocalName (string name, INamedBlockVariable li)
+               public void AddLocalName (string name, INamedBlockVariable li)
                {
-                       ParametersBlock.TopBlock.AddLocalName (name, li);
+                       ParametersBlock.TopBlock.AddLocalName (name, li, false);
                }
 
                public virtual void Error_AlreadyDeclared (string name, INamedBlockVariable variable, string reason)
@@ -3003,7 +3003,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void AddLocalName (string name, INamedBlockVariable li)
+               public void AddLocalName (string name, INamedBlockVariable li, bool ignoreChildrenBlocks)
                {
                        if (names == null)
                                names = new Dictionary<string, object> ();
@@ -3047,13 +3047,15 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               // Collision with with children
-                               b = existing.Block;
-                               while ((b = b.Parent) != null) {
-                                       if (li.Block == b) {
-                                               li.Block.Error_AlreadyDeclared (name, li, "child");
-                                               i = existing_list.Count;
-                                               break;
+                               if (!ignoreChildrenBlocks) {
+                                       // Collision with children
+                                       b = existing.Block;
+                                       while ((b = b.Parent) != null) {
+                                               if (li.Block == b) {
+                                                       li.Block.Error_AlreadyDeclared (name, li, "child");
+                                                       i = existing_list.Count;
+                                                       break;
+                                               }
                                        }
                                }
                        }
diff --git a/mcs/tests/gtest-linq-28.cs b/mcs/tests/gtest-linq-28.cs
new file mode 100644 (file)
index 0000000..edcc93f
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using System.Linq;
+
+class C
+{
+       public static int Main ()
+       {
+               var r = from m in "ab"
+                               let n = from n in "xyz" select n
+                               select n;
+               
+               int counter = 0;
+               foreach (var a in r) {
+                       foreach (var b in a) {
+                               Console.WriteLine (b);
+                               counter++;
+                       }
+               }
+               
+               if (counter != 6)
+                       return 1;
+               
+               return 0;
+       }
+}
\ No newline at end of file
index 42db079850a2657a6ac0fa77c14877a20ede16bd..1446e04a9e58fbab253da4e8ce648439f9221139 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-linq-28.cs">
+    <type name="C">
+      <method name="Int32 Main()">
+        <size>200</size>
+      </method>
+      <method name="&lt;&gt;__AnonType0`2[System.Char,System.Collections.Generic.IEnumerable`1[System.Char]] &lt;Main&gt;m__0(Char)">
+        <size>46</size>
+      </method>
+      <method name="IEnumerable`1 &lt;Main&gt;m__1(&lt;&gt;__AnonType0`2[System.Char,System.Collections.Generic.IEnumerable`1[System.Char]])">
+        <size>7</size>
+      </method>
+      <method name="Char &lt;Main&gt;m__2(Char)">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="&lt;&gt;__AnonType0`2[&lt;m&gt;__T,&lt;n&gt;__T]">
+      <method name="&lt;m&gt;__T get_m()">
+        <size>7</size>
+      </method>
+      <method name="&lt;n&gt;__T get_n()">
+        <size>7</size>
+      </method>
+      <method name="Boolean Equals(System.Object)">
+        <size>69</size>
+      </method>
+      <method name="Int32 GetHashCode()">
+        <size>86</size>
+      </method>
+      <method name="System.String ToString()">
+        <size>142</size>
+      </method>
+      <method name="Void .ctor(&lt;m&gt;__T, &lt;n&gt;__T)">
+        <size>21</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-named-01.cs">
     <type name="C">
       <method name="Int32 Test(Int32, Int32, System.String)">