summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-11-15 07:27:45 -0800
committerPaul Phillips <paulp@improving.org>2012-11-15 07:27:45 -0800
commitbc60605e182d526e4224c804d218e9a0e2952b72 (patch)
treee1789721cc30309f0ad0dde9f4d8d045cf5c4fc0
parentbdab9cd5456203284658c1fbd492dc184126b3d1 (diff)
parent24958f7a8b1748be0c462b4563e652c9f7e24d6a (diff)
downloadscala-bc60605e182d526e4224c804d218e9a0e2952b72.tar.gz
scala-bc60605e182d526e4224c804d218e9a0e2952b72.tar.bz2
scala-bc60605e182d526e4224c804d218e9a0e2952b72.zip
Merge pull request #1627 from paulp/issue/6664
Fix for SI-6664, cycle in case classes.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Scopes.scala8
-rw-r--r--test/files/pos/t6664.scala4
-rw-r--r--test/files/pos/t6664b.scala5
4 files changed, 17 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 3f5410eb45..04fb69671e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -909,11 +909,10 @@ trait Namers extends MethodSynthesis {
val modClass = companionSymbolOf(clazz, context).moduleClass
modClass.attachments.get[ClassForCaseCompanionAttachment] foreach { cma =>
val cdef = cma.caseClass
- def hasCopy(decls: Scope) = (decls lookup nme.copy) != NoSymbol
+ def hasCopy = (decls containsName nme.copy) || parents.exists(_ member nme.copy exists)
+
// SI-5956 needs (cdef.symbol == clazz): there can be multiple class symbols with the same name
- if (cdef.symbol == clazz && !hasCopy(decls) &&
- !parents.exists(p => hasCopy(p.typeSymbol.info.decls)) &&
- !parents.flatMap(_.baseClasses).distinct.exists(bc => hasCopy(bc.info.decls)))
+ if (cdef.symbol == clazz && !hasCopy)
addCopyMethod(cdef, templateNamer)
}
}
diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala
index a593a412d7..950e30dbc5 100644
--- a/src/reflect/scala/reflect/internal/Scopes.scala
+++ b/src/reflect/scala/reflect/internal/Scopes.scala
@@ -242,7 +242,8 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
// than a non-deterministic bizarre one (see any bug involving overloads
// in package objects.)
val alts = lookupAll(name).toList
- log("!!! scope lookup of $name found multiple symbols: $alts")
+ def alts_s = alts map (s => s.defString) mkString " <and> "
+ log(s"!!! scope lookup of $name found multiple symbols: $alts_s")
// FIXME - how is one supposed to create an overloaded symbol without
// knowing the correct owner? Using the symbol owner is not correct;
// say for instance this is List's scope and the symbols are its three
@@ -254,8 +255,9 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
// FIXME - a similar question for prefix, although there are more
// clues from the symbols on that one, as implemented here. In general
// the distinct list is one type and lub becomes the identity.
- val prefix = lub(alts map (_.info.prefix) distinct)
- NoSymbol.newOverloaded(prefix, alts)
+ // val prefix = lub(alts map (_.info.prefix) distinct)
+ // Now using NoSymbol and NoPrefix always to avoid forcing info (SI-6664)
+ NoSymbol.newOverloaded(NoPrefix, alts)
}
}
diff --git a/test/files/pos/t6664.scala b/test/files/pos/t6664.scala
new file mode 100644
index 0000000000..7eb85f619d
--- /dev/null
+++ b/test/files/pos/t6664.scala
@@ -0,0 +1,4 @@
+final case class A(i: Int, s: String) {
+ protected def copy(s2: String): A = A(i, s2)
+ protected def copy(i2: Int): A = A(i2, s)
+}
diff --git a/test/files/pos/t6664b.scala b/test/files/pos/t6664b.scala
new file mode 100644
index 0000000000..a622866838
--- /dev/null
+++ b/test/files/pos/t6664b.scala
@@ -0,0 +1,5 @@
+object T {
+ def A(s: String): A = new A(3, s)
+ def A(i: Int): A = A(i, "abc")
+ case class A(i: Int, s: String)
+}