Skip to content

Commit

Permalink
Merge pull request scala#5845 from adriaanm/t10261
Browse files Browse the repository at this point in the history
Actually retract clashing synthetic apply/unapply
  • Loading branch information
adriaanm authored Apr 12, 2017
2 parents 12c240d + 747e223 commit 21d12e9
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/Namers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,17 @@ trait Namers extends MethodSynthesis {

if (suppress) {
sym setInfo ErrorType

// There are two ways in which we exclude the symbol from being added in typedStats::addSynthetics,
// because we don't know when the completer runs with respect to this loop in addSynthetics
// for (sym <- scope)
// for (tree <- context.unit.synthetics.get(sym) if shouldAdd(sym)) {
// if (!sym.initialize.hasFlag(IS_ERROR))
// newStats += typedStat(tree)
// If we're already in the loop, set the IS_ERROR flag and trigger the condition `sym.initialize.hasFlag(IS_ERROR)`
sym setFlag IS_ERROR
// Or, if we are not yet in the addSynthetics loop, we can just retract our symbol from the synthetics for this unit.
companionContext.unit.synthetics -= sym

// Don't unlink in an error situation to generate less confusing error messages.
// Ideally, our error reporting would distinguish overloaded from recursive user-defined apply methods without signature,
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3168,7 +3168,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
for (sym <- scope)
// OPT: shouldAdd is usually true. Call it here, rather than in the outer loop
for (tree <- context.unit.synthetics.get(sym) if shouldAdd(sym)) {
newStats += typedStat(tree) // might add even more synthetics to the scope
// if the completer set the IS_ERROR flag, retract the stat (currently only used by applyUnapplyMethodCompleter)
if (!sym.initialize.hasFlag(IS_ERROR))
newStats += typedStat(tree) // might add even more synthetics to the scope
context.unit.synthetics -= sym
}
// the type completer of a synthetic might add more synthetics. example: if the
Expand Down
4 changes: 4 additions & 0 deletions test/files/run/t10261/Companion_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
trait Companion[T] {
def parse(value: String): Option[T]
def apply(value: String): T = parse(value).get
}
14 changes: 14 additions & 0 deletions test/files/run/t10261/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import scala.util.Try

object C extends Companion[C] {
def parse(v: String) = if (v.nonEmpty) Some(new C(v)) else None
}

case class C(value: String)

object Test {
def main(args: Array[String]): Unit = {
assert(Try{C("")}.isFailure, "Empty value should fail to parse") // check that parse is used to validate input
assert(C("a").value == "a", "Unexpected value")
}
}

0 comments on commit 21d12e9

Please sign in to comment.