diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 11 |
3 files changed, 14 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index d5fd594c2f..e3c40aee40 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -821,24 +821,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { } else { def doDynamic(fn: Tree, qual: Tree): Tree = { - if (fn.symbol.owner.isRefinementClass && fn.symbol.allOverriddenSymbols.isEmpty) { - /* a dynamic apply can only be done when all parameters are statically known - * (i.e. no type parameters in refinement) so that static dispatch can be done - * properly. See phase cleanup for more about that. */ - def testParams(tpe: Type): Unit = tpe match { - case MethodType(paramTypes, resType) => - paramTypes map { t => t match { - case TypeRef(NoPrefix, sym, Nil) if sym.isAbstractType && sym.owner != fn.symbol => - unit.error(fn.pos,"Parameter is defined as type variable "+sym.name.toString+" in a refinement.") - case _ => - } - } - case PolyType(tp, res) => testParams(res) - } - testParams(fn.symbol.tpe) - + if (fn.symbol.owner.isRefinementClass && fn.symbol.allOverriddenSymbols.isEmpty) ApplyDynamic(qual, args) setSymbol fn.symbol setPos tree.pos - } else tree } fn match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 8acb9173af..11b8d555c0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -940,6 +940,8 @@ trait Infer { case TypeRef(pre, sym, args) => if (sym.isAbstractType) patternWarning(tp, "abstract type ") + else if (sym.isAliasType) + check(tp.normalize, bound) else if (sym == AllClass || sym == AllRefClass) error(pos, "this type cannot be used in a type pattern") else diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 20797b87b8..37b47325f4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1182,6 +1182,12 @@ trait Typers { self: Analyzer => } } + private def checkStructuralCondition(refinement: Symbol, vparam: ValDef) { + val tp = vparam.symbol.tpe + if (tp.typeSymbol.isAbstractType && !(tp.typeSymbol.ownerChain contains refinement)) + error(vparam.tpt.pos,"Parameter type in structural refinement may not refer to abstract type defined outside that same refinement") + } + /** * @param ddef ... * @return ... @@ -1218,6 +1224,11 @@ trait Typers { self: Analyzer => phase.id <= currentRun.typerPhase.id && !reporter.hasErrors) computeParamAliases(meth.owner, vparamss1, rhs1) if (tpt1.tpe.typeSymbol != AllClass && !context.returnsSeen) rhs1 = checkDead(rhs1) + + if (meth.owner.isRefinementClass && meth.allOverriddenSymbols.isEmpty) + for (vparams <- ddef.vparamss; vparam <- vparams) + checkStructuralCondition(meth.owner, vparam) + copy.DefDef(ddef, ddef.mods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType } |