diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2014-02-09 20:49:48 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-02-09 20:49:48 +0100 |
commit | 2606becba91fa3d31cdeb3069a5a35b0163a4cde (patch) | |
tree | 767e8a3a966a5d93e1e84875a7bbda2e8575ceb7 /src | |
parent | 9dc60af28e2c17579c17e27168d1e29ef34efaef (diff) | |
download | scala-2606becba91fa3d31cdeb3069a5a35b0163a4cde.tar.gz scala-2606becba91fa3d31cdeb3069a5a35b0163a4cde.tar.bz2 scala-2606becba91fa3d31cdeb3069a5a35b0163a4cde.zip |
changes the order of whitebox typechecks. yes, again.
My first attempt at SI-6992 was about having whitebox expansions first
typecheck against outerPt and only then verify that the result is compatible
with innerPt.
That was a nice try, but soon after it went live in 2.11.0-M8, we've got
multiple reports with problems - both shapeless and then in a week specs2
started having issues with their whitebox macros.
In shapeless, typecheck against outerPt screwed up type inference, which
was more or less fixable by explicit type annotations, so I decided to
wait a bit before jumping to conclusions.
However, in specs2 the problem was more insidious. After being typechecked
against outerPt, expansions were being implicitly converted to a type
that became incompatible with innerPt. This revealed a fatal flaw of the
implemented approach - if allowed to typecheck against outerPt first,
whitebox macros could never be robust.
Now realizing that "outerPt > innerPt" doesn't work, I nevertheless wasn't
looking forward to rolling that back to "innerPt > outerPt", because that
would revive SI-6992 and SI-8048 that are highly unintuitive, especially
the latter one.
Therefore, this commit combines the permissiveness of "... > innerPt"
approaches with the robustness of "innerPt > outerPt", introducing
"WildcardType > innerPt > outerPt".
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index cf82d6baac..677c94e063 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -620,9 +620,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { val expanded1 = atPos(enclosingMacroPosition.makeTransparent)(Typed(expanded0, TypeTree(innerPt))) typecheck("blackbox typecheck", expanded1, outerPt) } else { - val expanded1 = expanded0 - val expanded2 = typecheck("whitebox typecheck #1", expanded1, outerPt) - typecheck("whitebox typecheck #2", expanded2, innerPt) + // whitebox expansions need to be typechecked against WildcardType first in order to avoid SI-6992 and SI-8048 + // then we typecheck against innerPt, not against outerPt in order to prevent SI-8209 + val expanded1 = typecheck("whitebox typecheck #0", expanded0, WildcardType) + val expanded2 = typecheck("whitebox typecheck #1", expanded1, innerPt) + typecheck("whitebox typecheck #2", expanded2, outerPt) } } override def onDelayed(delayed: Tree) = { |