summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala13
-rwxr-xr-xsrc/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala48
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala13
-rw-r--r--src/library/scala/reflect/ClassTag.scala9
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala25
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala14
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala281
9 files changed, 67 insertions, 349 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 1d29e33c50..9a6d32be01 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -95,11 +95,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val gvdefs = evdefs map {
- case vdef @ ValDef(_, _, tpt, _) => copyValDef(vdef)(
- // !!! I know "atPos in case" wasn't intentionally planted to
- // add an air of mystery to this file, but it is the sort of
- // comment which only its author could love.
- tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), // atPos in case
+ case vdef @ ValDef(_, _, tpt, _) =>
+ copyValDef(vdef)(
+ // atPos for the new tpt is necessary, since the original tpt might have no position
+ // (when missing type annotation for ValDef for example), so even though setOriginal modifies the
+ // position of TypeTree, it would still be NoPosition. That's what the author meant.
+ tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus),
rhs = EmptyTree
)
}
@@ -125,7 +126,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
- constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
+ constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false))
// Field definitions for the class - remove defaults.
val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree))
diff --git a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
index f4c96505a7..9d141efe0a 100755
--- a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
@@ -8,7 +8,6 @@ package doc
package model
import scala.collection._
-import language.reflectiveCalls
object IndexModelFactory {
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 06828f3a3a..b702d2787c 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -41,11 +41,11 @@ self: scala.tools.nsc.Global =>
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
* If some of the trees are ranges, returns a range position enclosing all ranges
- * Otherwise returns default position.
+ * Otherwise returns default position that is either focused or not.
*/
- override def wrappingPos(default: Position, trees: List[Tree]): Position = {
+ override def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = {
val ranged = trees filter (_.pos.isRange)
- if (ranged.isEmpty) default.focus
+ if (ranged.isEmpty) if (focus) default.focus else default
else new RangePosition(default.source, (ranged map (_.pos.start)).min, default.point, (ranged map (_.pos.end)).max)
}
@@ -59,13 +59,25 @@ self: scala.tools.nsc.Global =>
if (headpos.isDefined) wrappingPos(headpos, trees) else headpos
}
-/*
- override def integratePos(tree: Tree, pos: Position) =
- if (pos.isSynthetic && !tree.pos.isSynthetic) tree.syntheticDuplicate
- else tree
-*/
-
// -------------- ensuring no overlaps -------------------------------
+
+ /** Ensure that given tree has no positions that overlap with
+ * any of the positions of `others`. This is done by
+ * shortening the range, assigning TransparentPositions
+ * to some of the nodes in `tree` or focusing on the position.
+ */
+ override def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) {
+ def isOverlapping(pos: Position) =
+ pos.isRange && (others exists (pos overlaps _.pos))
+ if (isOverlapping(tree.pos)) {
+ val children = tree.children
+ children foreach (ensureNonOverlapping(_, others, focus))
+ if (tree.pos.isOpaqueRange) {
+ val wpos = wrappingPos(tree.pos, children, focus)
+ tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos)
+ }
+ }
+ }
def solidDescendants(tree: Tree): List[Tree] =
if (tree.pos.isTransparent) tree.children flatMap solidDescendants
@@ -106,24 +118,6 @@ self: scala.tools.nsc.Global =>
if (ts.head == t) replacement ::: ts.tail
else ts.head :: replace(ts.tail, t, replacement)
- /** Ensure that given tree has no positions that overlap with
- * any of the positions of `others`. This is done by
- * shortening the range or assigning TransparentPositions
- * to some of the nodes in `tree`.
- */
- override def ensureNonOverlapping(tree: Tree, others: List[Tree]) {
- def isOverlapping(pos: Position) =
- pos.isRange && (others exists (pos overlaps _.pos))
- if (isOverlapping(tree.pos)) {
- val children = tree.children
- children foreach (ensureNonOverlapping(_, others))
- if (tree.pos.isOpaqueRange) {
- val wpos = wrappingPos(tree.pos.focus, children)
- tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos)
- }
- }
- }
-
/** Does given list of trees have mutually non-overlapping positions?
* pre: None of the trees is transparent
*/
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 5115c49c87..24a74722b0 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -563,8 +563,16 @@ abstract class Erasure extends AddInterfaces
case _ =>
val clazz = tref.sym
log("not boxed: "+tree)
- val tree0 = adaptToType(tree, clazz.tpe)
- cast(Apply(Select(tree0, clazz.derivedValueClassUnbox), List()), pt)
+ lazy val underlying = underlyingOfValueClass(clazz)
+ val tree0 =
+ if (tree.tpe.typeSymbol == NullClass &&
+ isPrimitiveValueClass(underlying.typeSymbol)) {
+ // convert `null` directly to underlying type, as going
+ // via the unboxed type would yield a NPE (see SI-5866)
+ unbox1(tree, underlying)
+ } else
+ Apply(Select(adaptToType(tree, clazz.tpe), clazz.derivedValueClassUnbox), List())
+ cast(tree0, pt)
}
case _ =>
pt.typeSymbol match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b1c3249e35..e57cae00e0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1401,6 +1401,15 @@ trait Typers extends Modes with Adaptations with Tags {
unit.error(clazz.pos, "value class needs to have exactly one public val parameter")
}
}
+ body foreach {
+ case md: ModuleDef =>
+ unit.error(md.pos, "value class may not have nested module definitions")
+ case cd: ClassDef =>
+ unit.error(cd.pos, "value class may not have nested class definitions")
+ case md: DefDef if md.symbol.isConstructor && !md.symbol.isPrimaryConstructor =>
+ unit.error(md.pos, "value class may not have secondary constructors")
+ case _ =>
+ }
for (tparam <- clazz.typeParams)
if (tparam hasAnnotation definitions.SpecializedClass)
unit.error(tparam.pos, "type parameter of value class may not be specialized")
@@ -5019,7 +5028,9 @@ trait Typers extends Modes with Adaptations with Tags {
if (isPatternMode) {
val uncheckedTypeExtractor = extractorForUncheckedType(tpt.pos, tptTyped.tpe)
val ownType = inferTypedPattern(tptTyped, tptTyped.tpe, pt, canRemedy = uncheckedTypeExtractor.nonEmpty)
- treeTyped setType ownType
+ // println(s"Typed($expr, ${tpt.tpe}) : $pt --> $ownType (${isFullyDefined(ownType)}, ${makeFullyDefined(ownType)})")
+ // make fully defined to avoid bounded wildcard types that may be in pt from calling dropExistential (SI-2038)
+ treeTyped setType (if (isFullyDefined(ownType)) ownType else makeFullyDefined(ownType)) //ownType
uncheckedTypeExtractor match {
case None => treeTyped
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 5255c44f10..7b6df6e31c 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -64,7 +64,6 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial
}
object ClassTag {
- private val NothingTYPE = classOf[scala.runtime.Nothing$]
private val NullTYPE = classOf[scala.runtime.Null$]
private val ObjectTYPE = classOf[java.lang.Object]
@@ -81,7 +80,13 @@ object ClassTag {
val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object]{ def runtimeClass = ObjectTYPE; private def readResolve() = ClassTag.Object }
val AnyVal : ClassTag[scala.AnyVal] = ClassTag.Object.asInstanceOf[ClassTag[scala.AnyVal]]
val AnyRef : ClassTag[scala.AnyRef] = ClassTag.Object.asInstanceOf[ClassTag[scala.AnyRef]]
- val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{ def runtimeClass = NothingTYPE; private def readResolve() = ClassTag.Nothing }
+ val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{
+ def runtimeClass = throw new Exception("Nothing is a bottom type, therefore its erasure does not return a value")
+ private def readResolve() = ClassTag.Nothing
+ override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && (x.asInstanceOf[AnyRef] eq ClassTag.Nothing)
+ override def hashCode = System.identityHashCode(this)
+ override def toString = "ClassTag[Nothing]"
+ }
val Null : ClassTag[scala.Null] = new ClassTag[scala.Null]{ def runtimeClass = NullTYPE; private def readResolve() = ClassTag.Null }
def apply[T](runtimeClass1: jClass[_]): ClassTag[T] =
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 1d2888961b..c94c796279 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -232,31 +232,6 @@ trait Symbols extends base.Symbols { self: Universe =>
/** The overloaded alternatives of this symbol */
def alternatives: List[Symbol]
- /** Performs method overloading resolution. More precisely, resolves an overloaded TermSymbol
- * to a single, non-overloaded TermSymbol that accepts the specified argument types.
- * @param pre The prefix type, i.e. the type of the value the method is dispatched on.
- * This is required when resolving references to type parameters of the type
- * the method is declared in. For example if the method is declared in class `List[A]`,
- * providing the prefix as `List[Int]` allows the overloading resolution to use
- * `Int` instead of `A`.
- * @param targs Type arguments that a candidate alternative must be able to accept. Candidates
- * will be considered with these arguments substituted for their corresponding
- * type parameters.
- * @param posVargs Positional argument types that a candidate alternative must be able to accept.
- * @param nameVargs Named argument types that a candidate alternative must be able to accept.
- * Each element in the sequence should be a pair of a parameter name and an
- * argument type.
- * @param expected Return type that a candidate alternative has to be compatible with.
- * @return Either a single, non-overloaded Symbol referring to the selected alternative
- * or NoSymbol if no single member could be selected given the passed arguments.
- */
- def resolveOverloaded(
- pre: Type = NoPrefix,
- targs: Seq[Type] = List(),
- posVargs: Seq[Type] = List(),
- nameVargs: Seq[(TermName, Type)] = List(),
- expected: Type = NoType
- ): Symbol
}
/** The API of type symbols */
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 6ae9b40fcb..faa161d6b1 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -10,23 +10,25 @@ trait Positions extends api.Positions { self: SymbolTable =>
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
* If some of the trees are ranges, returns a range position enclosing all ranges
- * Otherwise returns default position.
+ * Otherwise returns default position that is either focused or not.
*/
- def wrappingPos(default: Position, trees: List[Tree]): Position = default
+ def wrappingPos(default: Position, trees: List[Tree]) = wrappingPos(default, trees, true)
+ def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = default
/** A position that wraps the non-empty set of trees.
* The point of the wrapping position is the point of the first trees' position.
- * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
+ * If some of the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
* Otherwise returns a synthetic offset position to point.
*/
def wrappingPos(trees: List[Tree]): Position = trees.head.pos
/** Ensure that given tree has no positions that overlap with
* any of the positions of `others`. This is done by
- * shortening the range or assigning TransparentPositions
- * to some of the nodes in `tree`.
+ * shortening the range, assigning TransparentPositions
+ * to some of the nodes in `tree` or focusing on the position.
*/
- def ensureNonOverlapping(tree: Tree, others: List[Tree]) {}
+ def ensureNonOverlapping(tree: Tree, others: List[Tree]){ ensureNonOverlapping(tree, others, true) }
+ def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) {}
trait PosAssigner extends Traverser {
var pos: Position
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index b14306282b..e6a9cb46c6 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -84,281 +84,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def getAnnotations: List[AnnotationInfo] = { initialize; annotations }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
- def resolveOverloaded(
- pre: Type,
- targs: Seq[Type],
- posVargTypes: Seq[Type],
- nameVargTypes: Seq[(TermName, Type)],
- expected: Type
- ): Symbol = {
-
- // Begin Correlation Helpers
-
- def isCompatible(tp: Type, pt: Type): Boolean = {
- def isCompatibleByName(tp: Type, pt: Type): Boolean = pt match {
- case TypeRef(_, ByNameParamClass, List(res)) if !definitions.isByNameParamType(tp) =>
- isCompatible(tp, res)
- case _ =>
- false
- }
- (tp weak_<:< pt) || isCompatibleByName(tp, pt)
- }
-
- def signatureAsSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = {
- (substituteTypeParams(method1), substituteTypeParams(method2)) match {
- case (NullaryMethodType(r1), NullaryMethodType(r2)) =>
- r1 weak_<:< r2
- case (NullaryMethodType(_), MethodType(_, _)) =>
- true
- case (MethodType(_, _), NullaryMethodType(_)) =>
- false
- case (MethodType(p1, _), MethodType(p2, _)) =>
- val len = p1.length max p2.length
- val sub = extend(p1 map (_.typeSignature), len)
- val sup = extend(p2 map (_.typeSignature), len)
- (sub corresponds sup)(isCompatible)
- }
- }
-
- def scopeMoreSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = {
- val o1 = method1.owner.asClassSymbol
- val o2 = method2.owner.asClassSymbol
- val c1 = if (o1.hasFlag(Flag.MODULE)) o1.companionSymbol else o1
- val c2 = if (o2.hasFlag(Flag.MODULE)) o2.companionSymbol else o2
- c1.typeSignature <:< c2.typeSignature
- }
-
- def moreSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = {
- def points(m1: MethodSymbol, m2: MethodSymbol) = {
- val p1 = if (signatureAsSpecific(m1, m2)) 1 else 0
- val p2 = if (scopeMoreSpecific(m1, m2)) 1 else 0
- p1 + p2
- }
- points(method1, method2) > points(method2, method1)
- }
-
- def combineInto (
- variadic: Boolean
- )(
- positional: Seq[Type],
- named: Seq[(TermName, Type)]
- )(
- target: Seq[TermName],
- defaults: Map[Int, Type]
- ): Option[Seq[Type]] = {
-
- val offset = positional.length
- val unfilled = target.zipWithIndex drop offset
- val canAcceptAllNameVargs = named forall { case (argName, _) =>
- unfilled exists (_._1 == argName)
- }
-
- val paramNamesUnique = {
- named.length == named.map(_._1).distinct.length
- }
-
- if (canAcceptAllNameVargs && paramNamesUnique) {
-
- val rest = unfilled map { case (paramName, paramIndex) =>
- val passedIn = named.collect {
- case (argName, argType) if argName == paramName => argType
- }.headOption
-
- passedIn orElse defaults.get(paramIndex).map(_.asInstanceOf[Type])
- }
-
- val rest1 = {
- if (variadic && !rest.isEmpty && !rest.last.isDefined) rest.init
- else rest
- }
-
-
- if (rest1 forall (_.isDefined)) {
- val joined = positional ++ rest1.map(_.get)
- val repeatedCollapsed = {
- if (variadic) {
- val (normal, repeated) = joined.splitAt(target.length - 1)
- if (repeated.forall(_ =:= repeated.head)) Some(normal ++ repeated.headOption)
- else None
- }
- else Some(joined)
- }
- if (repeatedCollapsed.exists(_.length == target.length))
- repeatedCollapsed
- else if (variadic && repeatedCollapsed.exists(_.length == target.length - 1))
- repeatedCollapsed
- else None
- } else None
-
- } else None
- }
-
- // Begin Reflection Helpers
-
- // Replaces a repeated parameter type at the end of the parameter list
- // with a number of non-repeated parameter types in order to pad the
- // list to be nargs in length
- def extend(types: Seq[Type], nargs: Int): Seq[Type] = {
- if (isVarArgTypes(types)) {
- val repeatedType = types.last.normalize.typeArgs.head
- types.init ++ Seq.fill(nargs - (types.length - 1))(repeatedType)
- } else types
- }
-
- // Replaces by-name parameters with their result type and
- // TypeRefs with the thing they reference
- def unwrap(paramType: Type): Type = paramType match {
- case TypeRef(_, IntClass, _) => typeOf[Int]
- case TypeRef(_, LongClass, _) => typeOf[Long]
- case TypeRef(_, ShortClass, _) => typeOf[Short]
- case TypeRef(_, ByteClass, _) => typeOf[Byte]
- case TypeRef(_, CharClass, _) => typeOf[Char]
- case TypeRef(_, FloatClass, _) => typeOf[Float]
- case TypeRef(_, DoubleClass, _) => typeOf[Double]
- case TypeRef(_, BooleanClass, _) => typeOf[Boolean]
- case TypeRef(_, UnitClass, _) => typeOf[Unit]
- case TypeRef(_, NullClass, _) => typeOf[Null]
- case TypeRef(_, AnyClass, _) => typeOf[Any]
- case TypeRef(_, NothingClass, _) => typeOf[Nothing]
- case TypeRef(_, AnyRefClass, _) => typeOf[AnyRef]
- case TypeRef(_, ByNameParamClass, List(resultType)) => unwrap(resultType)
- case t: Type => t
- }
-
- // Gives the names of the parameters to a method
- def paramNames(signature: Type): Seq[TermName] = signature match {
- case PolyType(_, resultType) => paramNames(resultType)
- case MethodType(params, _) => params.map(_.name.asInstanceOf[TermName])
- case NullaryMethodType(_) => Seq.empty
- }
-
- def valParams(signature: Type): Seq[TermSymbol] = signature match {
- case PolyType(_, resultType) => valParams(resultType)
- case MethodType(params, _) => params.map(_.asTermSymbol)
- case NullaryMethodType(_) => Seq.empty
- }
-
- // Returns a map from parameter index to default argument type
- def defaultTypes(method: MethodSymbol): Map[Int, Type] = {
- val typeSig = substituteTypeParams(method)
- val owner = method.owner
- valParams(typeSig).zipWithIndex.filter(_._1.hasFlag(Flag.DEFAULTPARAM)).map { case(_, index) =>
- val name = nme.defaultGetterName(method.name.decodedName, index + 1)
- val default = owner.asType member name
- index -> default.typeSignature.asInstanceOf[NullaryMethodType].resultType
- }.toMap
- }
-
- // True if any of method's parameters have default values. False otherwise.
- def usesDefault(method: MethodSymbol): Boolean = valParams(method.typeSignature) drop(posVargTypes).length exists { param =>
- (param hasFlag Flag.DEFAULTPARAM) && nameVargTypes.forall { case (argName, _) =>
- param.name != argName
- }
- }
-
- // The number of type parameters that the method takes
- def numTypeParams(x: MethodSymbol): Int = {
- x.typeSignature.typeParams.length
- }
-
- def substituteTypeParams(m: MethodSymbol): Type = {
- (pre memberType m) match {
- case m: MethodType => m
- case n: NullaryMethodType => n
- case PolyType(tparams, rest) => rest.substituteTypes(tparams, targs.toList)
- }
- }
-
- // Begin Selection Helpers
-
- def select(
- alternatives: Seq[MethodSymbol],
- filters: Seq[Seq[MethodSymbol] => Seq[MethodSymbol]]
- ): Seq[MethodSymbol] =
- filters.foldLeft(alternatives)((a, f) => {
- if (a.size > 1) f(a) else a
- })
-
- // Drop arguments that take the wrong number of type
- // arguments.
- val posTargLength: Seq[MethodSymbol] => Seq[MethodSymbol] = _.filter { alt =>
- numTypeParams(alt) == targs.length
- }
-
- // Drop methods that are not applicable to the arguments
- val applicable: Seq[MethodSymbol] => Seq[MethodSymbol] = _.filter { alt =>
- // Note: combine returns None if a is not applicable and
- // None.exists(_ => true) == false
- val paramTypes =
- valParams(substituteTypeParams(alt)).map(p => unwrap(p.typeSignature))
- val variadic = isVarArgTypes(paramTypes)
- val maybeArgTypes =
- combineInto(variadic)(posVargTypes, nameVargTypes)(paramNames(alt.typeSignature), defaultTypes(alt))
- maybeArgTypes exists { argTypes =>
- if (isVarArgTypes(argTypes) && !isVarArgTypes(paramTypes)) false
- else {
- val a = argTypes
- val p = extend(paramTypes, argTypes.length)
- (a corresponds p)(_ weak_<:< _)
- }
- }
- }
-
- // Always prefer methods that don't need to use default
- // arguments over those that do.
- // e.g. when resolving foo(1), prefer def foo(x: Int) over
- // def foo(x: Int, y: Int = 4)
- val noDefaults: Seq[MethodSymbol] => Seq[MethodSymbol] =
- _ filterNot usesDefault
-
- // Try to select the most specific method. If that's not possible,
- // return all of the candidates (this will likely cause an error
- // higher up in the call stack)
- val mostSpecific: Seq[MethodSymbol] => Seq[MethodSymbol] = { alts =>
- val sorted = alts.sortWith(moreSpecific)
- val mostSpecific = sorted.head
- val agreeTest: MethodSymbol => Boolean =
- moreSpecific(mostSpecific, _)
- val disagreeTest: MethodSymbol => Boolean =
- moreSpecific(_, mostSpecific)
- if (!sorted.tail.forall(agreeTest)) {
- mostSpecific +: sorted.tail.filterNot(agreeTest)
- } else if (sorted.tail.exists(disagreeTest)) {
- mostSpecific +: sorted.tail.filter(disagreeTest)
- } else {
- Seq(mostSpecific)
- }
- }
-
- def finalResult(t: Type): Type = t match {
- case PolyType(_, rest) => finalResult(rest)
- case MethodType(_, result) => finalResult(result)
- case NullaryMethodType(result) => finalResult(result)
- case t: Type => t
- }
-
- // If a result type is given, drop alternatives that don't meet it
- val resultType: Seq[MethodSymbol] => Seq[MethodSymbol] =
- if (expected == NoType) identity
- else _.filter { alt =>
- finalResult(substituteTypeParams(alt)) <:< expected
- }
-
- def defaultFilteringOps =
- Seq(posTargLength, resultType, applicable, noDefaults, mostSpecific)
-
- // Begin Method Proper
-
-
- val alts = alternatives.map(_.asMethodSymbol)
-
- val selection = select(alts, defaultFilteringOps)
-
- val knownApplicable = applicable(selection)
-
- if (knownApplicable.size == 1) knownApplicable.head
- else NoSymbol
- }
}
/** The class for all symbols */
@@ -2035,7 +1760,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
def isCoDefinedWith(that: Symbol) = {
- import language.reflectiveCalls
(this.rawInfo ne NoType) &&
(this.effectiveOwner == that.effectiveOwner) && {
!this.effectiveOwner.isPackageClass ||
@@ -2706,7 +2430,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def moduleClass = referenced
override def companionClass =
- flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this)
+ flatOwnerInfo.decl(name.toTypeName).suchThat(sym => sym.isClass && (sym isCoDefinedWith this))
override def owner = {
Statistics.incCounter(ownerCount)
@@ -3071,7 +2795,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
protected final def companionModule0: Symbol =
flatOwnerInfo.decl(name.toTermName).suchThat(
- sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod)
+ sym => sym.isModule && (sym isCoDefinedWith this) && !sym.isMethod)
override def companionModule = companionModule0
override def companionSymbol = companionModule0
@@ -3394,7 +3118,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable({
- import language.reflectiveCalls
"Companions '" + sym1 + "' and '" + sym2 + "' must be defined in same file:\n" +
" Found in " + sym1.sourceFile.canonicalPath + " and " + sym2.sourceFile.canonicalPath
}) {