Skip to content

Commit b3f49a9

Browse files
authored
Merge pull request #3931 from dotty-staging/fix-#533
Fix #533: Some isAbstractType tests should succeed for parameters
2 parents 6d06cce + 1f2d234 commit b3f49a9

File tree

12 files changed

+42
-15
lines changed

12 files changed

+42
-15
lines changed

compiler/src/dotty/tools/dotc/core/Flags.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,11 @@ object Flags {
574574
/** A synthetic or private definition */
575575
final val SyntheticOrPrivate = Synthetic | Private
576576

577-
/** A deferred member or a parameter accessor (these don't have right hand sides) */
578-
final val DeferredOrParamOrAccessor = Deferred | Param | ParamAccessor
577+
/** A deferred term member or a parameter accessor (these don't have right hand sides) */
578+
final val DeferredOrTermParamOrAccessor = Deferred | TermParam | ParamAccessor
579+
580+
/** A deferred term member or a parameter accessor (these don't have right hand sides) */
581+
final val DeferredOrTypeParam = Deferred | TypeParam
579582

580583
/** value that's final or inline */
581584
final val FinalOrInline = Final | Inline

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,14 +529,17 @@ object SymDenotations {
529529
}
530530

531531
/** Is this symbol an abstract type? */
532-
final def isAbstractType(implicit ctx: Context) = isType && (this is Deferred)
532+
final def isAbstractType(implicit ctx: Context) = this is DeferredType
533533

534534
/** Is this symbol an alias type? */
535535
final def isAliasType(implicit ctx: Context) = isAbstractOrAliasType && !(this is Deferred)
536536

537537
/** Is this symbol an abstract or alias type? */
538538
final def isAbstractOrAliasType = isType & !isClass
539539

540+
/** Is this symbol an abstract type or type parameter? */
541+
final def isAbstractOrParamType(implicit ctx: Context) = this is DeferredOrTypeParam
542+
540543
/** Is this the denotation of a self symbol of some class?
541544
* This is the case if one of two conditions holds:
542545
* 1. It is the symbol referred to in the selfInfo part of the ClassInfo

compiler/src/dotty/tools/dotc/core/TypeErasure.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ object TypeErasure {
211211
case tp: TypeAlias => isUnboundedGeneric(tp.alias)
212212
case tp: TypeBounds => !tp.hi.derivesFrom(defn.ObjectClass)
213213
case tp: TypeProxy => isUnboundedGeneric(tp.underlying)
214-
case tp: AndType => isUnboundedGeneric(tp.tp1) || isUnboundedGeneric(tp.tp2)
215-
case tp: OrType => isUnboundedGeneric(tp.tp1) && isUnboundedGeneric(tp.tp2)
214+
case tp: AndType => isUnboundedGeneric(tp.tp1) && isUnboundedGeneric(tp.tp2)
215+
case tp: OrType => isUnboundedGeneric(tp.tp1) || isUnboundedGeneric(tp.tp2)
216216
case _ => false
217217
}
218218

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,13 @@ class ClassfileParser(
368368
case ARRAY_TAG =>
369369
while ('0' <= sig(index) && sig(index) <= '9') index += 1
370370
var elemtp = sig2type(tparams, skiptvs)
371-
// make unbounded Array[T] where T is a type variable into Ar ray[T with Object]
371+
// make unbounded Array[T] where T is a type variable into Array[T with Object]
372372
// (this is necessary because such arrays have a representation which is incompatible
373373
// with arrays of primitive types.
374374
// NOTE that the comparison to Object only works for abstract types bounded by classes that are strict subclasses of Object
375375
// if the bound is exactly Object, it will have been converted to Any, and the comparison will fail
376376
// see also RestrictJavaArraysMap (when compiling java sources directly)
377-
if (elemtp.typeSymbol.isAbstractType && !(elemtp.derivesFrom(defn.ObjectClass))) {
377+
if (elemtp.typeSymbol.isAbstractOrParamType && !(elemtp.derivesFrom(defn.ObjectClass))) {
378378
elemtp = AndType(elemtp, defn.ObjectType)
379379
}
380380
defn.ArrayOf(elemtp)

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,14 @@ object Scala2Unpickler {
6666
assert(lastArg isRef defn.ArrayClass)
6767
val elemtp0 :: Nil = lastArg.baseType(defn.ArrayClass).argInfos
6868
val elemtp = elemtp0 match {
69-
case AndType(t1, t2) if t1.typeSymbol.isAbstractType && (t2 isRef defn.ObjectClass) =>
70-
t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them.
69+
case AndType(t1, t2) => // drop intersection with Object for abstract types an parameters in varargs. Erasure can handle them.
70+
if (t2.isRef(defn.ObjectClass))
71+
t1 match {
72+
case t1: TypeParamRef => t1
73+
case t1: TypeRef if t1.symbol.isAbstractOrParamType => t1
74+
case _ => elemtp0
75+
}
76+
else elemtp0
7177
case _ =>
7278
elemtp0
7379
}

compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ object GenericSignatures {
427427
* owners (e.g. when computing lubs, <root> is used). All packageClass symbols have `isJavaDefined == true`.
428428
*/
429429
case RefOrAppliedType(sym, tp, _) =>
430-
if (sym.isAbstractType && (!sym.owner.is(JavaDefined) || sym.is(Scala2Existential)))
430+
if (sym.isAbstractOrParamType && (!sym.owner.is(JavaDefined) || sym.is(Scala2Existential)))
431431
tp
432432
else
433433
NoType

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ object RefChecks {
191191
def info = self.memberInfo(sym1)
192192
val infoStr =
193193
if (sym1.isAliasType) i", which equals ${info.bounds.hi}"
194-
else if (sym1.isAbstractType) i" with bounds$info"
194+
else if (sym1.isAbstractOrParamType) i" with bounds$info"
195195
else if (sym1.is(Module)) ""
196196
else if (sym1.isTerm) i" of type $info"
197197
else ""
@@ -913,7 +913,7 @@ class RefChecks extends MiniPhase { thisPhase =>
913913
}
914914
def underlyingClass(tp: Type): Symbol = {
915915
val sym = tp.widen.typeSymbol
916-
if (sym.isAbstractType) underlyingClass(sym.info.bounds.hi)
916+
if (sym.isAbstractOrParamType) underlyingClass(sym.info.bounds.hi)
917917
else sym
918918
}
919919
val actual = underlyingClass(other.tpe)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ class Typer extends Namer
13591359
case rhs => typedExpr(rhs, tpt1.tpe)
13601360
}
13611361
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
1362-
if (sym.is(Inline, butNot = DeferredOrParamOrAccessor))
1362+
if (sym.is(Inline, butNot = DeferredOrTermParamOrAccessor))
13631363
checkInlineConformant(rhs1, em"right-hand side of inline $sym")
13641364
patchIfLazy(vdef1)
13651365
patchFinalVals(vdef1)

tests/neg/i1747.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
class Coll[E] extends java.util.Collection[E] { // error: needs to be abstract
2-
def toArray[T](a: Array[T]): Array[T] = ??? // error: cannot override
1+
abstract class Coll[E] extends java.util.Collection[E] {
2+
override def toArray[T](a: Array[T]): Array[T] = ??? // error: has different signature
33
}

tests/pos/i1747.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
abstract class Coll[E] extends java.util.Collection[E] {
2+
override def toArray[T](a: Array[T with Object]): Array[T with Object] = ??? // error: cannot override
3+
}

tests/run/i533/JA.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class JA {
2+
public static <T> T get(T[] arr) {
3+
return arr[0];
4+
}
5+
}

tests/run/i533/Test.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val x = new Array[Int](1)
4+
x(0) = 10
5+
println(JA.get(x))
6+
}
7+
}

0 commit comments

Comments
 (0)