Skip to content

Commit 4ee6119

Browse files
committed
Fix #4558: Avoid annotating ExprTypes
Annotations should apply only to value types, need to dereference first if we have an ExprType or a TermRef resolving to an ExprType.
1 parent b3d3b33 commit 4ee6119

File tree

5 files changed

+22
-3
lines changed

5 files changed

+22
-3
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,16 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
854854
else Assign(tree, rhs)
855855
}
856856

857+
/** tree @annot
858+
*
859+
* works differently for type trees and term trees
860+
*/
861+
def annotated(annot: Tree)(implicit ctx: Context): Tree =
862+
if (tree.isTerm)
863+
Typed(tree, TypeTree(AnnotatedType(tree.tpe.widenIfUnstable, Annotation(annot))))
864+
else
865+
Annotated(tree, annot)
866+
857867
/** A synthetic select with that will be turned into an outer path by ExplicitOuter.
858868
* @param levels How many outer levels to select
859869
* @param tp The type of the destination of the outer path.

compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class ExpandSAMs extends MiniPhase {
8888
Bind(defaultSym, Underscore(selectorTpe)),
8989
EmptyTree,
9090
defaultValue)
91-
val unchecked = Annotated(selector, New(ref(defn.UncheckedAnnotType)))
91+
val unchecked = selector.annotated(New(ref(defn.UncheckedAnnotType)))
9292
cpy.Match(tree)(unchecked, cases :+ defaultCase)
9393
.subst(param.symbol :: Nil, pfParam :: Nil)
9494
// Needed because a partial function can be written as:

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,10 @@ trait TypeAssigner {
546546
def assignType(tree: untpd.Import, sym: Symbol)(implicit ctx: Context) =
547547
tree.withType(sym.termRef)
548548

549-
def assignType(tree: untpd.Annotated, arg: Tree, annot: Tree)(implicit ctx: Context) =
549+
def assignType(tree: untpd.Annotated, arg: Tree, annot: Tree)(implicit ctx: Context) = {
550+
assert(tree.isType) // annotating a term is done via a Typed node, can't use Annotate directly
550551
tree.withType(AnnotatedType(arg.tpe, Annotation(annot)))
552+
}
551553

552554
def assignType(tree: untpd.PackageDef, pid: Tree)(implicit ctx: Context) =
553555
tree.withType(pid.symbol.termRef)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1658,7 +1658,7 @@ class Typer extends Namer
16581658
if (ctx.mode is Mode.Type)
16591659
assignType(cpy.Annotated(tree)(arg1, annot1), arg1, annot1)
16601660
else {
1661-
val tpt = TypeTree(AnnotatedType(arg1.tpe, Annotation(annot1)))
1661+
val tpt = TypeTree(AnnotatedType(arg1.tpe.widenIfUnstable, Annotation(annot1)))
16621662
assignType(cpy.Typed(tree)(arg1, tpt), tpt)
16631663
}
16641664
}

tests/run/i4558.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Foo {
2+
def f(z: => (Int, String)) = {
3+
val (x, y) = z
4+
}
5+
}
6+
7+
object Test { def main(args: Array[String]): Unit = { Foo.f { (1, "a") } } }

0 commit comments

Comments
 (0)