-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Eagerly enter default getters into scope #6286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
cf6c44d
to
ae90434
Compare
val default = owner.newMethodSymbol(name, vparam.pos, paramFlagsToDefaultGetter(meth.flags)) | ||
default.setPrivateWithin(meth.privateWithin) | ||
default.referenced = meth | ||
default.setInfo(ErrorType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is a bit gross, but we're not able to form the RHS of the default getter yet, so we can't assign the type completer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminds me of our discussion on generalizing unit.synthetics to take tree creators rather than trees
Hmmm
ed7e6b2 / https://scala-ci.typesafe.com/job/scala-2.13.x-validate-test/817/console The subsequent commit built successfully. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ae90434
to
f3f7935
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
f3f7935
to
53bf5f8
Compare
Pushed a fix for problem identifed by the failing test: |
53bf5f8
to
51d83db
Compare
This comment has been minimized.
This comment has been minimized.
51d83db
to
1fcb418
Compare
rebased |
- Factor out differences between constructors and regular methods into an virtual call to a helper class - Tease apart symbol creation/entry from synthesis of the default getter tree to prepare for a subsequent commit that will perform the first part eagerly. - Add a test to show the unstable order of the default getter symbols in the owner's scope.
1fcb418
to
d8f5db0
Compare
rebased again |
Looks like this broke paradise
|
I'll chase that problem down soon. |
I guess something like this is needed: diff --git a/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala b/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala
index 0444d547d1..e116fd5432 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala
@@ -272,8 +272,13 @@ trait MacroAnnotationNamers { self: Analyzer =>
if (isEnumConstant(tree))
tree.symbol setInfo ConstantType(Constant(tree.symbol))
case tree @ DefDef(_, nme.CONSTRUCTOR, _, _, _, _) =>
+ if (mexists(tree.vparamss)(_.mods.hasDefault))
+ enterDefaultGetters(tree.symbol, tree, tree.vparamss, tree.tparams)
sym setInfo completerOf(tree)
case tree @ DefDef(mods, name, tparams, _, _, _) =>
+ if (mexists(tree.vparamss)(_.mods.hasDefault))
+ enterDefaultGetters(tree.symbol, tree, tree.vparamss, tree.tparams)
+
val completer =
if (sym hasFlag SYNTHETIC) {
if (name == nme.copy) copyMethodCompleter(tree)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 0266dd86cc..c97824dfb0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1432,7 +1432,7 @@ trait Namers extends MethodSynthesis {
/**
* For every default argument, insert a method symbol computing that default
*/
- private def enterDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], tparams: List[TypeDef]) {
+ def enterDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], tparams: List[TypeDef]) {
val methOwner = meth.owner
val search = DefaultGetterNamerSearch(context, meth, initCompanionModule = false)
var posCounter = 1 But I can't get the macro annotation test suite to run:
Debugging that with
I see in this code: def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroStatus = {
import typer.TyperErrorGen._
val fallbackSym = expandee.symbol.nextOverriddenSymbol orElse MacroImplementationNotFoundError(expandee)
macroLogLite(s"falling back to: $fallbackSym")
Why is this looking for the overriden symbol of the |
Oh, its another instance of the JDK9+ problem in which protected def findMacroClassLoader(): ClassLoader = {
val classpath = global.classPath.asURLs
def newLoader = () => {
macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath))
ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
}
import scala.tools.nsc.io.Jar
import scala.reflect.io.{AbstractFile, Path}
val locations = classpath.map(u => Path(AbstractFile.getURL(u).file)) And swallowed in: def resolveRuntime(): MacroRuntime = {
if (className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded) {
args => throw new AbortMacroException(args.c.enclosingPosition, "macro implementation is missing")
} else {
try {
macroLogVerbose(s"resolving macro implementation as $className.$methName (isBundle = $isBundle)")
macroLogVerbose(s"classloader is: ${ReflectionUtils.show(defaultMacroClassloader)}")
resolveJavaReflectionRuntime(defaultMacroClassloader)
} catch {
case ex: Exception =>
macroLogVerbose(s"macro runtime failed to load: ${ex.toString}")
macroDef setFlag IS_ERROR
null
}
}
} And the |
The Java 9 thing was fixed in 2.12.x but accidentally lost in the merge to 2.13.x. Bringing it back in: #6695 |
This stabilizes the order they appear in the owners scope. Previously, their order was goverened by the order that the methods bearing default parameters were type completed. Make macro annotations compatible with these changes
991c4df
to
87be453
Compare
@adriaanm I've fixed the macro annotation incompatibility. |
@@ -27,7 +27,9 @@ trait NamesDefaults { self: Analyzer => | |||
// we need the ClassDef. To create and enter the symbols into the companion | |||
// object, we need the templateNamer of that module class. These two are stored | |||
// as an attachment in the companion module symbol | |||
class ConstructorDefaultsAttachment(val classWithDefault: ClassDef, var companionModuleClassNamer: Namer) | |||
class ConstructorDefaultsAttachment(val classWithDefault: ClassDef, var companionModuleClassNamer: Namer) { | |||
var defaults = mutable.ListBuffer[Symbol]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this a var?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be a val, I guess I started out with a var default: List[..]
but it worked out more convenient to use a mutable collection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tricky stuff! Can merge as is, but would be nice to update the comment in the new test
@@ -18,6 +18,6 @@ class NamerTest extends BytecodeTesting { | |||
compiler.compileClasses("package p1; class Test { C.b(); C.a() }; object C { def a(x: Int = 0) = 0; def b(x: Int = 0) = 0 }") | |||
val methods = compiler.global.rootMirror.getRequiredModule("p1.C").info.decls.toList.map(_.name.toString).filter(_.matches("""(a|b).*""")) | |||
def getterName(s: String) = nme.defaultGetterName(TermName(s), 1).toString | |||
Assert.assertEquals(List("a", "b", getterName("b"), getterName("a")), methods) // order depends on order of lazy type completion :( | |||
Assert.assertEquals(List("a", getterName("a"), "b", getterName("b")), methods) // order depends on order of lazy type completion :( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment now outdated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a commit to replace :(
with :)
val default = owner.newMethodSymbol(name, vparam.pos, paramFlagsToDefaultGetter(meth.flags)) | ||
default.setPrivateWithin(meth.privateWithin) | ||
default.referenced = meth | ||
default.setInfo(ErrorType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminds me of our discussion on generalizing unit.synthetics to take tree creators rather than trees
FTR, here's the pattern of case-class-esque synthesis that I'd like to make more straight forward with lazy synthetics: |
👌 I'll hit merge when ✅ |
Thanks for reviewing! |
This stabilizes the order they appear in the owners scope. Previously,
their order was governed by the order that the methods bearing default
parameters were type completed.
References scala/scala-dev#405