From 7fa6c08f531a65d4b238deee8907644b8a37a499 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 24 Sep 2010 12:30:39 +0000 Subject: closes #3808. moved typing indentation to where it belongs, now inliner shuold be able to do its job in implicits as well no review --- .../scala/tools/nsc/typechecker/Contexts.scala | 3 +++ .../scala/tools/nsc/typechecker/Infer.scala | 29 +++++++--------------- .../scala/tools/nsc/typechecker/Typers.scala | 14 +++++------ test/files/pos/t3808.scala | 11 ++++++++ 4 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 test/files/pos/t3808.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 900f7e471b..7973313786 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -121,6 +121,8 @@ trait Contexts { self: Analyzer => var savedTypeBounds: List[(Symbol, Type)] = List() // saved type bounds // for type parameters which are narrowed in a GADT + var typingIndent: String = "" + def undetparams = _undetparams def undetparams_=(ps: List[Symbol]) = { //System.out.println("undetparams = " + ps);//debug @@ -175,6 +177,7 @@ trait Contexts { self: Analyzer => c.reportAmbiguousErrors = this.reportAmbiguousErrors c.reportGeneralErrors = this.reportGeneralErrors c.diagnostic = this.diagnostic + c.typingIndent = typingIndent c.implicitsEnabled = this.implicitsEnabled c.checking = this.checking c.retyping = this.retyping diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index dff9c3d0c3..16de39b977 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1060,8 +1060,7 @@ trait Infer { * first to `strictPt' and then, if this fails, to `lenientPt'. If both * attempts fail, an error is produced. */ - def inferArgumentInstance(tree: Tree, undetparams: List[Symbol], - strictPt: Type, lenientPt: Type) { + def inferArgumentInstance(tree: Tree, undetparams: List[Symbol], strictPt: Type, lenientPt: Type) { if (inferInfo) println("infer argument instance "+tree+":"+tree.tpe+"\n"+ " undetparams = "+undetparams+"\n"+ @@ -1074,31 +1073,21 @@ trait Infer { substExpr(tree, undetparams, targs, lenientPt) } - /** Infer type arguments for `tparams` of polymorphic expression in `tree`, given prototype `pt`. - */ - def inferExprInstance(tree: Tree, tparams: List[Symbol], pt: Type, keepNothings: Boolean): List[Symbol] = { - if (inferInfo) - println("infer expr instance "+tree+":"+tree.tpe+"\n"+ - " tparams = "+tparams+"\n"+ - " pt = "+pt) - substAdjustedArgs(tree, tparams, pt, exprTypeArgs(tparams, tree.tpe, pt), keepNothings) - } - /** Infer type arguments for `tparams` of polymorphic expression in `tree`, given prototype `pt`. - * Use specified type `treeTp` instead of `tree.tp` + /** Infer type arguments `targs` for `tparams` of polymorphic expression in `tree`, given prototype `pt`. + * + * Substitute `tparams` to `targs` in `tree`, after adjustment by `adjustTypeArgs`, returning the type parameters that were not determined + * If passed, infers against specified type `treeTp` instead of `tree.tp`. */ - def inferExprInstance(tree: Tree, tparams: List[Symbol], pt: Type, treeTp: Type, keepNothings: Boolean): List[Symbol] = { + def inferExprInstance(tree: Tree, tparams: List[Symbol], pt: Type = WildcardType, treeTp0: Type = null, keepNothings: Boolean = true, checkCompat: (Type, Type) => Boolean = isCompatible): List[Symbol] = { + val treeTp = if(treeTp0 eq null) tree.tpe else treeTp0 // can't refer to tree in default for treeTp0 if (inferInfo) println("infer expr instance "+tree+":"+tree.tpe+"\n"+ " tparams = "+tparams+"\n"+ " pt = "+pt) - substAdjustedArgs(tree, tparams, pt, exprTypeArgs(tparams, treeTp, pt), keepNothings) - } - /** Substitute tparams to targs, after adjustment by adjustTypeArgs, - * return tparams that were not determined - */ - def substAdjustedArgs(tree: Tree, tparams: List[Symbol], pt: Type, targs: List[Type], keepNothings: Boolean): List[Symbol] = { + val targs = exprTypeArgs(tparams, treeTp, pt, checkCompat) + if (keepNothings || (targs eq null)) { //@M: adjustTypeArgs fails if targs==null, neg/t0226 substExpr(tree, tparams, targs, pt) List() diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 082d9afcfd..742f792e84 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -842,7 +842,8 @@ trait Typers { self: Analyzer => // as we would get ambiguity errors otherwise. Example // Looking for a manifest of Nil: This mas many potential types, // so we need to instantiate to minimal type List[Nothing]. - false) // false: retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType + keepNothings = false, // retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType + checkCompat = isWeaklyCompatible) // #3808 } val typer1 = constrTyperIf(treeInfo.isSelfOrSuperConstrCall(tree)) @@ -1037,7 +1038,7 @@ trait Typers { self: Analyzer => * @return ... */ def instantiate(tree: Tree, mode: Int, pt: Type): Tree = { - inferExprInstance(tree, context.extractUndetparams(), pt, true) + inferExprInstance(tree, context.extractUndetparams(), pt) adapt(tree, mode, pt) } @@ -2488,7 +2489,7 @@ trait Typers { self: Analyzer => } else if (needsInstantiation(tparams, formals, args)) { //println("needs inst "+fun+" "+tparams+"/"+(tparams map (_.info))) - inferExprInstance(fun, tparams, WildcardType, true) + inferExprInstance(fun, tparams) doTypedApply(tree, fun, args, mode, pt) } else { assert((mode & PATTERNmode) == 0) // this case cannot arise for patterns @@ -3031,10 +3032,9 @@ trait Typers { self: Analyzer => errorTree(tree, treeSymTypeMsg(fun)+" does not take type parameters.") } - private[this] var typingIndent: String = "" - @inline final def deindentTyping() = if (printTypings) typingIndent = typingIndent.substring(0, typingIndent.length() - 2) - @inline final def indentTyping() = if (printTypings) typingIndent += " " - @inline final def printTyping(s: => String) = if (printTypings) println(typingIndent+s) + @inline final def deindentTyping() = if (printTypings) context.typingIndent = context.typingIndent.substring(0, context.typingIndent.length() - 2) + @inline final def indentTyping() = if (printTypings) context.typingIndent += " " + @inline final def printTyping(s: => String) = if (printTypings) println(context.typingIndent+s) /** * @param tree ... diff --git a/test/files/pos/t3808.scala b/test/files/pos/t3808.scala new file mode 100644 index 0000000000..294621803a --- /dev/null +++ b/test/files/pos/t3808.scala @@ -0,0 +1,11 @@ +object Test { + def meh: Unit = { + trait TC[I] + implicit val tci = new TC[Int]{} + + def baz[J : TC] : String = "meh" + + baz + // () // commenting or uncommenting this line should not affect compilation (visibly) + } +} \ No newline at end of file -- cgit v1.2.3