Skip to content

Fix #533: Some isAbstractType tests should succeed for parameters #3931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 30, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc says Deferred term member or a parameter accessor, which is incorrect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll roll that into a future PR.


/** value that's final or inline */
final val FinalOrInline = Final | Inline
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -529,14 +529,17 @@ 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)

/** 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ object GenericSignatures {
* owners (e.g. when computing lubs, <root> 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
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions tests/run/i533/JA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class JA {
public static <T> T get(T[] arr) {
return arr[0];
}
}
7 changes: 7 additions & 0 deletions tests/run/i533/Test.scala
Original file line number Diff line number Diff line change
@@ -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))
}
}