Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1701 from retronym/ticket/5877

SI-5877 Support implicit classes in package objects
  • Loading branch information...
commit 7fe7d2537963dd24ea1cca7b0c4b96f96b773c4a 2 parents 38b9222 + 0b1ae9c
Adriaan Moors adriaanm authored
20 src/compiler/scala/tools/nsc/CompilationUnits.scala
View
@@ -23,7 +23,7 @@ trait CompilationUnits { self: Global =>
/** One unit of compilation that has been submitted to the compiler.
* It typically corresponds to a single file of source code. It includes
* error-reporting hooks. */
- class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi {
+ class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi { self =>
/** the fresh name creator */
var fresh: FreshNameCreator = new FreshNameCreator.Default
@@ -57,7 +57,23 @@ trait CompilationUnits { self: Global =>
/** Synthetic definitions generated by namer, eliminated by typer.
*/
- val synthetics = mutable.HashMap[Symbol, Tree]()
+ object synthetics {
+ private val map = mutable.HashMap[Symbol, Tree]()
+ def update(sym: Symbol, tree: Tree) {
+ debuglog(s"adding synthetic ($sym, $tree) to $self")
+ map.update(sym, tree)
+ }
+ def -=(sym: Symbol) {
+ debuglog(s"removing synthetic $sym from $self")
+ map -= sym
+ }
+ def get(sym: Symbol): Option[Tree] = logResultIf[Option[Tree]](s"found synthetic for $sym in $self", _.isDefined) {
+ map get sym
+ }
+ def keys: Iterable[Symbol] = map.keys
+ def clear(): Unit = map.clear()
+ override def toString = map.toString
+ }
/** things to check at end of compilation unit */
val toCheck = new ListBuffer[() => Unit]
6 src/compiler/scala/tools/nsc/typechecker/Typers.scala
View
@@ -2956,7 +2956,11 @@ trait Typers extends Modes with Adaptations with Tags {
var moreToAdd = true
while (moreToAdd) {
val initElems = scope.elems
- for (sym <- scope)
+ // SI-5877 The decls of a package include decls of the package object. But we don't want to add
+ // the corresponding synthetics to the package class, only to the package object class.
+ def shouldAdd(sym: Symbol) =
+ inBlock || !isInPackageObject(sym, context.owner)
+ for (sym <- scope if shouldAdd(sym))
for (tree <- context.unit.synthetics get sym) {
newStats += typedStat(tree) // might add even more synthetics to the scope
context.unit.synthetics -= sym
14 test/files/pos/t5877.scala
View
@@ -0,0 +1,14 @@
+package foo {
+ class Foo
+
+ object Test {
+ new Foo().huzzah
+ }
+}
+
+package object foo {
+ // Crasher: No synthetics for method PimpedFoo2: synthetics contains
+ implicit class PimpedFoo2(value: Foo) {
+ def huzzah = ""
+ }
+}
13 test/files/pos/t5877b.scala
View
@@ -0,0 +1,13 @@
+package foo
+
+class Foo
+
+object Test {
+ new Foo().huzzah
+}
+
+object `package` {
+ implicit class PimpedFoo2(value: Foo) {
+ def huzzah = ""
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.