diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2015-09-09 09:31:22 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2015-09-09 09:31:22 -0700 |
commit | 76269ca7a63848aee1f141da75be8ca436bf9e6c (patch) | |
tree | 3be0d1b978019ca825262a48bc4e18a34bdbf3f4 /src | |
parent | 17099706034d3ae2c63743488f076ed1dab286b7 (diff) | |
parent | ad17b552b8f7c3a435ad8de71cd7268f905a1b8d (diff) | |
download | scala-76269ca7a63848aee1f141da75be8ca436bf9e6c.tar.gz scala-76269ca7a63848aee1f141da75be8ca436bf9e6c.tar.bz2 scala-76269ca7a63848aee1f141da75be8ca436bf9e6c.zip |
Merge pull request #4732 from SethTisue/merge-2.11.x-sep-8
Merge 2.11.x into 2.12.x [ci: last-only]
Diffstat (limited to 'src')
45 files changed, 193 insertions, 66 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index bf53c47e9a..332acf4a26 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -261,7 +261,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { * Create a method based on a Function * * Used both to under `-Ydelambdafy:method` create a lifted function and - * under `-Ydelamdafy:inline` to create the apply method on the anonymous + * under `-Ydelambdafy:inline` to create the apply method on the anonymous * class. * * It creates a method definition with value params cloned from the diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index b76fb3d823..f9e6a12241 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2043,11 +2043,11 @@ self => /** Drop `private` modifier when followed by a qualifier. * Contract `abstract` and `override` to ABSOVERRIDE */ - private def normalizeModifers(mods: Modifiers): Modifiers = + private def normalizeModifiers(mods: Modifiers): Modifiers = if (mods.isPrivate && mods.hasAccessBoundary) - normalizeModifers(mods &~ Flags.PRIVATE) + normalizeModifiers(mods &~ Flags.PRIVATE) else if (mods hasAllFlags (Flags.ABSTRACT | Flags.OVERRIDE)) - normalizeModifers(mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE) + normalizeModifiers(mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE) else mods @@ -2092,7 +2092,7 @@ self => * AccessModifier ::= (private | protected) [AccessQualifier] * }}} */ - def accessModifierOpt(): Modifiers = normalizeModifers { + def accessModifierOpt(): Modifiers = normalizeModifiers { in.token match { case m @ (PRIVATE | PROTECTED) => in.nextToken() ; accessQualifierOpt(Modifiers(flagTokens(m))) case _ => NoMods @@ -2106,7 +2106,7 @@ self => * | override * }}} */ - def modifiers(): Modifiers = normalizeModifers { + def modifiers(): Modifiers = normalizeModifiers { def loop(mods: Modifiers): Modifiers = in.token match { case PRIVATE | PROTECTED => loop(accessQualifierOpt(addMod(mods, flagTokens(in.token), tokenRange(in)))) diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 01eff71057..a927097b62 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -2016,7 +2016,7 @@ abstract class GenICode extends SubComponent { * * This could result in unreachable code which has to be cleaned up later, e.g. if the try and all the exception * handlers always end in RETURN then there will be no "normal" flow out of the try/catch/finally. - * Later reachability analysis will remove unreacahble code. + * Later reachability analysis will remove unreachable code. */ def Try(body: Context => Context, handlers: List[(Symbol, TypeKind, Context => Context)], @@ -2060,7 +2060,7 @@ abstract class GenICode extends SubComponent { if (settings.YdisableUnreachablePrevention || !outerCtx.bb.ignore) { if (finalizer != EmptyTree) { val exh = outerCtx.newExceptionHandler(NoSymbol, finalizer.pos) // finalizer covers exception handlers - this.addActiveHandler(exh) // .. and body aswell + this.addActiveHandler(exh) // .. and body as well val exhStartCtx = finalizerCtx.enterExceptionHandler(exh) exhStartCtx.bb killIf outerCtx.bb.ignore val exception = exhStartCtx.makeLocal(finalizer.pos, ThrowableTpe, "exc") diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala index 843648282b..0f17b5d694 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala @@ -20,7 +20,7 @@ abstract class ICodeCheckers { * </p> * <ul> * <li> - * for primitive operations: the type and numer of operands match + * for primitive operations: the type and number of operands match * the type of the operation * </li> * <li> diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 22ac8f84d4..e5eb0b79d5 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -92,8 +92,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { def genThrow(expr: Tree): BType = { val thrownKind = tpeTK(expr) - // `throw null` is valid although scala.Null (as defined in src/libray-aux) isn't a subtype of Throwable. - // Similarly for scala.Nothing (again, as defined in src/libray-aux). + // `throw null` is valid although scala.Null (as defined in src/library-aux) isn't a subtype of Throwable. + // Similarly for scala.Nothing (again, as defined in src/library-aux). assert(thrownKind.isNullType || thrownKind.isNothingType || thrownKind.asClassBType.isSubtypeOf(ThrowableReference).get) genLoad(expr, thrownKind) lineNumber(expr) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala index 8720da84e8..0c26e01322 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala @@ -1126,7 +1126,7 @@ object BTypes { * The map is indexed by the string s"$name$descriptor" (to * disambiguate overloads). * - * @param warning Contains an warning message if an error occured when building this + * @param warning Contains an warning message if an error occurred when building this * InlineInfo, for example if some classfile could not be found on * the classpath. This warning can be reported later by the inliner. */ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 7153c09377..7883ce7ffa 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -2697,7 +2697,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self => case CMPG => (kind: @unchecked) match { case FLOAT => emit(Opcodes.FCMPG) - case DOUBLE => emit(Opcodes.DCMPL) // TODO bug? why not DCMPG? http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc3.html + case DOUBLE => emit(Opcodes.DCMPL) // TODO bug? why not DCMPG? http://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc3.html } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala index 31710dcbee..31b62f747e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala @@ -12,7 +12,7 @@ import scala.tools.nsc.backend.jvm.opt.BytecodeUtils import BytecodeUtils._ /** - * Some notes on the ASM ananlyzer framework. + * Some notes on the ASM analyzer framework. * * Value * - Abstract, needs to be implemented for each analysis. diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala index 92b9b34006..b0dc6ead1b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala @@ -359,7 +359,7 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) { } /** - * Stores a local varaible index the opcode offset required for operating on that variable. + * Stores a local variable index the opcode offset required for operating on that variable. * * The xLOAD / xSTORE opcodes are in the following sequence: I, L, F, D, A, so the offset for * a local variable holding a reference (`A`) is 4. See also method `getOpcode` in [[scala.tools.asm.Type]]. diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index 8477f5461a..6b2786c1a3 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -366,7 +366,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { clonedInstructions.insert(argStores) - // label for the exit of the inlined functions. xRETURNs are rplaced by GOTOs to this label. + // label for the exit of the inlined functions. xRETURNs are replaced by GOTOs to this label. val postCallLabel = newLabelNode clonedInstructions.add(postCallLabel) @@ -705,9 +705,9 @@ class Inliner[BT <: BTypes](val btypes: BT) { // - a method name+type // // execution [3] - // - resolve the CSP, yielding the boostrap method handle, the static args and the name+type + // - resolve the CSP, yielding the bootstrap method handle, the static args and the name+type // - resolution entails accessibility checking [4] - // - execute the `invoke` method of the boostrap method handle (which is signature polymorphic, check its javadoc) + // - execute the `invoke` method of the bootstrap method handle (which is signature polymorphic, check its javadoc) // - the descriptor for the call is made up from the actual arguments on the stack: // - the first parameters are "MethodHandles.Lookup, String, MethodType", then the types of the constant arguments, // - the return type is CallSite diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala index 2967f67e9c..efb026cdff 100644 --- a/src/compiler/scala/tools/nsc/io/Jar.scala +++ b/src/compiler/scala/tools/nsc/io/Jar.scala @@ -154,7 +154,7 @@ object Jar { def update(key: Attributes.Name, value: String) = attrs.put(key, value) } - // See http://download.java.net/jdk7/docs/api/java/nio/file/Path.html + // See http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html // for some ideas. private val ZipMagicNumber = List[Byte](80, 75, 3, 4) private def magicNumberIsZip(f: Path) = f.isFile && (f.toFile.bytes().take(4).toList == ZipMagicNumber) diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 79776485de..82e7c76409 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -111,7 +111,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => impl setInfo new LazyImplClassType(iface) } - /** Return the implementation class of a trait; create a new one of one does not yet exist */ + /** Return the implementation class of a trait; create a new one if one does not yet exist */ def implClass(iface: Symbol): Symbol = { iface.info diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 6ecdd2b195..48eb878e2a 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -137,7 +137,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { * and thus may only be accessed from value or method definitions owned by the current class * (ie there's no point drilling down into nested classes). * - * (d) regarding candidates in (b), they are accesible from all places listed in (c) and in addition + * (d) regarding candidates in (b), they are accessible from all places listed in (c) and in addition * from nested classes (nested at any number of levels). * * In all cases, we're done with traversing as soon as all candidates have been ruled out. diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index ddf003bb98..33fd5d0461 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -281,7 +281,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val parents = addSerializable(abstractFunctionErasedType) val funOwner = originalFunction.symbol.owner - // TODO harmonize the naming of delamdafy anon-fun classes with those spun up by Uncurry + // TODO harmonize the naming of delambdafy anon-fun classes with those spun up by Uncurry // - make `anonClass.isAnonymousClass` true. // - use `newAnonymousClassSymbol` or push the required variations into a similar factory method // - reinstate the assertion in `Erasure.resolveAnonymousBridgeClash` diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 79a77d7a0c..57639a94c7 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -703,9 +703,46 @@ abstract class UnCurry extends InfoTransform // declared type and assign this to a synthetic val. Later, we'll patch // the method body to refer to this, rather than the parameter. val tempVal: ValDef = { + // SI-9442: using the "uncurry-erased" type (the one after the uncurry phase) can lead to incorrect + // tree transformations. For example, compiling: + // ``` + // def foo(c: Ctx)(l: c.Tree): Unit = { + // val l2: c.Tree = l + // } + // ``` + // Results in the following AST: + // ``` + // def foo(c: Ctx, l: Ctx#Tree): Unit = { + // val l$1: Ctx#Tree = l.asInstanceOf[Ctx#Tree] + // val l2: c.Tree = l$1 // no, not really, it's not. + // } + // ``` + // Of course, this is incorrect, since `l$1` has type `Ctx#Tree`, which is not a subtype of `c.Tree`. + // + // So what we need to do is to use the pre-uncurry type when creating `l$1`, which is `c.Tree` and is + // correct. Now, there are two additional problems: + // 1. when varargs and byname params are involved, the uncurry transformation desugares these special + // cases to actual typerefs, eg: + // ``` + // T* ~> Seq[T] (Scala-defined varargs) + // T* ~> Array[T] (Java-defined varargs) + // =>T ~> Function0[T] (by name params) + // ``` + // we use the DesugaredParameterType object (defined in scala.reflect.internal.transform.UnCurry) + // to redo this desugaring manually here + // 2. the type needs to be normalized, since `gen.mkCast` checks this (no HK here, just aliases have + // to be expanded before handing the type to `gen.mkAttributedCast`, which calls `gen.mkCast`) + val info0 = + enteringUncurry(p.symbol.info) match { + case DesugaredParameterType(desugaredTpe) => + desugaredTpe + case tpe => + tpe + } + val info = info0.normalize val tempValName = unit freshTermName (p.name + "$") - val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(p.symbol.info) - atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), p.symbol.info))) + val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(info) + atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), info))) } Packed(newParam, tempVal) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 99dd81c7e2..3ed128cbc5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -55,6 +55,13 @@ trait Macros extends MacroRuntimes with Traces with Helpers { def globalSettings = global.settings + /** Obtains a `ClassLoader` instance used for macro expansion. + * + * By default a new `ScalaClassLoader` is created using the classpath + * from global and the classloader of self as parent. + * + * Mirrors with runtime definitions (e.g. Repl) need to adjust this method. + */ protected def findMacroClassLoader(): ClassLoader = { val classpath = global.classPath.asURLs macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath)) @@ -658,7 +665,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers { // // Situation #2 requires measures to be taken. If we're in it, then noone's going to help us infer // the undetermined type params. Therefore we need to do something ourselves or otherwise this - // expandee will forever remaing not expanded (see SI-5692). A traditional way out of this conundrum + // expandee will forever remain not expanded (see SI-5692). A traditional way out of this conundrum // is to call `instantiate` and let the inferencer try to find the way out. It works for simple cases, // but sometimes, if the inferencer lacks information, it will be forced to approximate. // diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index a7d48ceb89..e8db8309f1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -262,7 +262,14 @@ abstract class TreeCheckers extends Analyzer { checkedTyped(tree, mode, pt) ) private def checkedTyped(tree: Tree, mode: Mode, pt: Type): Tree = { - val typed = wrap(tree)(super.typed(tree, mode, pt)) + val typed = wrap(tree)(super.typed(tree.clearType(), mode, pt)) + + // Vlad: super.typed returns null for package defs, why is that? + if (typed eq null) + return tree + + if (typed.tpe ne null) + assert(!typed.tpe.isErroneous, "Tree has erroneous type: " + typed) if (tree ne typed) treesDiffer(tree, typed) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 8228adc20e..f26baf7d93 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3294,7 +3294,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.3 // // One can think of these methods as being infinitely overloaded. We create - // a ficticious new cloned method symbol for each call site that takes on a signature + // a fictitious new cloned method symbol for each call site that takes on a signature // governed by a) the argument types and b) the expected type val args1 = typedArgs(args, forArgMode(fun, mode)) val pts = args1.map(_.tpe.deconst) @@ -4095,7 +4095,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def resultingTypeTree(tpe: Type) = { // we need symbol-ful originals for reification - // hence we go the extra mile to hand-craft tis guy + // hence we go the extra mile to hand-craft this guy val original = arg1 match { case tt @ TypeTree() if tt.original != null => Annotated(ann, tt.original) // this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)" @@ -4247,7 +4247,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // in the special (though common) case where the types are equal, it pays to pack before comparing // especially virtpatmat needs more aggressive unification of skolemized types // this breaks src/library/scala/collection/immutable/TrieIterator.scala - // annotated types need to be lubbed regardless (at least, continations break if you by pass them like this) + // annotated types need to be lubbed regardless (at least, continuations break if you bypass them like this) def samePackedTypes = ( !isPastTyper && thenp1.tpe.annotations.isEmpty diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 8d4d07759f..2811520b67 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -22,7 +22,7 @@ import Jar.isJarOrZip /** <p> * This module provides star expansion of '-classpath' option arguments, behaves the same as - * java, see [http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html] + * java, see [[http://docs.oracle.com/javase/6/docs/technotes/tools/windows/classpath.html]] * </p> * * @author Stepan Koltsov diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala index ac63232967..e30d1ed7cd 100644 --- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala +++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala @@ -1,9 +1,11 @@ package scala.tools package reflect +import scala.reflect.internal.util.ScalaClassLoader import scala.tools.nsc.Global import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.Settings +import scala.tools.nsc.typechecker.Analyzer /** A version of Global that uses reflection to get class * infos, instead of reading class or source files. @@ -11,6 +13,20 @@ import scala.tools.nsc.Settings class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val rootClassLoader: ClassLoader) extends Global(currentSettings, reporter) with scala.tools.reflect.ReflectSetup with scala.reflect.runtime.SymbolTable { + override lazy val analyzer = new { + val global: ReflectGlobal.this.type = ReflectGlobal.this + } with Analyzer { + /** Obtains the classLoader used for runtime macro expansion. + * + * Macro expansion can use everything available in [[global.classPath]] or [[rootClassLoader]]. + * The [[rootClassLoader]] is used to obtain runtime defined macros. + */ + override protected def findMacroClassLoader(): ClassLoader = { + val classpath = global.classPath.asURLs + ScalaClassLoader.fromURLs(classpath, rootClassLoader) + } + } + override def transformedType(sym: Symbol) = postErasure.transformInfo(sym, erasure.transformInfo(sym, diff --git a/src/library-aux/scala/Any.scala b/src/library-aux/scala/Any.scala index 1be186d114..8caf0c5c0e 100644 --- a/src/library-aux/scala/Any.scala +++ b/src/library-aux/scala/Any.scala @@ -27,7 +27,7 @@ package scala * w.print() * }}} * - * See the [[http://docs.scala-lang.org/sips/pending/value-classes.html value classes guide]] for more + * See the [[http://docs.scala-lang.org/sips/completed/value-classes.html value classes guide]] for more * details on the interplay of universal traits and value classes. */ abstract class Any { diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala index ff62948413..fb3d213e19 100644 --- a/src/library/scala/AnyVal.scala +++ b/src/library/scala/AnyVal.scala @@ -49,7 +49,7 @@ package scala * It's important to note that user-defined value classes are limited, and in some circumstances, * still must allocate a value class instance at runtime. These limitations and circumstances are * explained in greater detail in the [[http://docs.scala-lang.org/overviews/core/value-classes.html Value Classes Guide]] - * as well as in [[http://docs.scala-lang.org/sips/pending/value-classes.html SIP-15: Value Classes]], + * as well as in [[http://docs.scala-lang.org/sips/completed/value-classes.html SIP-15: Value Classes]], * the Scala Improvement Proposal. */ abstract class AnyVal extends Any { diff --git a/src/library/scala/Equals.scala b/src/library/scala/Equals.scala index f2f9ead44c..e06557ccdd 100644 --- a/src/library/scala/Equals.scala +++ b/src/library/scala/Equals.scala @@ -13,8 +13,9 @@ package scala */ trait Equals extends Any { /** A method that should be called from every well-designed equals method - * that is open to be overridden in a subclass. See Programming in Scala, - * Chapter 28 for discussion and design. + * that is open to be overridden in a subclass. See + * [[http://www.artima.com/pins1ed/object-equality.html Programming in Scala, + * Chapter 28]] for discussion and design. * * @param that the value being probed for possible equality * @return true if this instance can possibly equal `that`, otherwise false diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index f134f5ce3d..7282feebb6 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -270,7 +270,7 @@ sealed abstract class Option[+A] extends Product with Serializable { * // Returns None because the partial function doesn't cover the case. * Some("ftp") collect {case "http" => "HTTP"} * - * // Returns None because None is passed to the collect method. + * // Returns None because the option is empty. There is no value to pass to the partial function. * None collect {case value => value} * }}} * diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index 6b71c0fa66..603d97c3ad 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -194,6 +194,7 @@ class HashSet[A] extends AbstractSet[A] protected def writeReplace(): AnyRef = new HashSet.SerializationProxy(this) + override def toSet[B >: A]: Set[B] = this.asInstanceOf[HashSet[B]] } /** $factoryInfo diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index 2e17677359..adc975479a 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -179,4 +179,6 @@ class ListSet[A] extends AbstractSet[A] override def tail: ListSet[A] = self } + + override def toSet[B >: A]: Set[B] = this.asInstanceOf[ListSet[B]] } diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index 94a5b7929a..bd5b9c9faf 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -113,6 +113,11 @@ self => override def - (elem: A): immutable.Set[A] = if (this(elem)) immutable.Set[A]() ++ this - elem else this + + // ImmutableDefaultKeySet is only protected, so we won't warn on override. + // Someone could override in a way that makes widening not okay + // (e.g. by overriding +, though the version in this class is fine) + override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]] } /** This function transforms all the values of mappings contained diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala index 0fbf7942d4..a115469b83 100644 --- a/src/library/scala/collection/immutable/Set.scala +++ b/src/library/scala/collection/immutable/Set.scala @@ -35,12 +35,22 @@ trait Set[A] extends Iterable[A] override def companion: GenericCompanion[Set] = Set - /** Returns this $coll as an immutable map. - * - * A new map will not be built; lazy collections will stay lazy. + /** Returns this $coll as an immutable set, perhaps accepting a + * wider range of elements. Since it already is an + * immutable set, it will only be rebuilt if the underlying structure + * cannot be expanded to include arbitrary element types. + * For instance, `BitSet` and `SortedSet` will be rebuilt, as + * they require `Int` and sortable elements respectively. + * + * When in doubt, the set will be rebuilt. Rebuilt sets never + * need to be rebuilt again. */ - @deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0") - override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]] + override def toSet[B >: A]: Set[B] = { + // This way of building sets typically has the best benchmarks, surprisingly! + val sb = Set.newBuilder[B] + foreach(sb += _) + sb.result() + } override def seq: Set[A] = this protected override def parCombiner = ParSet.newCombiner[A] // if `immutable.SetLike` gets introduced, please move this there! @@ -62,6 +72,7 @@ object Set extends ImmutableSetFactory[Set] { def - (elem: Any): Set[Any] = this def iterator: Iterator[Any] = Iterator.empty override def foreach[U](f: Any => U): Unit = {} + override def toSet[B >: Any]: Set[B] = this.asInstanceOf[Set[B]] } private[collection] def emptyInstance: Set[Any] = EmptySet @@ -92,6 +103,10 @@ object Set extends ImmutableSetFactory[Set] { if (f(elem1)) Some(elem1) else None } + // Why is Set1 non-final? Need to fix that! + @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8") + override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set1[B]] + } /** An optimized representation for immutable sets of size 2 */ @@ -123,6 +138,9 @@ object Set extends ImmutableSetFactory[Set] { else if (f(elem2)) Some(elem2) else None } + // Why is Set2 non-final? Need to fix that! + @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8") + override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set2[B]] } /** An optimized representation for immutable sets of size 3 */ @@ -156,6 +174,9 @@ object Set extends ImmutableSetFactory[Set] { else if (f(elem3)) Some(elem3) else None } + // Why is Set3 non-final? Need to fix that! + @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8") + override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set3[B]] } /** An optimized representation for immutable sets of size 4 */ @@ -191,6 +212,9 @@ object Set extends ImmutableSetFactory[Set] { else if (f(elem4)) Some(elem4) else None } + // Why is Set4 non-final? Need to fix that! + @deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8") + override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set4[B]] } } diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index f1493551ab..682788e18e 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -53,6 +53,12 @@ self => val map = self.rangeImpl(from, until) new map.DefaultKeySortedSet } + override def toSet[C >: A]: Set[C] = { + // This way of building sets typically has the best benchmarks, surprisingly! + val sb = Set.newBuilder[C] + foreach(sb += _) + sb.result() + } } /** Add a key/value pair to this map. diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 619beeb1d6..e6889da3b5 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -18,8 +18,19 @@ import generic._ * * Only the `dequeue` and `dequeueAll` methods will return elements in priority * order (while removing elements from the heap). Standard collection methods - * including `drop` and `iterator` will remove or traverse the heap in whichever - * order seems most convenient. + * including `drop`, `iterator`, and `toString` will remove or traverse the heap + * in whichever order seems most convenient. + * + * Therefore, printing a `PriorityQueue` will not reveal the priority order of + * the elements, though the highest-priority element will be printed first. To + * print the elements in order, one must duplicate the `PriorityQueue` (by using + * `clone`, for instance) and then dequeue them: + * + * @example {{{ + * val pq = collection.mutable.PriorityQueue(1, 2, 5, 3, 7) + * println(pq) // elements probably not in order + * println(pq.clone.dequeueAll) // prints Vector(7, 5, 3, 2, 1) + * }}} * * @tparam A type of the elements in this priority queue. * @param ord implicit ordering used to compare the elements of type `A`. diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala index 9634f6d900..1ee27b0f36 100644 --- a/src/library/scala/concurrent/SyncVar.scala +++ b/src/library/scala/concurrent/SyncVar.scala @@ -40,7 +40,7 @@ class SyncVar[A] { wait(timeout) val elapsed = System.nanoTime() - start // nanoTime should be monotonic, but it's not possible to rely on that. - // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458294. + // See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294. if (elapsed < 0) 0 else TimeUnit.NANOSECONDS.toMillis(elapsed) } diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala index 60f99199cb..2a41e25b01 100644 --- a/src/library/scala/io/Codec.scala +++ b/src/library/scala/io/Codec.scala @@ -22,7 +22,7 @@ import scala.language.implicitConversions // <?xml version="1.0" encoding="ISO8859-1" ?> // // MacRoman vs. UTF-8: see http://jira.codehaus.org/browse/JRUBY-3576 -// -Dfile.encoding: see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4375816 +// -Dfile.encoding: see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4375816 /** A class for character encoding/decoding preferences. * diff --git a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala index ca7a3cddb8..82ec872806 100644 --- a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala +++ b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala @@ -218,7 +218,7 @@ object ClassManifestFactory { /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not * strictly necessary as it could be obtained by reflection. It was * added so that erasure can be calculated without reflection. - * todo: remove after next boostrap + * todo: remove after next bootstrap */ def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = new ClassManifest[T] { @@ -239,4 +239,4 @@ private class ClassTypeManifest[T]( (if (prefix.isEmpty) "" else prefix.get.toString+"#") + (if (runtimeClass.isArray) "Array" else runtimeClass.getName) + argString -}
\ No newline at end of file +} diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index ce27a0ce63..026d5edd29 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -155,7 +155,7 @@ object ScalaRunTime { arr } - // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957 + // Java bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4071957 // More background at ticket #2318. def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala index ee2bdbc4a7..b4f965f69b 100644 --- a/src/library/scala/util/Sorting.scala +++ b/src/library/scala/util/Sorting.scala @@ -88,7 +88,7 @@ object Sorting { a(pL - 1) = current pL -= 1 case x if x < 0 => - // Already in place. Just update indicies. + // Already in place. Just update indices. iA += 1 case _ if iB > pR => // Wrong side. There's room on the other side, so swap diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index cd7648a44a..f9b49f1730 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -588,7 +588,7 @@ trait Types { /** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)` * Here, `pre` is the prefix of the type reference, `sym` is the symbol * referred to by the type reference, and `args` is a possible empty list of - * type argumenrts. + * type arguments. * @group Extractors */ abstract class TypeRefExtractor { diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala index e5d97e8959..a4223c1cb5 100644 --- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala +++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala @@ -14,7 +14,7 @@ object ClassfileConstants { final val JAVA_MAJOR_VERSION = 45 final val JAVA_MINOR_VERSION = 3 - /** (see http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html) + /** (see http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1) * * If the `ACC_INTERFACE` flag is set, the `ACC_ABSTRACT` flag must also * be set (ch. 2.13.1). diff --git a/src/reflect/scala/reflect/internal/Kinds.scala b/src/reflect/scala/reflect/internal/Kinds.scala index 8ae201f045..902ba9fa80 100644 --- a/src/reflect/scala/reflect/internal/Kinds.scala +++ b/src/reflect/scala/reflect/internal/Kinds.scala @@ -237,7 +237,7 @@ trait Kinds { * * Proper types are represented using ProperTypeKind. * - * Type constructors are reprented using TypeConKind. + * Type constructors are represented using TypeConKind. */ abstract class Kind { import Kind.StringState diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 1113da2eff..05fdfb51ed 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2124,7 +2124,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The package class containing this symbol, or NoSymbol if there * is not one. * TODO: formulate as enclosingSuchThat, after making sure - * we can start with current symbol rather than onwner. + * we can start with current symbol rather than owner. * TODO: Also harmonize with enclClass, enclMethod etc. */ def enclosingPackageClass: Symbol = { diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index e3f95f9fd8..bbd9df05d2 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1418,7 +1418,7 @@ trait Trees extends api.Trees { transformTypeDefs(tparams), transform(rhs)) } case LabelDef(name, params, rhs) => - treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy' + treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LambdaLifter.proxy' case PackageDef(pid, stats) => treeCopy.PackageDef( tree, transform(pid).asInstanceOf[RefTree], @@ -1601,7 +1601,7 @@ trait Trees extends api.Trees { case _ => // no special handling is required for Function or Import nodes here. // as they don't have interesting infos attached to their symbols. - // Subsitution of the referenced symbol of Return nodes is handled + // Substitution of the referenced symbol of Return nodes is handled // in .ChangeOwnerTraverser } tree match { diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala index abea8bed9f..85e3ac60e8 100644 --- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala +++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala @@ -40,19 +40,27 @@ trait UnCurry { apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe)) case NullaryMethodType(restpe) => apply(MethodType(List(), restpe)) - case TypeRef(pre, ByNameParamClass, arg :: Nil) => - apply(functionType(List(), arg)) - case TypeRef(pre, RepeatedParamClass, arg :: Nil) => - apply(seqType(arg)) - case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) => - apply(arrayType( - if (isUnboundedGeneric(arg)) ObjectTpe else arg)) + case DesugaredParameterType(desugaredTpe) => + apply(desugaredTpe) case _ => expandAlias(mapOver(tp)) } } } + object DesugaredParameterType { + def unapply(tpe: Type): Option[Type] = tpe match { + case TypeRef(pre, ByNameParamClass, arg :: Nil) => + Some(functionType(List(), arg)) + case TypeRef(pre, RepeatedParamClass, arg :: Nil) => + Some(seqType(arg)) + case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) => + Some(arrayType(if (isUnboundedGeneric(arg)) ObjectTpe else arg)) + case _ => + None + } + } + private val uncurryType = new TypeMap { def apply(tp0: Type): Type = { val tp = expandAlias(tp0) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index a2232d1963..278d081249 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -445,7 +445,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.ScalaValueClassesNoUnit definitions.ScalaValueClasses - + uncurry.DesugaredParameterType erasure.GenericArray erasure.scalaErasure erasure.specialScalaErasure diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index 06ae179da9..3b54f5274e 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -133,7 +133,6 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set } catch AbstractOrMissingHandler() } - private def tquoted(s: String) = "\"\"\"" + s + "\"\"\"" private val logScope = scala.sys.props contains "scala.repl.scope" private def scopelog(msg: String) = if (logScope) Console.err.println(msg) @@ -905,7 +904,10 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set def path = originalPath("$intp") def envLines = { if (!isReplPower) Nil // power mode only for now - else List("def %s = %s".format("$line", tquoted(originalLine)), "def %s = Nil".format("$trees")) + else { + val escapedLine = Constant(originalLine).escapedStringValue + List(s"""def $$line = $escapedLine """, """def $trees = _root_.scala.Nil""") + } } def preamble = s""" |$headerPreamble diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala index 743c2a401c..0353e58e67 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala @@ -787,7 +787,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp if (isReduced) NodeSeq.Empty else { def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = { def param0(vl: ValueParam): NodeSeq = - // notice the }{ in the next lines, they are necessary to avoid an undesired withspace in output + // notice the }{ in the next lines, they are necessary to avoid an undesired whitespace in output <span name={ vl.name }>{ Text(vl.name) }{ Text(": ") ++ typeToHtml(vl.resultType, hasLinks) }{ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala index 4bed106f43..9381cf3a35 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala @@ -145,7 +145,7 @@ class DotProcess(settings: doc.Settings) { // we shouldn't just sit there for 50s not reporting anything, no? settings.printMsg("Graphviz dot encountered an error when generating the diagram for:") settings.printMsg(templateName) - settings.printMsg("These are usually spurious errors, but if you notice a persistant error on") + settings.printMsg("These are usually spurious errors, but if you notice a persistent error on") settings.printMsg("a diagram, please use the " + settings.docDiagramsDebug.name + " flag and report a bug with the output.") } } |