diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 9c0174d89b99..4d35e12b5834 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2234,7 +2234,7 @@ self => if (ofCaseClass && in.token != LPAREN) syntaxError(in.lastOffset, "case classes without a parameter list are not allowed;\n"+ "use either case objects or case classes with an explicit `()' as a parameter list.") - while (implicitmod == 0 && in.token == LPAREN) { + while (in.token == LPAREN) { in.nextToken() vds += paramClause() accept(RPAREN) diff --git a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala index 1f1ccbe359c6..8e000aca8eee 100644 --- a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala +++ b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala @@ -52,7 +52,7 @@ trait DestructureTypes { else node("assocs", nodeList(names.indices.toList, (i: Int) => atom(names(i).toString, args(i)))) } private def typeTypeName(tp: Type) = tp match { - case mt @ MethodType(_, _) if mt.isImplicit => "ImplicitMethodType" + case mt @ MethodType(_, _) if mt.isImplicit => "ImplicitMethodType" // case TypeRef(_, sym, _) => typeRefType(sym) case _ => tp.kind } diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala index 97de2b6c850e..1069d9210be1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -99,7 +99,7 @@ trait EtaExpansion { self: Analyzer => /* Eta-expand lifted tree. */ def expand(tree: Tree, tpe: Type): Tree = tpe match { - case mt @ MethodType(paramSyms, restpe) if !mt.isImplicit => + case mt @ MethodType(paramSyms, restpe) if !mt.isImplicit => // val params: List[(ValDef, Boolean)] = paramSyms.map { sym => val origTpe = sym.tpe diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index bee2ae8e9932..ac34f8bca229 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -538,7 +538,7 @@ trait Implicits { private def checkCompatibility(fast: Boolean, tp0: Type, pt0: Type): Boolean = { @tailrec def loop(tp: Type, pt: Type): Boolean = tp match { case mt @ MethodType(params, restpe) => - if (mt.isImplicit) + if (mt.isImplicit) // loop(restpe, pt) else pt match { case tr @ TypeRef(pre, sym, args) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index dc91d23011c9..a77b698e5e30 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -148,7 +148,7 @@ trait Infer extends Checkable { } def skipImplicit(tp: Type) = tp match { - case mt: MethodType if mt.isImplicit => mt.resultType + case mt: MethodType if mt.isImplicit => mt.resultType // case _ => tp } @@ -163,7 +163,7 @@ trait Infer extends Checkable { logResult(sm"""|Normalizing PolyType in infer: | was: $restpe | now""")(normalize(restpe)) - case mt @ MethodType(_, restpe) if mt.isImplicit => normalize(restpe) + case mt @ MethodType(_, restpe) if mt.isImplicit => normalize(restpe) // case mt @ MethodType(_, restpe) if !mt.isDependentMethodType => if (phase.erasedTypes) FunctionClass(mt.params.length).tpe else functionType(mt.paramTypes, normalize(restpe)) @@ -366,7 +366,7 @@ trait Infer extends Checkable { // optimize type variables wrt to the implicit formals only; ignore the result type. // See test pos/jesper.scala def variance = restpe match { - case mt: MethodType if mt.isImplicit && isFullyDefined(pt) => MethodType(mt.params, AnyTpe) + case mt: MethodType if mt.isImplicit && isFullyDefined(pt) => MethodType(mt.params, AnyTpe) // case _ => restpe } def solve() = solvedTypes(tvars, tparams, tparams map varianceInType(variance), upper = false, lubDepth(restpe :: pt :: Nil)) @@ -811,21 +811,21 @@ trait Infer extends Checkable { def onRight = ftpe2 match { case OverloadedType(pre, alts) => alts forall (alt => isAsSpecific(ftpe1, pre memberType alt)) case et: ExistentialType => et.withTypeVars(isAsSpecific(ftpe1, _)) - case mt @ MethodType(_, restpe) => !mt.isImplicit || isAsSpecific(ftpe1, restpe) + case mt @ MethodType(_, restpe) => !mt.isImplicit || isAsSpecific(ftpe1, restpe) // case NullaryMethodType(res) => isAsSpecific(ftpe1, res) case PolyType(tparams, NullaryMethodType(restpe)) => isAsSpecific(ftpe1, PolyType(tparams, restpe)) - case PolyType(tparams, mt @ MethodType(_, restpe)) => !mt.isImplicit || isAsSpecific(ftpe1, PolyType(tparams, restpe)) + case PolyType(tparams, mt @ MethodType(_, restpe)) => !mt.isImplicit || isAsSpecific(ftpe1, PolyType(tparams, restpe)) // case _ => isAsSpecificValueType(ftpe1, ftpe2, Nil, Nil) } ftpe1 match { case OverloadedType(pre, alts) => alts exists (alt => isAsSpecific(pre memberType alt, ftpe2)) case et: ExistentialType => isAsSpecific(et.skolemizeExistential, ftpe2) case NullaryMethodType(restpe) => isAsSpecific(restpe, ftpe2) - case mt @ MethodType(_, restpe) if mt.isImplicit => isAsSpecific(restpe, ftpe2) + case mt @ MethodType(_, restpe) if mt.isImplicit => isAsSpecific(restpe, ftpe2) // case mt @ MethodType(_, _) if bothAreVarargs => checkIsApplicable(mt.paramTypes mapConserve repeatedToSingle) case mt @ MethodType(params, _) if params.nonEmpty => checkIsApplicable(mt.paramTypes) case PolyType(tparams, NullaryMethodType(restpe)) => isAsSpecific(PolyType(tparams, restpe), ftpe2) - case PolyType(tparams, mt @ MethodType(_, restpe)) if mt.isImplicit => isAsSpecific(PolyType(tparams, restpe), ftpe2) + case PolyType(tparams, mt @ MethodType(_, restpe)) if mt.isImplicit => isAsSpecific(PolyType(tparams, restpe), ftpe2) // case PolyType(_, mt @ MethodType(params, _)) if params.nonEmpty => checkIsApplicable(mt.paramTypes) case ErrorType => true case _ => onRight diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 8f5c4b9f6db4..92e51976ce8c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1165,7 +1165,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper notifyUndetparamsAdded(tparams1) adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt, original) - case mt: MethodType if mode.typingExprNotFunNotLhs && mt.isImplicit => // (4.1) + case mt: MethodType if mode.typingExprNotFunNotLhs && mt.isImplicit => // (4.1) // adaptToImplicitMethod(mt) case mt: MethodType if mode.typingExprNotFunNotLhs && !hasUndetsInMonoMode && !treeInfo.isMacroApplicationOrBlock(tree) => instantiateToMethodType(mt) diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 64535a749f54..1cc79e6f2866 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -1079,7 +1079,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") val context = doLocateContext(pos) val shouldTypeQualifier = tree0.tpe match { case null => true - case mt: MethodType => mt.isImplicit + case mt: MethodType => mt.isImplicit // case _ => false } diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 86b70643c923..7d8f3b431708 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -268,7 +268,7 @@ abstract class TreeInfo { def mayBeVarGetter(sym: Symbol): Boolean = sym.info match { case NullaryMethodType(_) => sym.owner.isClass && !sym.isStable case PolyType(_, NullaryMethodType(_)) => sym.owner.isClass && !sym.isStable - case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable + case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable // case _ => false } diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index de82a6a0b26c..a48dedbedb82 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -4025,7 +4025,7 @@ trait Types } def isImplicitMethodType(tp: Type) = tp match { - case mt: MethodType => mt.isImplicit + case mt: MethodType => mt.isImplicit // case _ => false } @@ -4219,7 +4219,7 @@ trait Types tp2 match { case mt2 @ MethodType(params2, res2) => // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performancewise?) - mt1.isImplicit == mt2.isImplicit && + mt1.isImplicit == mt2.isImplicit && // matchingParams(params1, params2, mt1.isJava, mt2.isJava) && matchesQuantified(params1, params2, res1, res2) case NullaryMethodType(res2) => diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala index cf274f24bb94..cac1e45fba08 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala @@ -157,7 +157,7 @@ trait TypeComparers { private def isSameMethodType(mt1: MethodType, mt2: MethodType) = ( isSameTypes(mt1.paramTypes, mt2.paramTypes) && (mt1.resultType =:= mt2.resultType.substSym(mt2.params, mt1.params)) - && (mt1.isImplicit == mt2.isImplicit) + && (mt1.isImplicit == mt2.isImplicit) // ) private def equalTypeParamsAndResult(tparams1: List[Symbol], res1: Type, tparams2: List[Symbol], res2: Type) = { @@ -489,7 +489,7 @@ trait TypeComparers { val params2 = mt2.params val res2 = mt2.resultType (sameLength(params1, params2) && - mt1.isImplicit == mt2.isImplicit && + mt1.isImplicit == mt2.isImplicit && // matchingParams(params1, params2, mt1.isJava, mt2.isJava) && isSubType(res1.substSym(params1, params2), res2, depth)) // TODO: if mt1.params.isEmpty, consider NullaryMethodType? diff --git a/test/files/pos/multi-implicits.scala b/test/files/pos/multi-implicits.scala new file mode 100644 index 000000000000..0238ee53892c --- /dev/null +++ b/test/files/pos/multi-implicits.scala @@ -0,0 +1,29 @@ +package test + +object Test { + // A couple of type classes with type members ... + trait Foo[T] { + type A + } + + object Foo { + implicit val fooIS = new Foo[Int] { type A = String } + } + + trait Bar[T] { + type B + val value: B + } + + object Bar { + implicit val barSB = new Bar[String] { + type B = Boolean + val value = true + } + } + + def run[T](t: T)(implicit foo: Foo[T])(bar: Bar[foo.A]): bar.B = bar.value + + val value = run(23) + assert(value: Boolean) +}