diff options
Diffstat (limited to 'src/compiler')
16 files changed, 92 insertions, 95 deletions
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala index 23eaa1088c..17924f0c0c 100644 --- a/src/compiler/scala/reflect/internal/Names.scala +++ b/src/compiler/scala/reflect/internal/Names.scala @@ -431,13 +431,16 @@ trait Names extends api.Names { /** A name that contains no operator chars nor dollar signs. * TODO - see if it's any faster to do something along these lines. + * Cute: now that exhaustivity kind of works, the mere presence of + * this trait causes TermName and TypeName to stop being exhaustive. + * Commented out. */ - trait AlphaNumName extends Name { - final override def encode = thisName - final override def decodedName = thisName - final override def decode = toString - final override def isOperatorName = false - } + // trait AlphaNumName extends Name { + // final override def encode = thisName + // final override def decodedName = thisName + // final override def decode = toString + // final override def isOperatorName = false + // } /** TermName_S and TypeName_S have fields containing the string version of the name. * TermName_R and TypeName_R recreate it each time toString is called. diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 93f359ae12..67c858356c 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -1973,7 +1973,7 @@ trait Types extends api.Types { self: SymbolTable => require(sym.isPackageClass, sym) override protected def finishPrefix(rest: String) = packagePrefix + rest } - class RefinementTypeRef(sym0: Symbol) extends NoArgsTypeRef(NoType, sym0) with ClassTypeRef { + class RefinementTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef { require(sym.isRefinementClass, sym) // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers @@ -2359,7 +2359,7 @@ trait Types extends api.Types { self: SymbolTable => else { if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef - else if (sym.isRefinementClass) new RefinementTypeRef(sym) + else if (sym.isRefinementClass) new RefinementTypeRef(pre, sym) else if (sym.isPackageClass) new PackageTypeRef(pre, sym) else if (sym.isModuleClass) new ModuleTypeRef(pre, sym) else new NoArgsTypeRef(pre, sym) with ClassTypeRef @@ -4318,7 +4318,7 @@ trait Types extends api.Types { self: SymbolTable => def throwError = abort("" + tp + sym.locationString + " cannot be instantiated from " + pre.widen) val symclazz = sym.owner - if (symclazz == clazz && !pre.isInstanceOf[TypeVar] && (pre.widen.typeSymbol isNonBottomSubClass symclazz)) { + if (symclazz == clazz && !pre.widen.isInstanceOf[TypeVar] && (pre.widen.typeSymbol isNonBottomSubClass symclazz)) { // have to deconst because it may be a Class[T]. pre.baseType(symclazz).deconst match { case TypeRef(_, basesym, baseargs) => diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 4461ae1cc1..9089be5cc0 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1566,20 +1566,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb refreshProgress } - /** - * Attempt to locate a source file providing the given name as a top-level - * definition in the given context, and add it to the run via compileLate - * if found. - */ - def compileSourceFor(context : analyzer.Context, name : Name) = false - - /** - * Attempt to locate a source file providing the given name as a top-level - * definition with the given prefix, and add it to the run via compileLate - * if found. - */ - def compileSourceFor(qual : Tree, name : Name) = false - /** Reset package class to state at typer (not sure what this * is needed for?) */ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 81fe907a0c..99832d1327 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -223,8 +223,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters { // unlike javaNameCache, reverseJavaName contains entries only for class symbols and their internal names.
val reverseJavaName = mutable.Map.empty[String, Symbol] ++= List(
- binarynme.RuntimeNothing.toString() -> NothingClass, // neither RuntimeNothingClass nor RuntimeNullClass belong to the co-domain of this map.
- binarynme.RuntimeNull.toString() -> NullClass
+ binarynme.RuntimeNothing.toString() -> RuntimeNothingClass, // RuntimeNothingClass is the bytecode-level return type of Scala methods with Nothing return-type.
+ binarynme.RuntimeNull.toString() -> RuntimeNullClass
)
private def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
@@ -587,7 +587,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { case None =>
reverseJavaName.put(internalName, trackedSym)
case Some(oldsym) =>
- assert(List(NothingClass, NullClass).contains(oldsym) || oldsym == trackedSym,
+ assert((oldsym == trackedSym) || List(RuntimeNothingClass, RuntimeNullClass).contains(oldsym), // NothingClass, NullClass,
"how can getCommonSuperclass() do its job if different class symbols get the same bytecode-level internal name.")
}
}
@@ -2542,7 +2542,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters { } else if(kind.isRefOrArrayType) { // REFERENCE(_) | ARRAY(_)
val Success = success
val Failure = failure
- (cond, nextBlock) match {
+ // @unchecked because references aren't compared with GT, GE, LT, LE.
+ ((cond, nextBlock) : @unchecked) match {
case (EQ, Success) => jcode emitIFNONNULL labels(failure)
case (NE, Failure) => jcode emitIFNONNULL labels(success)
case (EQ, Failure) => jcode emitIFNULL labels(success)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 17c244ee82..c29630d04b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1532,6 +1532,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with case (NE, _) => jcode emitIFNONNULL labels(success) jcode.emitGOTO_maybe_W(labels(failure), false) + case _ => } } else { (kind: @unchecked) match { diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 66e7becb12..d23571b517 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -1553,7 +1553,7 @@ abstract class GenMSIL extends SubComponent { } def emitBrBool(cond: TestOp, dest: Label) { - cond match { + (cond: @unchecked) match { // EQ -> Brfalse, NE -> Brtrue; this is because we come from // a CZJUMP. If the value on the stack is 0 (e.g. a boolean // method returned false), and we are in the case EQ, then diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index 49cd17c176..66189a6854 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -316,7 +316,6 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage def mbrCmt = mbr.comment.get def paramCommentToHtml(prs: List[ParameterEntity]): NodeSeq = prs match { - case Nil => NodeSeq.Empty case (tp: TypeParam) :: rest => val paramEntry: NodeSeq = { @@ -329,6 +328,9 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage <dt class="param">{ vp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.valueParams(vp.name)) }</dd> } paramEntry ++ paramCommentToHtml(rest) + + case _ => + NodeSeq.Empty } if (mbr.comment.isEmpty) NodeSeq.Empty diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index bf01e142c9..bbdf10a021 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -678,7 +678,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { // need to create a new block with inits and the old term treeCopy.Block(term, newStaticInits.toList, term) } - case None => + case _ => // create new static ctor val staticCtorSym = currentClass.newStaticConstructor(template.pos) val rhs = Block(newStaticInits.toList, Literal(Constant(()))) diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 007457ef7b..8556cc9ddc 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -44,8 +44,18 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { * in `extensionMethod` if the first name has the wrong type. We thereby gain a level of insensitivity * of how overloaded types are ordered between phases and picklings. */ - private def extensionNames(imeth: Symbol): Stream[Name] = - imeth.owner.info.decl(imeth.name).tpe match { + private def extensionNames(imeth: Symbol): Stream[Name] = { + val decl = imeth.owner.info.decl(imeth.name) + + // Bridge generation is done at phase `erasure`, but new scopes are only generated + // for the phase after that. So bridges are visible in earlier phases. + // + // `info.member(imeth.name)` filters these out, but we need to use `decl` + // to restrict ourselves to members defined in the current class, so we + // must do the filtering here. + val declTypeNoBridge = decl.filter(sym => !sym.isBridge).tpe + + declTypeNoBridge match { case OverloadedType(_, alts) => val index = alts indexOf imeth assert(index >= 0, alts+" does not contain "+imeth) @@ -55,6 +65,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { assert(tpe != NoType, imeth.name+" not found in "+imeth.owner+"'s decls: "+imeth.owner.info.decls) Stream(newTermName("extension$"+imeth.name)) } + } /** Return the extension method that corresponds to given instance method `meth`. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index a671b8d6b5..217cadaab8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -346,7 +346,11 @@ trait Implicits { case _ => tp } def stripped(tp: Type): Type = { - deriveTypeWithWildcards(freeTypeParametersNoSkolems.collect(tp))(tp) + // `t.typeSymbol` returns the symbol of the normalized type. If that normalized type + // is a `PolyType`, the symbol of the result type is collected. This is precisely + // what we require for SI-5318. + val syms = for (t <- tp; if t.typeSymbol.isTypeParameter) yield t.typeSymbol + deriveTypeWithWildcards(syms.distinct)(tp) } def sum(xs: List[Int]) = (0 /: xs)(_ + _) def complexity(tp: Type): Int = tp.normalize match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index abe77ead9a..85c2aebfab 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1088,7 +1088,7 @@ trait Infer { */ def inferConstructorInstance(tree: Tree, undetparams: List[Symbol], pt0: Type) { val pt = widen(pt0) - val ptparams = freeTypeParamsOfTerms.collect(pt) + val ptparams = freeTypeParamsOfTerms(pt) val ctorTp = tree.tpe val resTp = ctorTp.finalResultType @@ -1322,8 +1322,8 @@ trait Infer { def inferTypedPattern(tree0: Tree, pattp: Type, pt0: Type): Type = { val pt = widen(pt0) - val ptparams = freeTypeParamsOfTerms.collect(pt) - val tpparams = freeTypeParamsOfTerms.collect(pattp) + val ptparams = freeTypeParamsOfTerms(pt) + val tpparams = freeTypeParamsOfTerms(pattp) def ptMatchesPattp = pt matchesPattern pattp.widen def pattpMatchesPt = pattp matchesPattern pt @@ -1376,7 +1376,7 @@ trait Infer { def inferModulePattern(pat: Tree, pt: Type) = if (!(pat.tpe <:< pt)) { - val ptparams = freeTypeParamsOfTerms.collect(pt) + val ptparams = freeTypeParamsOfTerms(pt) debuglog("free type params (2) = " + ptparams) val ptvars = ptparams map freshVar val pt1 = pt.instantiateTypeParams(ptparams, ptvars) @@ -1393,19 +1393,6 @@ trait Infer { } } - abstract class SymCollector extends TypeCollector(List[Symbol]()) { - protected def includeCondition(sym: Symbol): Boolean - - def traverse(tp: Type) { - tp.normalize match { - case TypeRef(_, sym, _) => - if (includeCondition(sym) && !result.contains(sym)) result = sym :: result - case _ => - } - mapOver(tp) - } - } - object approximateAbstracts extends TypeMap { def apply(tp: Type): Type = tp.normalize match { case TypeRef(pre, sym, _) if sym.isAbstractType => WildcardType @@ -1413,31 +1400,30 @@ trait Infer { } } - /** A traverser to collect type parameters referred to in a type + /** Collects type parameters referred to in a type. */ - object freeTypeParamsOfTerms extends SymCollector { + def freeTypeParamsOfTerms(tp: Type): List[Symbol] = { // An inferred type which corresponds to an unknown type // constructor creates a file/declaration order-dependent crasher // situation, the behavior of which depends on the state at the // time the typevar is created. Until we can deal with these // properly, we can avoid it by ignoring type parameters which // have type constructors amongst their bounds. See SI-4070. - protected def includeCondition(sym: Symbol) = ( - sym.isAbstractType - && sym.owner.isTerm - && !sym.info.bounds.exists(_.typeParams.nonEmpty) - ) - } - - /** A traverser to collect type parameters referred to in a type - */ - object freeTypeParametersNoSkolems extends SymCollector { - protected def includeCondition(sym: Symbol): Boolean = - sym.isTypeParameter && sym.owner.isTerm - } + def isFreeTypeParamOfTerm(sym: Symbol) = ( + sym.isAbstractType + && sym.owner.isTerm + && !sym.info.bounds.exists(_.typeParams.nonEmpty) + ) - object typeRefs extends SymCollector { - protected def includeCondition(sym: Symbol): Boolean = true + // Intentionally *not* using `Type#typeSymbol` here, which would normalize `tp` + // and collect symbols from the result type of any resulting `PolyType`s, which + // are not free type parameters of `tp`. + // + // Contrast with `isFreeTypeParamNoSkolem`. + val syms = tp collect { + case TypeRef(_, sym, _) if isFreeTypeParamOfTerm(sym) => sym + } + syms.distinct } /* -- Overload Resolution ---------------------------------------------- */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index b4f42a5033..4eba665b93 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -473,12 +473,8 @@ trait Namers extends MethodSynthesis { if (from != nme.WILDCARD && base != ErrorType) { if (isValid(from)) { - if (currentRun.compileSourceFor(expr, from)) { - // side effecting, apparently - typeSig(tree) - } // for Java code importing Scala objects - else if (!nme.isModuleName(from) || isValid(nme.stripModuleSuffix(from))) { + if (!nme.isModuleName(from) || isValid(nme.stripModuleSuffix(from))) { typer.TyperErrorGen.NotAMemberError(tree, expr, from) typer.infer.setError(tree) } @@ -1306,14 +1302,18 @@ trait Namers extends MethodSynthesis { if (expr1.symbol != null && expr1.symbol.isRootPackage) RootImportError(tree) - val newImport = treeCopy.Import(tree, expr1, selectors).asInstanceOf[Import] - checkSelectors(newImport) - transformed(tree) = newImport - // copy symbol and type attributes back into old expression - // so that the structure builder will find it. - expr.symbol = expr1.symbol - expr.tpe = expr1.tpe - ImportType(expr1) + if (expr1.isErrorTyped) + ErrorType + else { + val newImport = treeCopy.Import(tree, expr1, selectors).asInstanceOf[Import] + checkSelectors(newImport) + transformed(tree) = newImport + // copy symbol and type attributes back into old expression + // so that the structure builder will find it. + expr.symbol = expr1.symbol + expr.tpe = expr1.tpe + ImportType(expr1) + } } val result = diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 80d40011ad..b36a92a186 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -1105,7 +1105,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride).getOrElse{ - if (requireSwitch) typer.context.unit.error(scrut.pos, "could not emit switch for @switch annotated match") + if (requireSwitch) typer.context.unit.warning(scrut.pos, "could not emit switch for @switch annotated match") if (casesNoSubstOnly nonEmpty) { // before optimizing, check casesNoSubstOnly for presence of a default case, @@ -1457,6 +1457,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def binderToUniqueTree(b: Symbol) = unique(accumSubst(normalize(CODE.REF(b))), b.tpe) + @inline def /\(conds: Iterable[Cond]) = if (conds.isEmpty) Top else conds.reduceLeft(AndCond(_, _)) + @inline def \/(conds: Iterable[Cond]) = if (conds.isEmpty) Havoc else conds.reduceLeft(OrCond(_, _)) + // note that the sequencing of operations is important: must visit in same order as match execution // binderToUniqueTree uses the type of the first symbol that was encountered as the type for all future binders def treeMakerToCond(tm: TreeMaker): Cond = { @@ -1475,7 +1478,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } ttm.renderCondition(condStrategy) case EqualityTestTreeMaker(prevBinder, patTree, _) => EqualityCond(binderToUniqueTree(prevBinder), unique(patTree)) - case AlternativesTreeMaker(_, altss, _) => altss map (_ map treeMakerToCond reduceLeft AndCond) reduceLeft OrCond + case AlternativesTreeMaker(_, altss, _) => \/(altss map (alts => /\(alts map treeMakerToCond))) case ProductExtractorTreeMaker(testedBinder, None, subst) => NonNullCond(binderToUniqueTree(testedBinder)) case ExtractorTreeMaker(_, _, _, _) | GuardTreeMaker(_) @@ -1973,6 +1976,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case Some(0) if testedBinder.tpe.typeSymbol == ListClass => // extractor.symbol.owner == SeqFactory EqualityCond(binderToUniqueTree(p.prevBinder), unique(Ident(NilModule) setType NilModule.tpe)) case _ => + backoff = true super.treeMakerToCond(tm) } case ExtractorTreeMaker(_, _, _, _) => diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 3373878beb..6d9c9c4ce8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -807,9 +807,9 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R for (i <- 0 until seenTypes.length) { val baseClass = clazz.info.baseTypeSeq(i).typeSymbol seenTypes(i) match { - case List() => + case Nil => println("??? base "+baseClass+" not found in basetypes of "+clazz) - case List(_) => + case _ :: Nil => ;// OK case tp1 :: tp2 :: _ => unit.error(clazz.pos, "illegal inheritance;\n " + clazz + diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 349bd1912b..e643a91da7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2523,7 +2523,7 @@ trait Typers extends Modes with Adaptations with Taggings { def typedImport(imp : Import) : Import = (transformed remove imp) match { case Some(imp1: Import) => imp1 - case None => log("unhandled import: "+imp+" in "+unit); imp + case _ => log("unhandled import: "+imp+" in "+unit); imp } private def isWarnablePureExpression(tree: Tree) = tree match { case EmptyTree | Literal(Constant(())) => false @@ -2549,9 +2549,11 @@ trait Typers extends Modes with Adaptations with Taggings { else stat match { case imp @ Import(_, _) => - context = context.makeNewImport(imp) imp.symbol.initialize - typedImport(imp) + if (!imp.symbol.isError) { + context = context.makeNewImport(imp) + typedImport(imp) + } else EmptyTree case _ => if (localTarget && !includesTargetPos(stat)) { // skip typechecking of statements in a sequence where some other statement includes @@ -4177,7 +4179,8 @@ trait Typers extends Modes with Adaptations with Taggings { nme.update, Apply(Select(mkCall(nme.apply), prefix) setPos fun.pos, args) setPos tree.pos ) - } + case _ => EmptyTree + } } val tree1 = qual match { @@ -4419,10 +4422,6 @@ trait Typers extends Modes with Adaptations with Taggings { var cx = startingIdentContext while (defSym == NoSymbol && cx != NoContext && (cx.scope ne null)) { // cx.scope eq null arises during FixInvalidSyms in Duplicators - // !!! Shouldn't the argument to compileSourceFor be cx, not context? - // I can't tell because those methods do nothing in the standard compiler, - // presumably they are overridden in the IDE. - currentRun.compileSourceFor(context.asInstanceOf[analyzer.Context], name) pre = cx.enclClass.prefix defEntry = cx.scope.lookupEntry(name) if ((defEntry ne null) && qualifies(defEntry.sym)) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 3d9453d8cd..d75e2705c3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -221,9 +221,9 @@ trait Unapplies extends ast.TreeDSL val bodyTpe = funParamss.foldRight(classTpe)((params, restp) => gen.scalaFunctionConstr(params.map(_.tpt), restp)) val argss = copyParamss match { - case Nil => Nil - case ps :: Nil => mmap(ps :: funParamss)(toIdent) - } + case Nil => Nil + case ps :: _ => mmap(ps :: funParamss)(toIdent) + } val body = funParamss.foldRight(New(classTpe, argss): Tree)(Function) Some(atPos(cdef.pos.focus)( |