Skip to content

Take expected type into account when typing a sequence argument #8669

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 13, 2020

Conversation

smarter
Copy link
Member

@smarter smarter commented Apr 5, 2020

No description provided.

smarter added a commit to lampepfl/xml-interpolator that referenced this pull request Apr 5, 2020
Implicit conversions are not normally applied when splicing, it happened
to work in this particular case before
scala/scala3#8669 because of the peculiar way
in which we typed repeated arguments.
@smarter smarter force-pushed the repeated-expected branch from a6c7300 to 917bc6a Compare April 5, 2020 14:52
@smarter smarter force-pushed the repeated-expected branch 2 times, most recently from 122f045 to 82fb3d2 Compare April 7, 2020 16:25
@smarter smarter changed the title [WIP] Take expected type into account when typing a sequence argument Take expected type into account when typing a sequence argument Apr 7, 2020
@smarter smarter marked this pull request as ready for review April 7, 2020 16:26
@smarter smarter force-pushed the repeated-expected branch from 82fb3d2 to b122756 Compare April 7, 2020 16:48
@smarter smarter requested a review from odersky April 7, 2020 17:03
@smarter smarter force-pushed the repeated-expected branch 2 times, most recently from 8061f6f to d42ca2e Compare April 7, 2020 20:26
@smarter
Copy link
Member Author

smarter commented Apr 7, 2020

Hmmph, somehow this is causing scalatest to get stuck in an infinite loop, I'll investigate.

@smarter smarter assigned smarter and unassigned odersky Apr 7, 2020
@smarter smarter removed the request for review from odersky April 7, 2020 23:11
@smarter smarter force-pushed the repeated-expected branch from d42ca2e to 6fbcc17 Compare April 8, 2020 10:39
@smarter
Copy link
Member Author

smarter commented Apr 8, 2020

I'll investigate.

Fixed. I had written if somewhere instead of else if :).

@smarter smarter requested a review from odersky April 8, 2020 11:24
@smarter smarter assigned odersky and unassigned smarter Apr 8, 2020
val expr1 = typedExpr(tree.expr, ptArg)
val fromCls = if expr1.tpe.derivesFrom(defn.ArrayClass) then defn.ArrayClass else defn.SeqClass
val tpt1 = TypeTree(expr1.tpe.widen.translateToRepeated(fromCls)).withSpan(tree.tpt.span)
assignType(cpy.Typed(tree)(expr1, tpt1), tpt1)
Copy link
Contributor

Choose a reason for hiding this comment

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

nice!

@odersky odersky assigned smarter and unassigned odersky Apr 13, 2020
The previous name was slightly misleading: we can pass Array sequence arguments
to Scala methods and Seq sequence argument to Java methods, so we may
want to translate a repeated parameter type to either an Array or a Seq
irrespective of what it erases to (we don't right now but we will in
the next commit).
@smarter smarter force-pushed the repeated-expected branch from 6fbcc17 to f01f307 Compare April 13, 2020 18:33
smarter added 2 commits April 13, 2020 21:55
Given an expected type `*T`, we allow a sequence argument `xs: _*` to be
either a `Seq[T]` or an `Array[_ <: T]`, irrespective of whether the
method we're calling is a Java or Scala method. So far we typed sequence
arguments without an expected type, meaning that adaptation did not take
place. But thanks to scala#8635, we can type them with an expected type of
`Seq[T] | Array[_ <: T]` and type inference works out. This is what this
commit does.
I don't know of a case where this matters currently but it's more correct.
@smarter smarter force-pushed the repeated-expected branch from f01f307 to 03d5d9b Compare April 13, 2020 19:56
@smarter smarter merged commit 4356d70 into scala:master Apr 13, 2020
@smarter smarter deleted the repeated-expected branch April 13, 2020 20:38
smarter added a commit to dotty-staging/dotty that referenced this pull request Apr 13, 2020
A Java generic array `T[]` is unpickled in ClassfileParser to `Array[T &
Object]`, because it will not accept primitive arrays. However, Java
varargs were special-cased to drop this intersection. Erasure contained
some code to compensate for this, but this is still unsound and lead to
tests/run/t1360.scala failing with a ClassCastException.

