diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index f1cd9db376a3..25c75dbc7e72 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -574,8 +574,11 @@ object Flags { /** A synthetic or private definition */ final val SyntheticOrPrivate = Synthetic | Private - /** A deferred member or a parameter accessor (these don't have right hand sides) */ - final val DeferredOrParamOrAccessor = Deferred | Param | ParamAccessor + /** A deferred term member or a parameter accessor (these don't have right hand sides) */ + final val DeferredOrTermParamOrAccessor = Deferred | TermParam | ParamAccessor + + /** A deferred term member or a parameter accessor (these don't have right hand sides) */ + final val DeferredOrTypeParam = Deferred | TypeParam /** value that's final or inline */ final val FinalOrInline = Final | Inline diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 5ee57d02a107..d2c1678cf967 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -529,7 +529,7 @@ object SymDenotations { } /** Is this symbol an abstract type? */ - final def isAbstractType(implicit ctx: Context) = isType && (this is Deferred) + final def isAbstractType(implicit ctx: Context) = this is DeferredType /** Is this symbol an alias type? */ final def isAliasType(implicit ctx: Context) = isAbstractOrAliasType && !(this is Deferred) @@ -537,6 +537,9 @@ object SymDenotations { /** Is this symbol an abstract or alias type? */ final def isAbstractOrAliasType = isType & !isClass + /** Is this symbol an abstract type or type parameter? */ + final def isAbstractOrParamType(implicit ctx: Context) = this is DeferredOrTypeParam + /** Is this the denotation of a self symbol of some class? * This is the case if one of two conditions holds: * 1. It is the symbol referred to in the selfInfo part of the ClassInfo diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 321ef835ae78..05dc572dc51e 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -211,8 +211,8 @@ object TypeErasure { case tp: TypeAlias => isUnboundedGeneric(tp.alias) case tp: TypeBounds => !tp.hi.derivesFrom(defn.ObjectClass) case tp: TypeProxy => isUnboundedGeneric(tp.underlying) - case tp: AndType => isUnboundedGeneric(tp.tp1) || isUnboundedGeneric(tp.tp2) - case tp: OrType => isUnboundedGeneric(tp.tp1) && isUnboundedGeneric(tp.tp2) + case tp: AndType => isUnboundedGeneric(tp.tp1) && isUnboundedGeneric(tp.tp2) + case tp: OrType => isUnboundedGeneric(tp.tp1) || isUnboundedGeneric(tp.tp2) case _ => false } diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 55b2f2ae4c8f..5f4dd0153040 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -368,13 +368,13 @@ class ClassfileParser( case ARRAY_TAG => while ('0' <= sig(index) && sig(index) <= '9') index += 1 var elemtp = sig2type(tparams, skiptvs) - // make unbounded Array[T] where T is a type variable into Ar ray[T with Object] + // make unbounded Array[T] where T is a type variable into Array[T with Object] // (this is necessary because such arrays have a representation which is incompatible // with arrays of primitive types. // NOTE that the comparison to Object only works for abstract types bounded by classes that are strict subclasses of Object // if the bound is exactly Object, it will have been converted to Any, and the comparison will fail // see also RestrictJavaArraysMap (when compiling java sources directly) - if (elemtp.typeSymbol.isAbstractType && !(elemtp.derivesFrom(defn.ObjectClass))) { + if (elemtp.typeSymbol.isAbstractOrParamType && !(elemtp.derivesFrom(defn.ObjectClass))) { elemtp = AndType(elemtp, defn.ObjectType) } defn.ArrayOf(elemtp) diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index a2542cbaefee..4247cb4fdfb9 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -66,8 +66,14 @@ object Scala2Unpickler { assert(lastArg isRef defn.ArrayClass) val elemtp0 :: Nil = lastArg.baseType(defn.ArrayClass).argInfos val elemtp = elemtp0 match { - case AndType(t1, t2) if t1.typeSymbol.isAbstractType && (t2 isRef defn.ObjectClass) => - t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them. + case AndType(t1, t2) => // drop intersection with Object for abstract types an parameters in varargs. Erasure can handle them. + if (t2.isRef(defn.ObjectClass)) + t1 match { + case t1: TypeParamRef => t1 + case t1: TypeRef if t1.symbol.isAbstractOrParamType => t1 + case _ => elemtp0 + } + else elemtp0 case _ => elemtp0 } diff --git a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala index fcbfc6387a6a..0086680d69e2 100644 --- a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala +++ b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala @@ -427,7 +427,7 @@ object GenericSignatures { * owners (e.g. when computing lubs, is used). All packageClass symbols have `isJavaDefined == true`. */ case RefOrAppliedType(sym, tp, _) => - if (sym.isAbstractType && (!sym.owner.is(JavaDefined) || sym.is(Scala2Existential))) + if (sym.isAbstractOrParamType && (!sym.owner.is(JavaDefined) || sym.is(Scala2Existential))) tp else NoType diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 09a06820d0a8..f88e658c05cc 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -191,7 +191,7 @@ object RefChecks { def info = self.memberInfo(sym1) val infoStr = if (sym1.isAliasType) i", which equals ${info.bounds.hi}" - else if (sym1.isAbstractType) i" with bounds$info" + else if (sym1.isAbstractOrParamType) i" with bounds$info" else if (sym1.is(Module)) "" else if (sym1.isTerm) i" of type $info" else "" @@ -913,7 +913,7 @@ class RefChecks extends MiniPhase { thisPhase => } def underlyingClass(tp: Type): Symbol = { val sym = tp.widen.typeSymbol - if (sym.isAbstractType) underlyingClass(sym.info.bounds.hi) + if (sym.isAbstractOrParamType) underlyingClass(sym.info.bounds.hi) else sym } val actual = underlyingClass(other.tpe) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 5f023820bc07..3aeb49bbe6b8 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1345,7 +1345,7 @@ class Typer extends Namer case rhs => typedExpr(rhs, tpt1.tpe) } val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) - if (sym.is(Inline, butNot = DeferredOrParamOrAccessor)) + if (sym.is(Inline, butNot = DeferredOrTermParamOrAccessor)) checkInlineConformant(rhs1, em"right-hand side of inline $sym") patchIfLazy(vdef1) patchFinalVals(vdef1) diff --git a/tests/neg/i1747.scala b/tests/neg/i1747.scala index 54492aaed393..c34fe4f95b4b 100644 --- a/tests/neg/i1747.scala +++ b/tests/neg/i1747.scala @@ -1,3 +1,3 @@ -class Coll[E] extends java.util.Collection[E] { // error: needs to be abstract - def toArray[T](a: Array[T]): Array[T] = ??? // error: cannot override +abstract class Coll[E] extends java.util.Collection[E] { + override def toArray[T](a: Array[T]): Array[T] = ??? // error: has different signature } diff --git a/tests/pos/i1747.scala b/tests/pos/i1747.scala new file mode 100644 index 000000000000..b8be2433abc6 --- /dev/null +++ b/tests/pos/i1747.scala @@ -0,0 +1,3 @@ +abstract class Coll[E] extends java.util.Collection[E] { + override def toArray[T](a: Array[T with Object]): Array[T with Object] = ??? // error: cannot override +} diff --git a/tests/run/i533/JA.java b/tests/run/i533/JA.java new file mode 100644 index 000000000000..92421e5b1fee --- /dev/null +++ b/tests/run/i533/JA.java @@ -0,0 +1,5 @@ +class JA { + public static T get(T[] arr) { + return arr[0]; + } +} \ No newline at end of file diff --git a/tests/run/i533/Test.scala b/tests/run/i533/Test.scala new file mode 100644 index 000000000000..3f1091bf8e02 --- /dev/null +++ b/tests/run/i533/Test.scala @@ -0,0 +1,7 @@ +object Test { + def main(args: Array[String]): Unit = { + val x = new Array[Int](1) + x(0) = 10 + println(JA.get(x)) + } +}