Skip to content

Commit

Permalink
work around incorrectly unexpanded names
Browse files Browse the repository at this point in the history
  • Loading branch information
Martijn Hoekstra committed Jun 3, 2020
1 parent b28e1f1 commit e001e0b
Show file tree
Hide file tree
Showing 7 changed files with 1,647 additions and 3,177 deletions.
22 changes: 14 additions & 8 deletions src/compiler/scala/tools/nsc/transform/Constructors.scala
Expand Up @@ -474,15 +474,21 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
def usesSpecializedField = intoConstructor.usesSpecializedField

// The constructor parameter corresponding to an accessor
def parameter(acc: Symbol): Symbol = parameterNamed(acc.unexpandedName.getterName)
def parameter(acc: Symbol): Symbol = {
import scala.util.Try
//works around the edge case where unexpandedName over-unexpands shenanigans like literal $$ or `$#`
def unexpanded = parameterNamed(acc.unexpandedName.getterName)
def expanded = parameterNamed(acc.getterName)
unexpanded.orElse(expanded).swap.map(abort).merge
}

// The constructor parameter with given name. This means the parameter
// has given name, or starts with given name, and continues with a `$` afterwards.
def parameterNamed(name: Name): Symbol =
// The constructor parameter with given getter name. This means the parameter name
// decodes to the same name that the getter decodes to
def parameterNamed(name: Name): Either[String, Symbol] =
primaryConstrParams.filter(_.name.decodedName == name.decodedName) match {
case List(p) => p
case Nil => abort(s"$name not in $primaryConstrParams")
case ps => abort(s"$name matches multiple constructor paramters $ps")
case List(p) => Right(p)
case Nil => Left(s"No constructor parameter named $name (decoded to ${name.decodedName}) found in list of constructor parameters $primaryConstrParams (decoded to ${primaryConstrParams.map(_.decodedName)})")
case ps => Left(s"$name matches multiple constructor parameters $ps")
}

// A transformer for expressions that go into the constructor
Expand Down Expand Up @@ -529,7 +535,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
else if (canBeSupplanted(tree.symbol))
gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos
else if (tree.symbol.outerSource == clazz && !isDelayedInitSubclass)
gen.mkAttributedIdent(parameterNamed(nme.OUTER)) setPos tree.pos
gen.mkAttributedIdent(parameterNamed(nme.OUTER).fold(abort, identity)).setPos(tree.pos)
else
super.transform(tree)

Expand Down
3 changes: 3 additions & 0 deletions src/reflect/scala/reflect/internal/StdNames.scala
Expand Up @@ -437,6 +437,9 @@ trait StdNames {
* Look backward from the end of the string for "$$", and take the
* part of the string after that; but if the string is "$$$" or longer,
* be sure to retain the extra dollars.
* If the name happens to be a back quoted name containing literal $$
* or $ followed by an operator that gets encoded, go directly to compiler
* crash. Do not pass go and don't even think about collecting any $$
*/
def unexpandedName(name: Name): Name = name lastIndexOf "$$" match {
case 0 | -1 => name
Expand Down
3 changes: 3 additions & 0 deletions test/files/run/t10625.check
@@ -0,0 +1,3 @@
1
1
Some(1)
8 changes: 8 additions & 0 deletions test/files/run/t10625.scala
@@ -0,0 +1,8 @@
case class WhyNot(`^$#`: Int)
object Test extends App {
val wn = WhyNot(1)
println(wn.`^$#`)
val WhyNot(i) = wn
println(i)
println(WhyNot.unapply(wn))
}

0 comments on commit e001e0b

Please sign in to comment.