From 7babdab9ace07884ce844af923c93e0dcd49f7ea Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 9 Jan 2013 14:53:08 +0100 Subject: SI-6891 Fix value class + tailrec crasher. rhs.substituteSymbols(old, new) leaves us with: def loop#12225(x#12226: A#15491): scala#21.this.Unit#1615 = loop#12225(x#12226) In which the TermSymbol x#12226 has a stale info, pointing at the A#7274, the class type parameter, rather than A#15491, the corresponding type parameter of the synthetic backing method. I've improved `TreeSymSubstituter` to substitute not only `Tree#{tpe, symbol}`, but also `DefTree#sym.info`. The `pos` test that triggered the new code path are listed here: https://gist.github.com/4575687 AFAICS, no special treatment of Function, Return, or Import is needed in TreeSymSubstutor. --- src/reflect/scala/reflect/internal/Trees.scala | 16 ++++++++++++++++ test/files/pos/t6891.flags | 1 + test/files/pos/t6891.scala | 26 ++++++++++++++++++++++++++ test/pending/pos/t6891.flags | 1 - test/pending/pos/t6891.scala | 19 ------------------- 5 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 test/files/pos/t6891.flags create mode 100644 test/files/pos/t6891.scala delete mode 100644 test/pending/pos/t6891.flags delete mode 100644 test/pending/pos/t6891.scala diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 62998ef6cb..a528a9ced8 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1439,6 +1439,22 @@ trait Trees extends api.Trees { self: SymbolTable => if (tree.tpe ne null) tree.tpe = symSubst(tree.tpe) if (tree.hasSymbol) { subst(from, to) + tree match { + case _: DefTree => + val newInfo = symSubst(tree.symbol.info) + if (!(newInfo =:= tree.symbol.info)) { + debuglog(sm""" + |TreeSymSubstituter: updated info of symbol ${tree.symbol} + | Old: ${showRaw(tree.symbol.info, printTypes = true, printIds = true)} + | New: ${showRaw(newInfo, printTypes = true, printIds = true)}""") + tree.symbol updateInfo newInfo + } + case _ => + // no special handling is required for Function or Import nodes here. + // as they don't have interesting infos attached to their symbols. + // Subsitution of the referenced symbol of Return nodes is handled + // in .ChangeOwnerTraverser + } tree match { case Ident(name0) if tree.symbol != NoSymbol => treeCopy.Ident(tree, tree.symbol.name) diff --git a/test/files/pos/t6891.flags b/test/files/pos/t6891.flags new file mode 100644 index 0000000000..fe048006aa --- /dev/null +++ b/test/files/pos/t6891.flags @@ -0,0 +1 @@ +-Ycheck:extmethods -Xfatal-warnings \ No newline at end of file diff --git a/test/files/pos/t6891.scala b/test/files/pos/t6891.scala new file mode 100644 index 0000000000..bed2d0d777 --- /dev/null +++ b/test/files/pos/t6891.scala @@ -0,0 +1,26 @@ +object O { + implicit class Foo[A](val value: String) extends AnyVal { + def bippy() = { + @annotation.tailrec def loop(x: A): Unit = loop(x) + () + } + + def boppy() = { + @annotation.tailrec def loop(x: value.type): Unit = loop(x) + () + } + + def beppy[C](c: => C) = { + () => c + @annotation.tailrec def loop(x: value.type): Unit = loop(x) + () => c + () + } + } + // uncaught exception during compilation: Types$TypeError("type mismatch; + // found : A(in method bippy$extension) + // required: A(in class Foo)") @ scala.tools.nsc.typechecker.Contexts$Context.issueCommon(Contexts.scala:396) + // error: scala.reflect.internal.Types$TypeError: type mismatch; + // found : A(in method bippy$extension) + // required: A(in class Foo) +} diff --git a/test/pending/pos/t6891.flags b/test/pending/pos/t6891.flags deleted file mode 100644 index fe048006aa..0000000000 --- a/test/pending/pos/t6891.flags +++ /dev/null @@ -1 +0,0 @@ --Ycheck:extmethods -Xfatal-warnings \ No newline at end of file diff --git a/test/pending/pos/t6891.scala b/test/pending/pos/t6891.scala deleted file mode 100644 index bf79c2d293..0000000000 --- a/test/pending/pos/t6891.scala +++ /dev/null @@ -1,19 +0,0 @@ -object O { - implicit class Foo[A](val value: String) extends AnyVal { - def bippy() = { - @annotation.tailrec def loop(x: A): Unit = loop(x) - () - } - - def boppy() = { - @annotation.tailrec def loop(x: value.type): Unit = loop(x) - () - } - } - // uncaught exception during compilation: Types$TypeError("type mismatch; - // found : A(in method bippy$extension) - // required: A(in class Foo)") @ scala.tools.nsc.typechecker.Contexts$Context.issueCommon(Contexts.scala:396) - // error: scala.reflect.internal.Types$TypeError: type mismatch; - // found : A(in method bippy$extension) - // required: A(in class Foo) -} -- cgit v1.2.3