diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 61502cddf482..62e8c14a01d8 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -271,14 +271,18 @@ trait TypeAssigner { def assignType(tree: untpd.Select, qual: Tree)(implicit ctx: Context): Select = { def qualType = qual.tpe.widen def arrayElemType = { - val JavaArrayType(elemtp) = qualType - elemtp + qualType match { + case JavaArrayType(elemtp) => elemtp + case _ => + ctx.error("Array type conflict with " + qual.symbol.name, tree.pos) + defn.NothingType + } } val p = nme.primitive val tp = tree.name match { case p.arrayApply => MethodType(defn.IntType :: Nil, arrayElemType) case p.arrayUpdate => MethodType(defn.IntType :: arrayElemType :: Nil, defn.UnitType) - case p.arrayLength => MethodType(Nil, defn.IntType) + case p.arrayLength => arrayElemType; MethodType(Nil, defn.IntType) // Note that we do not need to handle calls to Array[T]#clone() specially: // The JLS section 10.7 says "The return type of the clone method of an array type diff --git a/tests/neg/i4247.scala b/tests/neg/i4247.scala new file mode 100644 index 000000000000..12e6786ea0a5 --- /dev/null +++ b/tests/neg/i4247.scala @@ -0,0 +1,3 @@ +class Foo[U] { self : Array[U] & Nothing => + val s = self(0) // error: Array type conflict with Foo +} diff --git a/tests/neg/i4247b.scala b/tests/neg/i4247b.scala new file mode 100644 index 000000000000..e23a5ee410e7 --- /dev/null +++ b/tests/neg/i4247b.scala @@ -0,0 +1,3 @@ +class Foo[U] { self : Array[U] & Nothing => + self(0) = ??? // error: Array type conflict with Foo +} diff --git a/tests/neg/i4247c.scala b/tests/neg/i4247c.scala new file mode 100644 index 000000000000..4fe28f7d381c --- /dev/null +++ b/tests/neg/i4247c.scala @@ -0,0 +1,3 @@ +class Foo[U] { self : Array[U] & Nothing => + self.length // error: Array type conflict with Foo +}