Thanks to scala#8669 we can drop this special-casing of varargs without
affecting typing too much: it's still possible to pass `Array(1, 2): _*`
where `(T & Object)*` is expected because adaptation will take care of
boxing.

One test case had to be adapted, I replaced:

    def apply[X](xs : X*): java.util.List[X]
      java.util.Arrays.asList(xs: _*)

with:

    def apply[X <: AnyRef](xs : X*): java.util.List[X] =
      java.util.Arrays.asList(xs: _*)

I don't think that's too constraining.

Note: after this commit, tests/run/i533 started failing, this is fixed
in the next commit.
smarter added a commit to dotty-staging/dotty that referenced this pull request Apr 13, 2020
A Java generic array `T[]` is unpickled in ClassfileParser to `Array[T &
Object]`, because it will not accept primitive arrays. However, Java
varargs were special-cased to drop this intersection. Erasure contained
some code to compensate for this, but this is still unsound and lead to
tests/run/t1360.scala failing with a ClassCastException.

Thanks to scala#8669 we can drop this special-casing of varargs without
affecting typing too much: it's still possible to pass `Array(1, 2): _*`
where `(T & Object)*` is expected because adaptation will take care of
boxing.

One test case had to be adapted, I replaced:

    def apply[X](xs : X*): java.util.List[X]
      java.util.Arrays.asList(xs: _*)

with:

    def apply[X <: AnyRef](xs : X*): java.util.List[X] =
      java.util.Arrays.asList(xs: _*)

I don't think that's too constraining.

Note: after this commit, tests/run/i533 started failing, this is fixed
in the next commit.
smarter added a commit to dotty-staging/dotty that referenced this pull request May 18, 2020
A Java generic array `T[]` is unpickled in ClassfileParser to `Array[T &
Object]`, because it will not accept primitive arrays. However, Java
varargs were special-cased to drop this intersection. Erasure contained
some code to compensate for this, but this is still unsound and lead to
tests/run/t1360.scala failing with a ClassCastException.

Thanks to scala#8669 we can drop this special-casing of varargs without
affecting typing too much: it's still possible to pass `Array(1, 2): _*`
where `(T & Object)*` is expected because adaptation will take care of
boxing.

One test case had to be adapted, I replaced:

    def apply[X](xs : X*): java.util.List[X]
      java.util.Arrays.asList(xs: _*)

with:

    def apply[X <: AnyRef](xs : X*): java.util.List[X] =
      java.util.Arrays.asList(xs: _*)

I don't think that's too constraining.

Note: after this commit, tests/run/i533 started failing, this is fixed
in the next commit.
rethab pushed a commit to rethab/dotty that referenced this pull request May 27, 2020
A Java generic array `T[]` is unpickled in ClassfileParser to `Array[T &
Object]`, because it will not accept primitive arrays. However, Java
varargs were special-cased to drop this intersection. Erasure contained
some code to compensate for this, but this is still unsound and lead to
tests/run/t1360.scala failing with a ClassCastException.

Thanks to scala#8669 we can drop this special-casing of varargs without
affecting typing too much: it's still possible to pass `Array(1, 2): _*`
where `(T & Object)*` is expected because adaptation will take care of
boxing.

One test case had to be adapted, I replaced:

    def apply[X](xs : X*): java.util.List[X]
      java.util.Arrays.asList(xs: _*)

with:

    def apply[X <: AnyRef](xs : X*): java.util.List[X] =
      java.util.Arrays.asList(xs: _*)

I don't think that's too constraining.

Note: after this commit, tests/run/i533 started failing, this is fixed
in the next commit.
odersky pushed a commit to lampepfl/xml-interpolator that referenced this pull request May 29, 2020
Implicit conversions are not normally applied when splicing, it happened
to work in this particular case before
scala/scala3#8669 because of the peculiar way
in which we typed repeated arguments.
gorilskij pushed a commit to gorilskij/xml-interpolator that referenced this pull request Jun 13, 2022
Implicit conversions are not normally applied when splicing, it happened
to work in this particular case before
scala/scala3#8669 because of the peculiar way
in which we typed repeated arguments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants