Skip to content
Merged
12 changes: 4 additions & 8 deletions src/dotty/tools/dotc/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ object TypeErasure {
* as upper bound and that is not Java defined? Arrays of such types are
* erased to `Object` instead of `ObjectArray`.
*/
def isUnboundedGeneric(tp: Type)(implicit ctx: Context): Boolean = tp match {
def isUnboundedGeneric(tp: Type)(implicit ctx: Context): Boolean = tp.dealias match {
case tp: TypeRef =>
tp.symbol.isAbstractType &&
!tp.symbol.isClass &&
!tp.derivesFrom(defn.ObjectClass) &&
!tp.typeSymbol.is(JavaDefined)
!tp.symbol.is(JavaDefined)
case tp: PolyParam =>
!tp.derivesFrom(defn.ObjectClass) &&
!tp.binder.resultType.isInstanceOf[JavaMethodType]
Expand Down Expand Up @@ -342,11 +342,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
private def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
val defn.ArrayType(elemtp) = tp
if (elemtp derivesFrom defn.NullClass) JavaArrayType(defn.ObjectType)
else if (isUnboundedGeneric(elemtp))
elemtp match {
case elemtp: TypeRef if elemtp.symbol.is(JavaDefined) => JavaArrayType(defn.ObjectType)
case _ => defn.ObjectType
}
else if (isUnboundedGeneric(elemtp)) defn.ObjectType
else JavaArrayType(this(elemtp))
}

Expand Down
6 changes: 5 additions & 1 deletion src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,12 @@ object desugar {
val caseParams = constrVparamss.head.toArray
val productElemMeths = for (i <- 0 until arity) yield
syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeName), caseParams(i).name))
val hasRepeatedParam = constrVparamss.exists(_.exists {
case ValDef(_, PostfixOp(_, nme.raw.STAR), _) => true
case _ => false
})
val copyMeths =
if (mods is Abstract) Nil
if (mods.is(Abstract) || hasRepeatedParam) Nil // cannot have default arguments for repeated parameters, hence copy method is not issued
else {
def copyDefault(vparam: ValDef) =
makeAnnotated(defn.UncheckedVarianceAnnot, refOfDef(vparam))
Expand Down
6 changes: 5 additions & 1 deletion src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,11 @@ object Contexts {
if (implicitsCache == null )
implicitsCache = {
val implicitRefs: List[TermRef] =
if (isClassDefContext) owner.thisType.implicitMembers
if (isClassDefContext)
try owner.thisType.implicitMembers
catch {
case ex: CyclicReference => Nil
}
else if (isImportContext) importInfo.importedImplicits
else if (isNonEmptyScopeContext) scope.implicitDecls
else Nil
Expand Down
15 changes: 12 additions & 3 deletions src/dotty/tools/dotc/core/NameOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ object NameOps {
def isSetterName = name endsWith SETTER_SUFFIX
def isSingletonName = name endsWith SINGLETON_SUFFIX
def isModuleClassName = name endsWith MODULE_SUFFIX
def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX
def isImportName = name startsWith IMPORT
def isFieldName = name endsWith LOCAL_SUFFIX
def isInheritedName = name.length > 0 && name.head == '(' && name.startsWith(nme.INHERITED)
Expand Down Expand Up @@ -129,11 +130,19 @@ object NameOps {
/** If name ends in module class suffix, drop it */
def stripModuleClassSuffix: Name =
if (isModuleClassName) name dropRight MODULE_SUFFIX.length else name

/** Append a suffix so that this name does not clash with another name in the same scope */
def avoidClashName: TermName = (name ++ AVOID_CLASH_SUFFIX).toTermName

/** If name ends in "avoid clash" suffix, drop it */
def stripAvoidClashSuffix: Name =
if (isAvoidClashName) name dropRight AVOID_CLASH_SUFFIX.length else name

/** If flags is a ModuleClass but not a Package, add module class suffix */
def adjustIfModuleClass(flags: Flags.FlagSet): N =
if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName.asInstanceOf[N]
else name
def adjustIfModuleClass(flags: Flags.FlagSet): N = {
if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName
else stripAvoidClashSuffix
}.asInstanceOf[N]

/** The superaccessor for method with given name */
def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName
Expand Down
1 change: 1 addition & 0 deletions src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ object StdNames {
val INTERPRETER_WRAPPER_SUFFIX: N = "$object"
val LOCALDUMMY_PREFIX: N = "<local " // owner of local blocks
val MODULE_SUFFIX: N = NameTransformer.MODULE_SUFFIX_STRING
val AVOID_CLASH_SUFFIX: N = "$_avoid_name_clash_$"
val MODULE_VAR_SUFFIX: N = "$module"
val NAME_JOIN: N = NameTransformer.NAME_JOIN_STRING
val USCORE_PARAM_PREFIX: N = "_$"
Expand Down
9 changes: 7 additions & 2 deletions src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,14 @@ object SymDenotations {
myInfo = tp
}

/** The name, except if this is a module class, strip the module class suffix */
/** The name, except
* - if this is a module class, strip the module class suffix
* - if this is a companion object with a clash-avoiding name, strip the
* "avoid clash" suffix
*/
def effectiveName(implicit ctx: Context) =
if (this is ModuleClass) name.stripModuleClassSuffix else name
if (this is ModuleClass) name.stripModuleClassSuffix
else name.stripAvoidClashSuffix

/** The privateWithin boundary, NoSymbol if no boundary is given.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2976,7 +2976,7 @@ object Types {
val ex = new CyclicReference(denot)
if (!(ctx.mode is typer.Mode.CheckCyclic)) {
cyclicErrors.println(ex.getMessage)
for (elem <- ex.getStackTrace take 40)
for (elem <- ex.getStackTrace take 50)
cyclicErrors.println(elem.toString)
}
ex
Expand Down
10 changes: 9 additions & 1 deletion src/dotty/tools/dotc/transform/FirstTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,15 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi

def addMissingCompanions(stats: List[Tree]): List[Tree] = stats map {
case stat: TypeDef if singleClassDefs contains stat.name =>
Thicket(stat :: newCompanion(stat.name.toTermName).trees)
val objName = stat.name.toTermName
val nameClash = stats.exists {
case other: MemberDef =>
other.name == objName && other.symbol.info.isParameterless
case _ =>
false
}
val uniqueName = if (nameClash) objName.avoidClashName else objName
Thicket(stat :: newCompanion(uniqueName).trees)
case stat => stat
}

Expand Down
22 changes: 11 additions & 11 deletions src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,15 @@ class Namer { typer: Typer =>

def typeDefSig(tdef: TypeDef, sym: Symbol)(implicit ctx: Context): Type = {
completeParams(tdef.tparams)
sym.info = TypeBounds.empty
val tparamSyms = tdef.tparams map symbolOfTree
val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree]
val toParameterize = tparamSyms.nonEmpty && !isDerived
val needsLambda = sym.allOverriddenSymbols.exists(_ is HigherKinded) && !isDerived
def abstracted(tp: Type): Type =
if (needsLambda) tp.LambdaAbstract(tparamSyms)
else if (toParameterize) tp.parameterizeWith(tparamSyms)
else tp
sym.info = abstracted(TypeBounds.empty)
// Temporarily set info of defined type T to ` >: Nothing <: Any.
// This is done to avoid cyclic reference errors for F-bounds.
// This is subtle: `sym` has now an empty TypeBounds, but is not automatically
Expand All @@ -684,18 +692,10 @@ class Namer { typer: Typer =>
//
// The scheme critically relies on an implementation detail of isRef, which
// inspects a TypeRef's info, instead of simply dealiasing alias types.
val tparamSyms = tdef.tparams map symbolOfTree
val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree]
val toParameterize = tparamSyms.nonEmpty && !isDerived
val needsLambda = sym.allOverriddenSymbols.exists(_ is HigherKinded) && !isDerived
val rhsType = typedAheadType(tdef.rhs).tpe
def abstractedRhsType =
if (needsLambda) rhsType.LambdaAbstract(tparamSyms)
else if (toParameterize) rhsType.parameterizeWith(tparamSyms)
else rhsType
val unsafeInfo = rhsType match {
case _: TypeBounds => abstractedRhsType.asInstanceOf[TypeBounds]
case _ => TypeAlias(abstractedRhsType, if (sym is Local) sym.variance else 0)
case _: TypeBounds => abstracted(rhsType).asInstanceOf[TypeBounds]
case _ => TypeAlias(abstracted(rhsType), if (sym is Local) sym.variance else 0)
}
sym.info = NoCompleter
checkNonCyclic(sym, unsafeInfo, reportErrors = true)
Expand Down
6 changes: 0 additions & 6 deletions src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,6 @@ object RefChecks {
emitOverrideError(overrideErrorMsg(msg))
}

def overrideTypeError() = {
if (noErrorType) {
emitOverrideError(overrideErrorMsg("has incompatible type"))
}
}

def overrideAccessError() = {
ctx.log(i"member: ${member.showLocated} ${member.flags}") // DEBUG
ctx.log(i"other: ${other.showLocated} ${other.flags}") // DEBUG
Expand Down
5 changes: 3 additions & 2 deletions test/test/DottyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import dotty.tools.dotc.Compiler
import dotty.tools.dotc
import dotty.tools.dotc.core.Phases.Phase

class DottyTest extends ContextEscapeDetection{
class DottyTest /*extends ContextEscapeDetection*/ {

dotty.tools.dotc.parsing.Scanners // initialize keywords

Expand All @@ -36,11 +36,12 @@ class DottyTest extends ContextEscapeDetection{
base.definitions.init(ctx)
ctx
}

/*
override def getCtx: Context = ctx
override def clearCtx() = {
ctx = null
}
*/
private def compilerWithChecker(phase: String)(assertion:(tpd.Tree, Context) => Unit) = new Compiler {
self =>
override def phases = {
Expand Down
33 changes: 33 additions & 0 deletions tests/disabled/rewrite-needed/CustomGlobal.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package custom

import scala.tools.nsc._, reporters._, typechecker._

/** Demonstration of a custom Global with a custom Typer,
* decoupled from trunk. Demonstration:
*
{{{
scalac -d . CustomGlobal.scala && scala -nc -Yglobal-class custom.CustomGlobal \
-e 'class Bippy(x: Int) ; def f = new Bippy(5)'

I'm typing a Bippy! It's a ClassDef.
I'm typing a Bippy! It's a Ident.
I'm typing a Bippy! It's a DefDef.
}}}
*
*/
class CustomGlobal(currentSettings: Settings, reporter: Reporter) extends Global(currentSettings, reporter) {
override lazy val analyzer = new {
val global: CustomGlobal.this.type = CustomGlobal.this
} with Analyzer {
override def newTyper(context: Context): Typer = new CustomTyper(context)

class CustomTyper(context : Context) extends Typer(context) {
override def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
if (tree.summaryString contains "Bippy")
println("I'm typing a Bippy! It's a " + tree.shortClass + ".")

super.typed(tree, mode, pt)
}
}
}
}
5 changes: 0 additions & 5 deletions tests/new/t296.scala

This file was deleted.

2 changes: 2 additions & 0 deletions tests/pending/pos/annotations.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Needs an implementation of beanproperty to work

class ann(i: Int) extends scala.annotation.Annotation
class cfann(x: String) extends annotation.ClassfileAnnotation

Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion tests/pending/pos/S5.scala → tests/pos/S5.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Here's a fragment of a Scala encoding for the Keris module system;
/* Original comment:
* Here's a fragment of a Scala encoding for the Keris module system;
** the compiler claims:
**
** S5.scala:28: value n in class N of type N.this._N.n
Expand Down
File renamed without changes.
File renamed without changes.
52 changes: 52 additions & 0 deletions tests/pos/SI-7638a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Same as SI-7638, but without (Int) arguments to @specialized
package miniboxing.tests.compile

trait Ordering[@specialized A] {
def eqv(x: Array[A], y: Array[A]): Boolean = false
}

trait ArrayVectorOrder[@specialized A] extends Ordering[A] {
override def eqv(x: Array[A], y: Array[A]): Boolean = super.eqv(x, y)
}

object vectorOrder {
implicit def arrayOrder[@specialized A](): miniboxing.tests.compile.ArrayVectorOrder[A] =
/*
* Before applying patch:
*
* while compiling: SI-7638.scala
* during phase: mixin
* library version: version 2.10.3-20130625-164027-d22e8d282c
* compiler version: version 2.10.3-20130627-153946-54cb6af7db
* reconstructed args:
*
* last tree to typer: TypeTree(class Array)
* symbol: class Array in package scala (flags: final)
* symbol definition: final class Array[T >: ? <: ?] extends Object
* tpe: Array[Int]
* symbol owners: class Array -> package scala
* context owners: anonymous class anon$1 -> package compile
*
* == Expanded type of tree ==
*
* TypeRef(
* TypeSymbol(final class Array[T >: ? <: ?] extends Object)
* args = List(TypeRef(TypeSymbol(final abstract class Int extends )))
* )
*
* unhandled exception while transforming SI-7638.scala
* error: uncaught exception during compilation: java.lang.UnsupportedOperationException
* error: java.lang.UnsupportedOperationException: tail of empty list
* at scala.collection.immutable.Nil$.tail(List.scala:339)
* at scala.collection.immutable.Nil$.tail(List.scala:334)
* at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$rebindSuper$1.apply(Mixin.scala:123)
* at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$rebindSuper$1.apply(Mixin.scala:122)
* at scala.reflect.internal.SymbolTable.atPhase(SymbolTable.scala:207)
* at scala.reflect.internal.SymbolTable.afterPhase(SymbolTable.scala:216)
* at scala.tools.nsc.Global.afterPickler(Global.scala:1104)
* at scala.tools.nsc.transform.Mixin.scala$tools$nsc$transform$Mixin$$rebindSuper(Mixin.scala:122)
* at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$mixinTraitMembers$1$1.apply(Mixin.scala:339)
* at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$mixinTraitMembers$1$1.apply(Mixin.scala:292)
*/
new ArrayVectorOrder[A] { }
}
4 changes: 3 additions & 1 deletion tests/pos/t296.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
object Bug {
def foo (l: => String) : String = 12 match { case _ => l}
def foo (l: => String, l1: => String) : String = 12 match {
case 12 => l1
case _ => l}
}
17 changes: 0 additions & 17 deletions tests/untried/pos/t2610.scala

This file was deleted.