Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ private[tasties] class TreeUnpickler private (
val simpleName = tpe match
case tpe: PackageRef => tpe.fullyQualifiedName.simpleName
case tpe: TermRef => extractUnsignedName(tpe.name) // fallback for incomplete or invalid programs
Ident(simpleName)(tpe)(span)
Ident(simpleName)(tpe)(spn)
case TERMREFdirect =>
val spn = span
reader.readByte()
Expand Down Expand Up @@ -1699,7 +1699,8 @@ private[tasties] class TreeUnpickler private (
case tag if isTypeTreeTag(tag) =>
throw TastyFormatException(s"Unexpected type tree tag ${astTagToString(tag)} $posErrorMsg")
case _ =>
TypeWrapper(readNonEmptyPrefix())(span)
val spn = span
TypeWrapper(readNonEmptyPrefix())(spn)
}

private def readInlinedCaller(end: Addr)(using SourceFile): Option[TypeIdent | SelectTypeTree] =
Expand Down
38 changes: 31 additions & 7 deletions tasty-query/shared/src/test/scala/tastyquery/PositionSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,37 @@ class PositionSuite extends RestrictedUnpicklingSuite {
assertEquals(collectCode[TypeApply](tree), List("Seq", "Seq[Int]", "A[Int, Seq[String]]"))
}

testUnpickle("inferred-type-arg", "simple_trees.InferredTypeArgs") { tree =>
/*
* The inferred `Int` type argument in `id(42)` is encoded as a non-tree-tagged type (a `TYPEREF`). When tasty-query
* reads it, it must capture `span` before consuming the type bytes, otherwise the resulting `TypeWrapper` gets the
* position of whatever node comes next.
*/
val idName = termName("id")
val typeApply = findTree(tree) {
case typeApply @ TypeApply(Select(_, SignedName(`idName`, _, _)), _) => typeApply
case typeApply @ TypeApply(Select(_, `idName`), _) => typeApply
}

val typeArg = typeApply.args match {
case (typeWrapper: TypeWrapper) :: Nil => typeWrapper
case other => fail(s"expected a single TypeWrapper, got: $other")
}

assertEquals(posToCode(typeArg.pos), Some("id"))
}

testUnpickle("package-ref-ident", "simple_trees.PackageRefIdent") { tree =>
/*
* The leading `scala` in `scala.Predef.identity(1)` is an `Ident` with a `TermRef` type pickled as TERMREFpkg. The
* unpickler must use the span captured before `readPackageRef` advances the reader, otherwise the `Ident` inherits
* the position of the next entry.
*/
val scalaIdentifier = findTree(tree) { case identifier @ Ident(SimpleName("scala")) => identifier }

assertEquals(posToCode(scalaIdentifier.pos), Some("scala"))
}

testUnpickle("type-ident", "simple_trees.Typed") { tree =>
assertEquals(collectCode[TypeIdent](tree), List("Int"))
}
Expand Down Expand Up @@ -369,12 +400,6 @@ class PositionSuite extends RestrictedUnpicklingSuite {
collectCode[TypeDefinitionTree](tree),
List(
"Int",
/* The following makes no sense; it is the position of the type def
* of `type AbstractType`. It's probably dotc's auto-assigning of
* positions that goes wild.
*/
"""type AbstractType
| type AbstractWithBounds >: Null <: Product""".stripMargin,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it suspicious that this item disappears, instead of being fixed. Same thing below. Could you explain why that happens?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's because of the !pos.isZeroExtent check here:
https://github.com/scalacenter/tasty-query/blob/main/tasty-query/shared/src/test/scala/tastyquery/PositionSuite.scala#L27

The type has no bounds, so the returned string is empty. If I remove that check, I get this error:

==> X tastyquery.PositionSuite.type-definition-tree-1  0.011s munit.ComparisonFailException: /home/jpeterson/lucid/tasty-query/tasty-query/shared/src/test/scala/tastyquery/PositionSuite.scala:404
403:      )
404:    )
405:  }
values are not the same
=> Obtained
List(
  "Int",
  "",
  ">: Null <: Product",
  "Int",
  "Null <: Product = Null",
  "Null <: Product"
)
=> Diff (- obtained, + expected)
   "Int",
-  "",
   ">: Null <: Product",
    at munit.Assertions.failComparison(Assertions.scala:278)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah that makes sense.

">: Null <: Product",
"Int",
"Null <: Product = Null",
Expand All @@ -388,7 +413,6 @@ class PositionSuite extends RestrictedUnpicklingSuite {
collectCode[TypeDefinitionTree](tree),
List(
"[X] =>> List[X]",
"X] =>> List[X]", // TODO Improve this
"List[X]"
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package simple_trees

class InferredTypeArgs {
def id[T](x: T): T = x

val a = id(42)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package simple_trees

class PackageRefIdent {
val x = scala.Predef.identity(1)
}
Loading