diff options
Diffstat (limited to 'src/compiler/scala')
20 files changed, 148 insertions, 138 deletions
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala index 6d24b31531..bf93ad30bc 100644 --- a/src/compiler/scala/tools/nsc/ScriptRunner.scala +++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala @@ -16,16 +16,16 @@ import util.Exceptional.unwrap /** An object that runs Scala code in script files. * - * <p>For example, here is a complete Scala script on Unix:</pre> - * <pre> + * For example, here is a complete Scala script on Unix: + * {{{ * #!/bin/sh * exec scala "$0" "$@" * !# * Console.println("Hello, world!") * args.toList foreach Console.println - * </pre> - * <p>And here is a batch file example on Windows XP:</p> - * <pre> + * }}} + * And here is a batch file example on Windows XP: + * {{{ * ::#! * @echo off * call scala %0 %* @@ -33,7 +33,7 @@ import util.Exceptional.unwrap * ::!# * Console.println("Hello, world!") * args.toList foreach Console.println - * </pre> + * }}} * * @author Lex Spoon * @version 1.0, 15/05/2006 diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 92833d647b..51bb0d3c5b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -226,7 +226,7 @@ trait Scanners extends ScannersCommon { * RPAREN if region starts with '(' * RBRACKET if region starts with '[' * RBRACE if region starts with '{' - * ARROW if region starts with `case' + * ARROW if region starts with 'case' * STRINGLIT if region is a string interpolation expression starting with '${' * (the STRINGLIT appears twice in succession on the stack iff the * expression is a multiline string literal). @@ -515,7 +515,7 @@ trait Scanners extends ScannersCommon { charLitOr(getIdentRest) else if (isOperatorPart(ch) && (ch != '\\')) charLitOr(getOperatorRest) - else { + else if (!isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) { getLitChar() if (ch == '\'') { nextChar() @@ -525,6 +525,8 @@ trait Scanners extends ScannersCommon { syntaxError("unclosed character literal") } } + else + syntaxError("unclosed character literal") } fetchSingleQuote() case '.' => @@ -690,7 +692,7 @@ trait Scanners extends ScannersCommon { private def unclosedStringLit(): Unit = syntaxError("unclosed string literal") - private def getRawStringLit(): Unit = { + @tailrec private def getRawStringLit(): Unit = { if (ch == '\"') { nextRawChar() if (isTripleQuote()) { @@ -707,7 +709,7 @@ trait Scanners extends ScannersCommon { } } - @scala.annotation.tailrec private def getStringPart(multiLine: Boolean): Unit = { + @tailrec private def getStringPart(multiLine: Boolean): Unit = { def finishStringPart() = { setStrVal() token = STRINGPART diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 7096f16d75..7153c09377 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -492,8 +492,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self => * generic classes or interfaces. * * @param superName the internal of name of the super class. For interfaces, - * the super class is {@link Object}. May be <tt>null</tt>, but - * only for the {@link Object} class. + * the super class is [[Object]]. May be <tt>null</tt>, but + * only for the [[Object]] class. * * @param interfaces the internal names of the class's interfaces (see * {@link Type#getInternalName() getInternalName}). May be @@ -529,6 +529,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self => case e: java.lang.RuntimeException if e.getMessage != null && (e.getMessage contains "too large!") => reporter.error(sym.pos, s"Could not write class $jclassName because it exceeds JVM code size limits. ${e.getMessage}") + case e: java.io.IOException if e.getMessage != null && (e.getMessage contains "File name too long") => + reporter.error(sym.pos, e.getMessage + "\n" + + "This can happen on some encrypted or legacy file systems. Please see SI-3623 for more details.") + } } diff --git a/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala b/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala index 0e6ee76eb2..fb1799e092 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala @@ -170,9 +170,11 @@ abstract class ConstantOptimization extends SubComponent { // out all the possibilities case Impossible(possible2) => (possible -- possible2).nonEmpty }) - def mightNotEqual(other: Contents): Boolean = (this ne other) && (other match { - // two Possibles might not be equal if either has possible members that the other doesn't - case Possible(possible2) => (possible -- possible2).nonEmpty || (possible2 -- possible).nonEmpty + def mightNotEqual(other: Contents): Boolean = (other match { + case Possible(possible2) => + // two Possibles must equal if each is known to be of the same, single value + val mustEqual = possible.size == 1 && possible == possible2 + !mustEqual case Impossible(_) => true }) } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index f15bd3c31c..3422167d02 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -140,7 +140,7 @@ trait ScalaSettings extends AbsScalaSettings // XML parsing options object XxmlSettings extends MultiChoiceEnumeration { val coalescing = Choice("coalescing", "Convert PCData to Text and coalesce sibling nodes") - def isCoalescing = (Xxml contains coalescing) || (!isScala212 && !Xxml.isSetByUser) + def isCoalescing = Xxml contains coalescing } val Xxml = MultiChoiceSetting( name = "-Xxml", diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 06a0299d2a..99e61d2482 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -84,6 +84,9 @@ abstract class ClassfileParser { protected final def u2(): Int = in.nextChar.toInt protected final def u4(): Int = in.nextInt + protected final def s1(): Int = in.nextByte.toInt // sign-extend the byte to int + protected final def s2(): Int = (in.nextByte.toInt << 8) | u1 // sign-extend and shift the first byte, or with the unsigned second byte + private def readInnerClassFlags() = readClassFlags() private def readClassFlags() = JavaAccFlags classFlags u2 private def readMethodFlags() = JavaAccFlags methodFlags u2 diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 438a71061e..b2f5a4119d 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -326,8 +326,8 @@ abstract class ICodeReader extends ClassfileParser { case JVM.dconst_0 => code emit CONSTANT(Constant(0.0)) case JVM.dconst_1 => code emit CONSTANT(Constant(1.0)) - case JVM.bipush => code.emit(CONSTANT(Constant(u1))); size += 1 - case JVM.sipush => code.emit(CONSTANT(Constant(u2))); size += 2 + case JVM.bipush => code.emit(CONSTANT(Constant(s1))); size += 1 + case JVM.sipush => code.emit(CONSTANT(Constant(s2))); size += 2 case JVM.ldc => code.emit(CONSTANT(pool.getConstant(u1))); size += 1 case JVM.ldc_w => code.emit(CONSTANT(pool.getConstant(u2))); size += 2 case JVM.ldc2_w => code.emit(CONSTANT(pool.getConstant(u2))); size += 2 @@ -466,7 +466,7 @@ abstract class ICodeReader extends ClassfileParser { size += 2 val local = code.getLocal(u1, INT) code.emit(LOAD_LOCAL(local)) - code.emit(CONSTANT(Constant(u1))) + code.emit(CONSTANT(Constant(s1))) code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))) code.emit(STORE_LOCAL(local)) diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 7c66bda46b..6ecdd2b195 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -396,9 +396,9 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { } if (stat1 eq stat) { - assert(ctorParams(genericClazz).length == constrInfo.constrParams.length) + assert(ctorParams(genericClazz).length == primaryConstrParams.length) // this is just to make private fields public - (new specializeTypes.ImplementationAdapter(ctorParams(genericClazz), constrInfo.constrParams, null, true))(stat1) + (new specializeTypes.ImplementationAdapter(ctorParams(genericClazz), primaryConstrParams, null, true))(stat1) val stat2 = rewriteArrayUpdate(stat1) // statements coming from the original class need retyping in the current context @@ -435,16 +435,16 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { // postfix = postfix.tail // } - if (shouldGuard && usesSpecializedField && stats.nonEmpty) { + if (guardSpecializedFieldInit && intoConstructor.usesSpecializedField && stats.nonEmpty) { // save them for duplication in the specialized subclass guardedCtorStats(clazz) = stats - ctorParams(clazz) = constrInfo.constrParams + ctorParams(clazz) = primaryConstrParams val tree = If( Apply( CODE.NOT ( - Apply(gen.mkAttributedRef(specializedFlag), List())), + Apply(gen.mkAttributedRef(hasSpecializedFieldsSym), List())), List()), Block(stats, Literal(Constant(()))), EmptyTree) @@ -476,27 +476,17 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { val stats = impl.body // the transformed template body val localTyper = typer.atOwner(impl, clazz) - val specializedFlag: Symbol = clazz.info.decl(nme.SPECIALIZED_INSTANCE) - val shouldGuard = (specializedFlag != NoSymbol) && !clazz.hasFlag(SPECIALIZED) - - val isDelayedInitSubclass = (clazz isSubClass DelayedInitClass) - - case class ConstrInfo( - constr: DefDef, // The primary constructor - constrParams: List[Symbol], // ... and its parameters - constrBody: Block // ... and its body - ) - // decompose primary constructor into the three entities above. - val constrInfo: ConstrInfo = { - val ddef = (stats find (_.symbol.isPrimaryConstructor)) - ddef match { - case Some(ddef @ DefDef(_, _, _, List(vparams), _, rhs @ Block(_, _))) => - ConstrInfo(ddef, vparams map (_.symbol), rhs) - case x => - abort("no constructor in template: impl = " + impl) - } - } - import constrInfo._ + val hasSpecializedFieldsSym = clazz.info.decl(nme.SPECIALIZED_INSTANCE) + // The constructor of a non-specialized class that has specialized subclasses + // should use `q"${hasSpecializedFieldsSym}()"` to guard the initialization of specialized fields. + val guardSpecializedFieldInit = (hasSpecializedFieldsSym != NoSymbol) && !clazz.hasFlag(SPECIALIZED) + + val isDelayedInitSubclass = clazz isSubClass DelayedInitClass + + // find and dissect primary constructor + val (primaryConstr, primaryConstrParams, primaryConstrBody) = stats collectFirst { + case dd@DefDef(_, _, _, vps :: Nil, _, rhs: Block) if dd.symbol.isPrimaryConstructor => (dd, vps map (_.symbol), rhs) + } getOrElse abort("no constructor in template: impl = " + impl) // The parameter accessor fields which are members of the class val paramAccessors = clazz.constrParamAccessors @@ -509,27 +499,26 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { def parameterNamed(name: Name): Symbol = { def matchesName(param: Symbol) = param.name == name || param.name.startsWith(name + nme.NAME_JOIN_STRING) - (constrParams filter matchesName) match { - case Nil => abort(name + " not in " + constrParams) + primaryConstrParams filter matchesName match { + case Nil => abort(name + " not in " + primaryConstrParams) case p :: _ => p } } - /* - * `usesSpecializedField` makes a difference in deciding whether constructor-statements - * should be guarded in a `shouldGuard` class, ie in a class that's the generic super-class of - * one or more specialized sub-classes. - * - * Given that `usesSpecializedField` isn't read for any other purpose than the one described above, - * we skip setting `usesSpecializedField` in case the current class isn't `shouldGuard` to start with. - * That way, trips to a map in `specializeTypes` are saved. - */ - var usesSpecializedField: Boolean = false - // A transformer for expressions that go into the constructor - private class IntoCtorTransformer extends Transformer { - - private def isParamRef(sym: Symbol) = (sym.isParamAccessor && sym.owner == clazz) + object intoConstructor extends Transformer { + /* + * `usesSpecializedField` makes a difference in deciding whether constructor-statements + * should be guarded in a `guardSpecializedFieldInit` class, ie in a class that's the generic super-class of + * one or more specialized sub-classes. + * + * Given that `usesSpecializedField` isn't read for any other purpose than the one described above, + * we skip setting `usesSpecializedField` in case the current class isn't `guardSpecializedFieldInit` to start with. + * That way, trips to a map in `specializeTypes` are saved. + */ + var usesSpecializedField: Boolean = false + + private def isParamRef(sym: Symbol) = sym.isParamAccessor && sym.owner == clazz // Terminology: a stationary location is never written after being read. private def isStationaryParamRef(sym: Symbol) = ( @@ -548,10 +537,9 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { * (b.2) the constructor in the specialized (sub-)class. * (c) isn't part of a DelayedInit subclass. */ - private def canBeSupplanted(sym: Symbol) = (!isDelayedInitSubclass && isStationaryParamRef(sym) && !possiblySpecialized(sym)) + private def canBeSupplanted(sym: Symbol) = !isDelayedInitSubclass && isStationaryParamRef(sym) && !possiblySpecialized(sym) override def transform(tree: Tree): Tree = tree match { - case Apply(Select(This(_), _), List()) => // references to parameter accessor methods of own class become references to parameters // outer accessors become references to $outer parameter @@ -566,7 +554,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { // references to parameter accessor field of own class become references to parameters gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos - case Select(_, _) if shouldGuard => // reasoning behind this guard in the docu of `usesSpecializedField` + case Select(_, _) if guardSpecializedFieldInit => // reasoning behind this guard in the docu of `usesSpecializedField` if (possiblySpecialized(tree.symbol)) { usesSpecializedField = true } @@ -576,18 +564,10 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { super.transform(tree) } - } - - private val intoConstructorTransformer = new IntoCtorTransformer - - // Move tree into constructor, take care of changing owner from `oldowner` to constructor symbol - def intoConstructor(oldowner: Symbol, tree: Tree) = - intoConstructorTransformer transform tree.changeOwner(oldowner -> constr.symbol) - - // Should tree be moved in front of super constructor call? - def canBeMoved(tree: Tree) = tree match { - case ValDef(mods, _, _, _) => (mods hasFlag PRESUPER | PARAMACCESSOR) - case _ => false + // Move tree into constructor, take care of changing owner from `oldowner` to constructor symbol + def apply(oldowner: Symbol, tree: Tree) = + if (tree eq EmptyTree) tree + else transform(tree.changeOwner(oldowner -> primaryConstr.symbol)) } // Create an assignment to class field `to` with rhs `from` @@ -629,10 +609,10 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { val classInitStatBuf = new ListBuffer[Tree] // generate code to copy pre-initialized fields - for (stat <- constrBody.stats) { + for (stat <- primaryConstrBody.stats) { constrStatBuf += stat stat match { - case ValDef(mods, name, _, _) if (mods hasFlag PRESUPER) => + case ValDef(mods, name, _, _) if mods hasFlag PRESUPER => // stat is the constructor-local definition of the field value val fields = presupers filter (_.getterName == name) assert(fields.length == 1) @@ -643,45 +623,48 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { } } - // Triage all template definitions to go into defBuf/auxConstructorBuf, constrStatBuf, or constrPrefixBuf. - for (stat <- stats) stat match { - case DefDef(_,_,_,_,_,rhs) => - // methods with constant result type get literals as their body - // all methods except the primary constructor go into template - stat.symbol.tpe match { - case MethodType(List(), tp @ ConstantType(c)) => - defBuf += deriveDefDef(stat)(Literal(c) setPos _.pos setType tp) - case _ => - if (stat.symbol.isPrimaryConstructor) () - else if (stat.symbol.isConstructor) auxConstructorBuf += stat - else defBuf += stat - } - case ValDef(mods, _, _, rhs) if !mods.hasStaticFlag => + + for (stat <- stats) { + val statSym = stat.symbol + + stat match { + // recurse on class definition, store in defBuf + case _: ClassDef => defBuf += new ConstructorTransformer(unit).transform(stat) + + // methods (except primary constructor) go into template + // (non-primary ctors --> auxConstructorBuf / regular defs --> defBuf) + case _: DefDef if statSym.isPrimaryConstructor => () + case _: DefDef if statSym.isConstructor => auxConstructorBuf += stat + case _: DefDef => defBuf += stat + // val defs with constant right-hand sides are eliminated. - // for all other val defs, an empty valdef goes into the template and - // the initializer goes as an assignment into the constructor - // if the val def is an early initialized or a parameter accessor, it goes - // before the superclass constructor call, otherwise it goes after. - // Lazy vals don't get the assignment in the constructor. - if (!stat.symbol.tpe.isInstanceOf[ConstantType]) { - if (rhs != EmptyTree && !stat.symbol.isLazy) { - val rhs1 = intoConstructor(stat.symbol, rhs) - (if (canBeMoved(stat)) constrPrefixBuf else constrStatBuf) += mkAssign( - stat.symbol, rhs1) + case _: ValDef if statSym.info.isInstanceOf[ConstantType] => () + + // For all other val defs, an empty valdef goes into the template. + // Additionally, non-lazy vals are initialized by an assignment in: + // - the class initializer (static), + // - the constructor, before the super call (early initialized or a parameter accessor), + // - the constructor, after the super call (regular val). + case ValDef(mods, _, _, rhs) => + val initializingRhs = + if (statSym.isLazy) EmptyTree + else if (!mods.hasStaticFlag) intoConstructor(statSym, rhs) + else rhs + + if (initializingRhs ne EmptyTree) { + val initPhase = + if (mods hasFlag STATIC) classInitStatBuf + else if (mods hasFlag PRESUPER | PARAMACCESSOR) constrPrefixBuf + else constrStatBuf + + initPhase += mkAssign(statSym, initializingRhs) } + defBuf += deriveValDef(stat)(_ => EmptyTree) - } - case ValDef(_, _, _, rhs) => - // Add static initializer statements to classInitStatBuf and remove the rhs from the val def. - classInitStatBuf += mkAssign(stat.symbol, rhs) - defBuf += deriveValDef(stat)(_ => EmptyTree) - - case ClassDef(_, _, _, _) => - // classes are treated recursively, and left in the template - defBuf += new ConstructorTransformer(unit).transform(stat) - case _ => + // all other statements go into the constructor - constrStatBuf += intoConstructor(impl.symbol, stat) + case _ => constrStatBuf += intoConstructor(impl.symbol, stat) + } } populateOmittables() @@ -716,12 +699,12 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { rewriteDelayedInit() // Assemble final constructor - defBuf += deriveDefDef(constr)(_ => + defBuf += deriveDefDef(primaryConstr)(_ => treeCopy.Block( - constrBody, + primaryConstrBody, paramInits ::: constrPrefixBuf.toList ::: uptoSuperStats ::: guardSpecializedInitializer(remainingConstrStats), - constrBody.expr)) + primaryConstrBody.expr)) // Followed by any auxiliary constructors defBuf ++= auxConstructorBuf @@ -732,6 +715,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { // Eliminate all field definitions that can be dropped from template val templateWithoutOmittables: Template = deriveTemplate(impl)(_ => defBuf.toList filter (stat => mustBeKept(stat.symbol))) + // Add the static initializers val transformed: Template = addStaticInits(templateWithoutOmittables, classInitStatBuf, localTyper) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 25d45cc819..a079a76ce7 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1122,7 +1122,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { if (scope exists (_.isLazy)) { val map = mutable.Map[Symbol, Set[Symbol]]() withDefaultValue Set() // check what fields can be nulled for - for ((field, users) <- singleUseFields(templ); lazyFld <- users) + for ((field, users) <- singleUseFields(templ); lazyFld <- users if !lazyFld.accessed.hasAnnotation(TransientAttr)) map(lazyFld) += field map.toMap diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 72e2174bf8..79a77d7a0c 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -582,6 +582,7 @@ abstract class UnCurry extends InfoTransform } case dd @ DefDef(_, _, _, vparamss0, _, rhs0) => + val ddSym = dd.symbol val (newParamss, newRhs): (List[List[ValDef]], Tree) = if (dependentParamTypeErasure isDependent dd) dependentParamTypeErasure erase dd @@ -593,11 +594,22 @@ abstract class UnCurry extends InfoTransform (vparamss1, rhs0) } + // A no-arg method with ConstantType result type can safely be reduced to the corresponding Literal + // (only pure methods are typed as ConstantType). We could also do this for methods with arguments, + // after ensuring the arguments are not referenced. + val literalRhsIfConst = + if (newParamss.head.isEmpty) { // We know newParamss.length == 1 from above + ddSym.info.resultType match { + case tp@ConstantType(value) => Literal(value) setType tp setPos newRhs.pos // inlining of gen.mkAttributedQualifier(tp) + case _ => newRhs + } + } else newRhs + val flatdd = copyDefDef(dd)( vparamss = newParamss, - rhs = nonLocalReturnKeys get dd.symbol match { - case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(newRhs, k, dd.symbol)) - case None => newRhs + rhs = nonLocalReturnKeys get ddSym match { + case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(literalRhsIfConst, k, ddSym)) + case None => literalRhsIfConst } ) addJavaVarargsForwarders(dd, flatdd) diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala index 8bcd5e6f12..2b6a4c763a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala @@ -44,7 +44,7 @@ import scala.language.postfixOps * which is essentially the intersection of X and |P|, where |P| is * the erasure of P. If XR <: P, then no warning is emitted. * - * We evaluate "X with conform to P" by checking `X <: P_wild, where + * We evaluate "X with conform to P" by checking `X <: P_wild`, where * P_wild is the result of substituting wildcard types in place of * pattern type variables. This is intentionally stricter than * (X matchesPattern P), see SI-8597 for motivating test cases. diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 196b137a3e..73e454bf47 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -110,10 +110,10 @@ trait Implicits { * Ignore their constr field! The list of type constraints returned along with each tree specifies the constraints that * must be met by the corresponding type parameter in `tpars` (for the returned implicit view to be valid). * - * @arg tp from-type for the implicit conversion - * @arg context search implicits here - * @arg tpars symbols that should be considered free type variables - * (implicit search should not try to solve them, just track their constraints) + * @param tp from-type for the implicit conversion + * @param context search implicits here + * @param tpars symbols that should be considered free type variables + * (implicit search should not try to solve them, just track their constraints) */ def allViewsFrom(tp: Type, context: Context, tpars: List[Symbol]): List[(SearchResult, List[TypeConstraint])] = { // my untouchable typevars are better than yours (they can't be constrained by them) @@ -324,8 +324,10 @@ trait Implicits { */ class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context, pos0: Position = NoPosition) extends Typer(context0) with ImplicitsContextErrors { val searchId = implicitSearchId() - private def typingLog(what: String, msg: => String) = - typingStack.printTyping(tree, f"[search #$searchId] $what $msg") + private def typingLog(what: String, msg: => String) = { + if (printingOk(tree)) + typingStack.printTyping(f"[search #$searchId] $what $msg") + } import infer._ if (Statistics.canEnable) Statistics.incCounter(implicitSearchCount) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index bf705e89ad..a5fdbb5148 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1375,7 +1375,7 @@ trait Infer extends Checkable { * Otherwise, if there is no best alternative, error. * * @param argtpes0 contains the argument types. If an argument is named, as - * "a = 3", the corresponding type is `NamedType("a", Int)'. If the name + * "a = 3", the corresponding type is `NamedType("a", Int)`. If the name * of some NamedType does not exist in an alternative's parameter names, * the type is replaces by `Unit`, i.e. the argument is treated as an * assignment expression. diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 10aefae20b..99dd81c7e2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -85,9 +85,9 @@ trait Macros extends MacroRuntimes with Traces with Helpers { */ case class MacroImplBinding( // Is this macro impl a bundle (a trait extending *box.Macro) or a vanilla def? - val isBundle: Boolean, + isBundle: Boolean, // Is this macro impl blackbox (i.e. having blackbox.Context in its signature)? - val isBlackbox: Boolean, + isBlackbox: Boolean, // Java class name of the class that contains the macro implementation // is used to load the corresponding object with Java reflection className: String, diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 0198529ef7..90ac1f466d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1511,7 +1511,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans sym.isSourceMethod && sym.isCase && sym.name == nme.apply && - isClassTypeAccessible(tree) + isClassTypeAccessible(tree) && + !tree.tpe.resultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol) if (doTransform) { tree foreach { diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index ea44b9dc39..92b0719ba3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -132,7 +132,7 @@ trait StdAttachments { /** Marks the tree as a macro impl reference, which is a naked reference to a method. * * This is necessary for typechecking macro impl references (see `DefaultMacroCompiler.defaultResolveMacroImpl`), - * because otherwise typing a naked reference will result in the "follow this method with `_' if you want to + * because otherwise typing a naked reference will result in the "follow this method with `_` if you want to * treat it as a partially applied function" errors. * * This mark suppresses adapt except for when the annottee is a macro application. diff --git a/src/compiler/scala/tools/nsc/typechecker/Tags.scala b/src/compiler/scala/tools/nsc/typechecker/Tags.scala index 57dc74d2a0..56127f4026 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Tags.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Tags.scala @@ -36,7 +36,7 @@ trait Tags { * @param allowMaterialization If true (default) then the resolver is allowed to launch materialization macros when there's no class tag in scope. * If false then materialization macros are prohibited from running. * - * @returns Tree that represents an `scala.reflect.ClassTag` for `tp` if everything is okay. + * @return Tree that represents an `scala.reflect.ClassTag` for `tp` if everything is okay. * EmptyTree if the result contains unresolved (i.e. not spliced) type parameters and abstract type members. * EmptyTree if `allowMaterialization` is false, and there is no class tag in scope. */ @@ -57,7 +57,7 @@ trait Tags { * @param allowMaterialization If true (default) then the resolver is allowed to launch materialization macros when there's no type tag in scope. * If false then materialization macros are prohibited from running. * - * @returns Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay. + * @return Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay. * EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members. * EmptyTree if `allowMaterialization` is false, and there is no array tag in scope. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index cc15a2485f..8228adc20e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2714,7 +2714,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper * * If 'T' is not fully defined, it is inferred by type checking * `apply$body` without a result type before type checking the block. - * The method's inferred result type is used instead of T`. [See test/files/pos/sammy_poly.scala] + * The method's inferred result type is used instead of `T`. [See test/files/pos/sammy_poly.scala] * * The `apply` method is identified by the argument `sam`; `S` corresponds to the argument `samClassTp`, * and `resPt` is derived from `samClassTp` -- it may be fully defined, or not... diff --git a/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala b/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala index 550fd4e68d..37fbb73b85 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala @@ -159,7 +159,7 @@ trait TypersTracking { // Some trees which are typed with mind-numbing frequency and // which add nothing by being printed. Did () type to Unit? Let's // gamble on yes. - private def printingOk(t: Tree) = printTypings && (settings.debug.value || !noPrint(t)) + def printingOk(t: Tree) = printTypings && (settings.debug.value || !noPrint(t)) def noPrintTyping(t: Tree) = (t.tpe ne null) || !printingOk(t) def noPrintAdapt(tree1: Tree, tree2: Tree) = !printingOk(tree1) || ( (tree1.tpe == tree2.tpe) diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index 4ff7067a21..501546b8f6 100755 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -37,7 +37,7 @@ object DocStrings { /** Returns index of string `str` after `start` skipping longest * sequence of space and tab characters, possibly also containing * a single `*` character or the `/``**` sequence. - * @pre start == str.length || str(start) == `\n' + * @pre start == str.length || str(start) == `\n` */ def skipLineLead(str: String, start: Int): Int = if (start == str.length) start @@ -49,7 +49,7 @@ object DocStrings { else idx } - /** Skips to next occurrence of `\n' or to the position after the `/``**` sequence following index `start`. + /** Skips to next occurrence of `\n` or to the position after the `/``**` sequence following index `start`. */ def skipToEol(str: String, start: Int): Int = if (start + 2 < str.length && (str charAt start) == '/' && (str charAt (start + 1)) == '*' && (str charAt (start + 2)) == '*') start + 3 |