diff options
author | Paul Phillips <paulp@improving.org> | 2012-09-20 14:33:59 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-09-20 15:07:28 -0700 |
commit | 2097a653642927c39b1cb614546240ac9213f3fb (patch) | |
tree | 646778309893b3394fc36c720bd0bda4e0f86006 /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | feb77881ff8bc1e46c8ae4317a9d95cbf97e34bd (diff) | |
parent | c065bde5f50cae3e1fa6d0724e2043818d6301e9 (diff) | |
download | scala-2097a653642927c39b1cb614546240ac9213f3fb.tar.gz scala-2097a653642927c39b1cb614546240ac9213f3fb.tar.bz2 scala-2097a653642927c39b1cb614546240ac9213f3fb.zip |
Merge branch '2.10.x'
* 2.10.x: (36 commits)
Normalized line endings.
New .gitattributes file.
Disabled failing build manager tests.
New test case for SI-6337
New test case for closing SI-6385
Value classes: eliminated half-boxing
Cleanup of OverridingPairs
Fixes SI-6260
Use faster download URL now that artifactory is fixed.
don't try to create tags w/o scala-reflect.jar
some small remaining fixes
SI-5943 toolboxes now autoimport Predef and scala
Fix for loud test.
SI-6363 deploys the updated starr
SI-6363 removes scala.reflect.base
SI-6392 wraps non-terms before typecheck/eval
SI-6394 fixes macros.Context.enclosingClass
Error message improvement for SI-6336.
Adjustments to scala.concurrent.duration.
prepping for the refactoring
...
Conflicts:
src/actors-migration/scala/actors/Pattern.scala
src/compiler/scala/tools/nsc/Global.scala
src/compiler/scala/tools/nsc/transform/Erasure.scala
src/compiler/scala/tools/nsc/typechecker/Typers.scala
src/library/scala/collection/immutable/Vector.scala
test/files/jvm/actmig-PinS_1.scala
test/files/jvm/actmig-PinS_2.scala
test/files/jvm/actmig-PinS_3.scala
test/files/jvm/actmig-public-methods_1.scala
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 7b5a5144b0..2344e71883 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -91,7 +91,7 @@ trait Typers extends Modes with Adaptations with Tags { // - we may virtualize matches (if -Xexperimental and there's a suitable __match in scope) // - we synthesize PartialFunction implementations for `x => x match {...}` and `match {...}` when the expected type is PartialFunction // this is disabled by: -Xoldpatmat or interactive compilation (we run it for scaladoc due to SI-5933) - @inline private def newPatternMatching = !settings.XoldPatmat.value && !forInteractive //&& !forScaladoc && (phase.id < currentRun.uncurryPhase.id) + private def newPatternMatching = !settings.XoldPatmat.value && !forInteractive //&& !forScaladoc && (phase.id < currentRun.uncurryPhase.id) abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tag with TyperContextErrors { import context0.unit @@ -478,7 +478,6 @@ trait Typers extends Modes with Adaptations with Tags { /** The typer for an expression, depending on where we are. If we are before a superclass * call, this is a typer over a constructor context; otherwise it is the current typer. */ - @inline final def constrTyperIf(inConstr: Boolean): Typer = if (inConstr) { assert(context.undetparams.isEmpty, context.undetparams) @@ -1198,7 +1197,7 @@ trait Typers extends Modes with Adaptations with Tags { val found = tree.tpe if (!found.isErroneous && !pt.isErroneous) { - if (!context.reportErrors && isPastTyper) { + if ((!context.reportErrors && isPastTyper) || tree.attachments.get[MacroExpansionAttachment].isDefined) { val (bound, req) = pt match { case ExistentialType(qs, tpe) => (qs, tpe) case _ => (Nil, pt) @@ -1231,6 +1230,17 @@ trait Typers extends Modes with Adaptations with Tags { // to consistently transform skolems and fix 6029), I'd like to // investigate ways to avoid skolems completely. // + // upd. The same problem happens when we try to typecheck the result of macro expansion against its expected type + // (which is the return type of the macro definition instantiated in the context of expandee): + // + // Test.scala:2: error: type mismatch; + // found : $u.Expr[Class[_ <: Object]] + // required: reflect.runtime.universe.Expr[Class[?0(in value <local Test>)]] where type ?0(in value <local Test>) <: Object + // scala.reflect.runtime.universe.reify(new Object().getClass) + // ^ + // Therefore following Martin's advice I use this logic to recover from skolem errors after macro expansions + // (by adding the ` || tree.attachments.get[MacroExpansionAttachment].isDefined` clause to the conditional above). + // log("recovering from existential or skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree) return adapt(tree, mode, deriveTypeWithWildcards(boundOrSkolems)(pt)) } @@ -1395,8 +1405,10 @@ trait Typers extends Modes with Adaptations with Tags { case List(acc) => def isUnderlyingAcc(sym: Symbol) = sym == acc || acc.hasAccessorFlag && sym == acc.accessed - if (acc.accessBoundary(clazz) != rootMirror.RootClass) + if (acc.accessBoundary(clazz) != rootMirror.RootClass) unit.error(acc.pos, "value class needs to have a publicly accessible val parameter") + else if (acc.tpe.typeSymbol.isDerivedValueClass) + unit.error(acc.pos, "value class may not wrap another user-defined value class") for (stat <- body) if (!treeInfo.isAllowedInUniversalTrait(stat) && !isUnderlyingAcc(stat.symbol)) unit.error(stat.pos, @@ -1557,7 +1569,7 @@ trait Typers extends Modes with Adaptations with Tags { */ def validateParentClasses(parents: List[Tree], selfType: Type) { val pending = ListBuffer[AbsTypeError]() - @inline def validateDynamicParent(parent: Symbol) = + def validateDynamicParent(parent: Symbol) = if (parent == DynamicClass) checkFeature(parent.pos, DynamicsFeature) def validateParentClass(parent: Tree, superclazz: Symbol) = @@ -1974,32 +1986,44 @@ trait Typers extends Modes with Adaptations with Tags { * - the self-type of the refinement * - a type member of the refinement * - an abstract type declared outside of the refinement. + * - an instance of a value class + * Furthermore, the result type may not be a value class either */ - def checkMethodStructuralCompatible(meth: Symbol): Unit = { - def fail(msg: String) = unit.error(meth.pos, msg) + def checkMethodStructuralCompatible(ddef: DefDef): Unit = { + val meth = ddef.symbol + def fail(pos: Position, msg: String) = unit.error(pos, msg) val tp: Type = meth.tpe match { case mt @ MethodType(_, _) => mt case NullaryMethodType(restpe) => restpe // TODO_NMT: drop NullaryMethodType from resultType? case PolyType(_, restpe) => restpe case _ => NoType } - def failStruct(what: String) = - fail(s"Parameter type in structural refinement may not refer to $what") - for (paramType <- tp.paramTypes) { + def nthParamPos(n: Int) = ddef.vparamss match { + case xs :: _ if xs.length > n => xs(n).pos + case _ => meth.pos + } + def failStruct(pos: Position, what: String, where: String = "Parameter") = + fail(pos, s"$where type in structural refinement may not refer to $what") + + foreachWithIndex(tp.paramTypes) { (paramType, idx) => val sym = paramType.typeSymbol + def paramPos = nthParamPos(idx) if (sym.isAbstractType) { if (!sym.hasTransOwner(meth.owner)) - failStruct("an abstract type defined outside that refinement") + failStruct(paramPos, "an abstract type defined outside that refinement") else if (!sym.hasTransOwner(meth)) - failStruct("a type member of that refinement") + failStruct(paramPos, "a type member of that refinement") } if (sym.isDerivedValueClass) - failStruct("a user-defined value class") + failStruct(paramPos, "a user-defined value class") if (paramType.isInstanceOf[ThisType] && sym == meth.owner) - failStruct("the type of that refinement (self type)") + failStruct(paramPos, "the type of that refinement (self type)") } + if (tp.resultType.typeSymbol.isDerivedValueClass) + failStruct(ddef.tpt.pos, "a user-defined value class", where = "Result") } + def typedUseCase(useCase: UseCase) { def stringParser(str: String): syntaxAnalyzer.Parser = { val file = new BatchSourceFile(context.unit.source.file, str) { @@ -2116,7 +2140,7 @@ trait Typers extends Modes with Adaptations with Tags { } } if (meth.isStructuralRefinementMember) - checkMethodStructuralCompatible(meth) + checkMethodStructuralCompatible(ddef) if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match { case List(param) :: _ if !param.isImplicit => @@ -3842,7 +3866,7 @@ trait Typers extends Modes with Adaptations with Tags { case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs) case t => (t, Nil) } - @inline def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty + def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty def desugaredApply = tree match { case Select(`qual`, nme.apply) => true @@ -3880,8 +3904,8 @@ trait Typers extends Modes with Adaptations with Tags { } } - @inline final def deindentTyping() = context.typingIndentLevel -= 2 - @inline final def indentTyping() = context.typingIndentLevel += 2 + final def deindentTyping() = context.typingIndentLevel -= 2 + final def indentTyping() = context.typingIndentLevel += 2 @inline final def printTyping(s: => String) = { if (printTypings) println(context.typingIndent + s.replaceAll("\n", "\n" + context.typingIndent)) @@ -4721,12 +4745,10 @@ trait Typers extends Modes with Adaptations with Tags { */ def typedIdent(tree: Tree, name: Name): Tree = { var errorContainer: AbsTypeError = null - @inline def ambiguousError(msg: String) = { assert(errorContainer == null, "Cannot set ambiguous error twice for identifier") errorContainer = AmbiguousIdentError(tree, name, msg) } - @inline def identError(tree: AbsTypeError) = { assert(errorContainer == null, "Cannot set ambiguous error twice for identifier") errorContainer = tree |