typing: fix failed cast when iterate over a nullable collection
authorAlexandre Terrasa <alexandre@moz-code.org>
Tue, 25 Feb 2014 18:48:01 +0000 (13:48 -0500)
committerAlexandre Terrasa <alexandre@moz-code.org>
Tue, 25 Feb 2014 18:48:01 +0000 (13:48 -0500)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/typing.nit
tests/base_for_nullable.nit [new file with mode: 0644]
tests/sav/base_for_nullable.res [new file with mode: 0644]
tests/sav/base_for_nullable_alt1.res [new file with mode: 0644]
tests/sav/base_for_nullable_alt2.res [new file with mode: 0644]

index 92675fc..62e1bc0 100644 (file)
@@ -830,6 +830,11 @@ redef class AForExpr
 
        private fun do_type_iterator(v: TypeVisitor, mtype: MType)
        do
+               if mtype isa MNullType then
+                       v.error(self, "Type error: 'for' cannot iterate over 'null'")
+                       return
+               end
+
                # get obj class
                var objcla = v.get_mclass(self, "Object")
                if objcla == null then return
@@ -898,6 +903,7 @@ redef class AForExpr
                # anchor formal and virtual types
                if mtype.need_anchor then mtype = v.anchor_to(mtype)
 
+               if mtype isa MNullableType then mtype = mtype.mtype
                self.coltype = mtype.as(MClassType)
 
                # get methods is_ok, next, item
diff --git a/tests/base_for_nullable.nit b/tests/base_for_nullable.nit
new file mode 100644 (file)
index 0000000..4fd3253
--- /dev/null
@@ -0,0 +1,22 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import array
+
+var list: nullable Array[Int] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+#alt1# if true then list = null
+#alt2# list = null
+
+for i in list do i.output
+
diff --git a/tests/sav/base_for_nullable.res b/tests/sav/base_for_nullable.res
new file mode 100644 (file)
index 0000000..8b1acc1
--- /dev/null
@@ -0,0 +1,10 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
diff --git a/tests/sav/base_for_nullable_alt1.res b/tests/sav/base_for_nullable_alt1.res
new file mode 100644 (file)
index 0000000..c28bd5a
--- /dev/null
@@ -0,0 +1 @@
+Runtime error: Receiver is null (alt/base_for_nullable_alt1.nit:21)
diff --git a/tests/sav/base_for_nullable_alt2.res b/tests/sav/base_for_nullable_alt2.res
new file mode 100644 (file)
index 0000000..30e9b42
--- /dev/null
@@ -0,0 +1 @@
+alt/base_for_nullable_alt2.nit:21,1--25: Type error: 'for' cannot iterate over 'null'