--- /dev/null
+# 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.
+
+# A comprehensive test to check most cast of adaptive typing with merge, union and intersections.
+#
+# alt1 is for necessary static errors
+# alt2 is for errors due to the lack of union&intersection types
+
+import core::kernel
+
+# Base diamond hierarchy to have types
+
+class A
+end
+class B
+ super A
+end
+class C
+ super A
+end
+class D
+ super B
+ super C
+end
+
+class N
+end
+
+# Base methods to statically check the adapted types.
+
+fun test_a(x:A) do end
+fun test_b(x:B) do end
+fun test_nb(x:nullable B) do end
+fun test_c(x:C) do end
+fun test_nn(x:nullable N) do end
+fun test_o(x:Object) do end
+
+## Intersections and substractions
+
+# Intersection B and C (from B)
+fun inter1(x: B) do
+ if x isa C then
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+ else
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ end
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+end
+
+# Intersection B and C (from Object)
+fun inter2(x: nullable Object) do
+ if x isa B and x isa C then
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+ end
+end
+
+# Intersection B and then C (from Object)
+fun inter3(x: nullable Object) do
+ if x isa B then
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ if x isa C then
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+ else
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ end
+ #alt2#test_a(x)
+ # The previous one need an explanation: merge(inter(B,C),sub(B,C)) = merge(C,B) = null (because conflict).
+ # Unfortunately the fallback is on Object (instead of B) because the B information in the then branch
+ # is lost and for the typer, `x isa C` is indistinguishable with `x=new C`.
+ #alt2#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+ else
+ #alt1#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ if x isa C then
+ test_a(x)
+ #alt1#test_b(x)
+ test_c(x)
+ else
+ #alt1#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ end
+ #alt1#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ end
+ #alt1#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+end
+
+# Intersection nB and notnull (from nb)
+fun null_inter1n(x: nullable B) do
+ if x != null then
+ test_b(x)
+ else
+ test_nn(x)
+ end
+ test_nb(x)
+ #alt1#test_b(x)
+ #alt1#test_nn(x)
+end
+
+# Intersection nB and notnull (from nObject)
+fun null_inter2n(b: nullable B) do
+ var x
+ x = b
+ if x != null then
+ test_b(x)
+ else
+ test_nb(x)
+ test_nn(x)
+ end
+ test_nb(x)
+ #alt1#test_b(x)
+ #alt1#test_nn(x)
+end
+
+# Intersection nB and Object (from nb)
+fun null_inter1o(x: nullable B) do
+ if x isa A then
+ test_b(x)
+ else
+ test_nb(x)
+ test_nn(x)
+ end
+ test_nb(x)
+ #alt1#test_b(x)
+ #alt1#test_nn(x)
+end
+
+# Intersection nB and Object (from nObject)
+fun null_inter2o(b: nullable B) do
+ var x
+ x = b
+ if x isa A then
+ test_b(x)
+ else
+ test_nb(x)
+ test_nn(x)
+ end
+ test_nb(x)
+ #alt1#test_b(x)
+ #alt1#test_nn(x)
+end
+
+# Intersection Object and nB
+fun null_inter3(x: A) do
+ if x isa nullable B then
+ test_b(x)
+ else
+ test_a(x)
+ end
+ test_a(x)
+end
+
+## Unions
+
+# Union between B and C (with assigment)
+fun union1(b:B, c:C, m: Bool) do
+ var x
+ x = b
+ if m then x = c
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+end
+
+# Union between B and C (with isa or isa)
+fun union2(x: nullable Object) do
+ if x isa B or x isa C then
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+ end
+end
+
+# Union between B and null (from nullable Object)
+fun null_union(b: B) do
+ var x
+ x = b
+ test_nb(x)
+ test_b(x)
+ if true then x = null
+ test_nb(x)
+ #alt1#test_b(x)
+end
+
+## Loops
+
+# Type adaptation in a loop
+fun loop1(b:B, c:C, m: Bool) do
+ var x
+ x = b
+ while m do
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+ x = c
+ test_a(x)
+ #alt1#test_b(x)
+ test_c(x)
+ end
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+end
+
+# Union in a loop
+fun loop_union(b:B, c:C, m: Bool) do
+ var x
+ x = b
+ while m do
+ test_o(x)
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ if m then x = c
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+ end
+ #alt2#test_a(x)
+ #alt1#test_b(x)
+ #alt1#test_c(x)
+ test_o(x)
+end
+
+# Loop while not null
+fun null_loop_1(b: nullable B) do
+ var x
+ x = b
+ while x != null do
+ test_b(x)
+ test_nb(x)
+ if true then x = null
+ #alt1#test_b(x)
+ test_nb(x)
+ end
+ #alt1#test_b(x)
+ test_nb(x)
+end
+
+# Loop while null
+fun null_loop_2(b: nullable B) do
+ var x
+ x = b
+ while x == null do
+ #alt1#test_b(x)
+ test_nb(x)
+ if true then x = b
+ #alt1#test_b(x)
+ test_nb(x)
+ end
+ test_b(x)
+ test_nb(x)
+end
+
+# Loop while isa (from B)
+fun loop_inter1a(b: B) do
+ var x = b
+ while x isa C do
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+ x = b
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ end
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+end
+
+# Loop while not isa (from B)
+fun loop_inter2a(b: B) do
+ var x = b
+ while not x isa C do
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ x = b
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ end
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+end
+
+# loop while isa (from Object)
+fun loop_inter1b(b: B) do
+ var x
+ x = b
+ while x isa C do
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+ x = b
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ end
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+end
+
+# loop while not isa (from Object)
+fun loop_inter2b(b: B) do
+ var x
+ x = b
+ while not x isa C do
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ x = b
+ test_a(x)
+ test_b(x)
+ #alt1#test_c(x)
+ end
+ test_a(x)
+ #alt2#test_b(x)
+ test_c(x)
+end
--- /dev/null
+alt/base_adaptive_full_alt1.nit:60,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:64,9: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:81,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:89,11: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:96,10: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:99,10: Type Error: expected `A`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:100,10: Type Error: expected `B`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:101,10: Type Error: expected `C`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:104,11: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt1.nit:107,11: Type Error: expected `A`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:108,11: Type Error: expected `B`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:109,11: Type Error: expected `C`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:111,10: Type Error: expected `A`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:112,10: Type Error: expected `B`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:113,10: Type Error: expected `C`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:115,9: Type Error: expected `A`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:116,9: Type Error: expected `B`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:117,9: Type Error: expected `C`, got `nullable Object`.
+alt/base_adaptive_full_alt1.nit:128,9: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:129,10: Type Error: expected `nullable N`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:143,9: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:144,10: Type Error: expected `nullable N`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:156,9: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:157,10: Type Error: expected `nullable N`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:171,9: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:172,10: Type Error: expected `nullable N`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:193,9: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:194,9: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:202,10: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:203,10: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:216,9: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:227,10: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:228,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:228,10: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:232,10: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt1.nit:236,9: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:237,9: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:248,10: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:249,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:249,10: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:252,10: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:253,10: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:257,9: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt1.nit:258,9: Type Error: expected `C`, got `Object`.
+alt/base_adaptive_full_alt1.nit:270,10: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:273,9: Type Error: expected `B`, got `null`.
+alt/base_adaptive_full_alt1.nit:282,10: Type Error: expected `B`, got `null`.
+alt/base_adaptive_full_alt1.nit:285,10: Type Error: expected `B`, got `nullable B`.
+alt/base_adaptive_full_alt1.nit:302,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:306,9: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:315,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:319,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:337,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:341,9: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:351,10: Type Error: expected `C`, got `B`.
+alt/base_adaptive_full_alt1.nit:355,10: Type Error: expected `C`, got `B`.
--- /dev/null
+alt/base_adaptive_full_alt2.nit:55,10: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt2.nit:71,10: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt2.nit:84,11: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt2.nit:91,10: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:95,10: Type Error: expected `B`, got `Object`.
+alt/base_adaptive_full_alt2.nit:192,9: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:201,10: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:226,10: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:235,9: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:247,10: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:251,10: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:256,9: Type Error: expected `A`, got `Object`.
+alt/base_adaptive_full_alt2.nit:297,10: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt2.nit:322,9: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt2.nit:332,10: Type Error: expected `B`, got `C`.
+alt/base_adaptive_full_alt2.nit:358,9: Type Error: expected `B`, got `C`.