diff options
author | Uladzimir Abramchuk <u.abramchuk@gmail.com> | 2013-02-05 20:17:23 +0300 |
---|---|---|
committer | Uladzimir Abramchuk <u.abramchuk@gmail.com> | 2013-02-16 17:00:46 +0300 |
commit | 9d5d55bdf4e36489c249fe9736d53c8d12a9d7e5 (patch) | |
tree | b26f68cefe1a119bc5898d09eda7a39bbba31a43 /test | |
parent | 466fc670a38836dfb81d75f72d46ddcaa12bc3bb (diff) | |
download | scala-9d5d55bdf4e36489c249fe9736d53c8d12a9d7e5.tar.gz scala-9d5d55bdf4e36489c249fe9736d53c8d12a9d7e5.tar.bz2 scala-9d5d55bdf4e36489c249fe9736d53c8d12a9d7e5.zip |
SI-5744 evidence params are now SYNTHETIC
The macro def <-> macro impl correspondence check compares names of the
corresponding parameters in def and impl and reports an error if they
don't match. This was originally designed to avoid confusion w.r.t named
arguments (which ended up being never implemented as described in SI-5920).
Sometimes parameter names are generated by the compiler, which puts the
user in a tough position. Luckily, there's an escape hatch built it, which
omits the name correspondence check if one of the parameters is SYNTHETIC.
Everything went well until we realized that evidences generated by
context bounds aren't SYNTHETIC, which led to the bug at hand.
Marking auto-generated evidence parameters SYNTHETIC was only the first
step, as the correspondence checker uses parameter symbols, not parameter
trees. Why's that a problem? Because SYNTHETIC doesn't get propagated from def
trees to their underlying symbols (see ValueParameterFlags).
Unfortunately one cannot just change ValueParameterFlags, because that
would break printouts generated in TypeDiagnostics, which is designed to not
print synthetic symbols. Thus we modify methodTypeErrorString in
TypeDiagnostics to always print synthetic symbols.
Therefore now we propagate all paramSym.flags when doing correspondent sweeps
to keep them in sync between def trees and their underlying symbols. This
fixes the problem.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/pos/t5744/Macros_1.scala | 22 | ||||
-rw-r--r-- | test/files/pos/t5744/Test_2.scala | 6 |
2 files changed, 28 insertions, 0 deletions
diff --git a/test/files/pos/t5744/Macros_1.scala b/test/files/pos/t5744/Macros_1.scala new file mode 100644 index 0000000000..288a88653d --- /dev/null +++ b/test/files/pos/t5744/Macros_1.scala @@ -0,0 +1,22 @@ +import scala.language.experimental.macros +import scala.reflect.macros.Context + +object Macros { + def foo[U: Numeric](x: U) = macro foo_impl[U] + def bar[U: Numeric : Equiv, Y <% String](x: U)(implicit s: String) = macro bar_impl[U, Y] + + def foo_impl[U](c: Context)(x: c.Expr[U])(numeric: c.Expr[Numeric[U]]) = { + import c.universe._ + val plusOne = Apply(Select(numeric.tree, newTermName("plus")), List(x.tree, Literal(Constant(1)))) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(plusOne)) + c.Expr[Unit](body) + } + + def bar_impl[U, Y](c: Context)(x: c.Expr[U])(numeric: c.Expr[Numeric[U]], equiv: c.Expr[Equiv[U]], viewAsString: c.Expr[Y => String], s: c.Expr[String]) = { + import c.universe._ + val plusOne = Apply(Select(numeric.tree, newTermName("plus")), List(x.tree, Literal(Constant(1)))) + val plusLen = Apply(Select(numeric.tree, newTermName("plus")), List(plusOne, Select(s.tree, newTermName("length")))) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(plusLen)) + c.Expr[Unit](body) + } +}
\ No newline at end of file diff --git a/test/files/pos/t5744/Test_2.scala b/test/files/pos/t5744/Test_2.scala new file mode 100644 index 0000000000..64b57e6032 --- /dev/null +++ b/test/files/pos/t5744/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import Macros._ + foo(42) + implicit val s = "" + bar(43) +}
\ No newline at end of file |