forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix scala#16405 - wildcards prematurely resolving to Nothing
This was a problem because it could it get in the way of some metaprogramming techniques. The main issue was the fact that when typing functions, the type inference would first look at the types from the source method (resolving type wildcards to Nothing) and only after that, it could look at the target method. Now, in the case of wildcards we delay the resolution from the source method until later, after which it is resolved according to the target method. We also modify the targettype resolution method a bit, as just applying the above procedure would fail some of the tests, eg. val y1: Function1[_, Nothing] = x => x would be typed as Function1[Any, Nothing], which was incorrect.
- Loading branch information
Showing
3 changed files
with
53 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import scala.compiletime.summonInline | ||
|
||
case class TypeDesc[T](tpe: String) | ||
object TypeDesc { | ||
given nothing: TypeDesc[Nothing] = TypeDesc("Nothing") | ||
given string: TypeDesc[String] = TypeDesc("String") | ||
given int: TypeDesc[Int] = TypeDesc("Int") | ||
} | ||
|
||
def exampleFn(s: String, i: Int): Unit = () | ||
|
||
inline def argumentTypesOf[R](fun: (_, _) => R): (TypeDesc[?], TypeDesc[?]) = { | ||
inline fun match { | ||
case x: ((a, b) => R) => | ||
(scala.compiletime.summonInline[TypeDesc[a]], scala.compiletime.summonInline[TypeDesc[b]]) | ||
} | ||
} | ||
inline def argumentTypesOfNoWildCard[A, B, R](fun: (A, B) => R): (TypeDesc[?], TypeDesc[?]) = argumentTypesOf(fun) | ||
inline def argumentTypesOfAllWildCard(fun: (?, ?) => ?): (TypeDesc[?], TypeDesc[?]) = argumentTypesOf(fun) | ||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
val expected = (TypeDesc.string, TypeDesc.int) | ||
assert(argumentTypesOf(exampleFn) == expected) | ||
assert(argumentTypesOf(exampleFn(_, _)) == expected) | ||
assert(argumentTypesOfNoWildCard(exampleFn) == expected) | ||
assert(argumentTypesOfNoWildCard(exampleFn(_, _)) == expected) | ||
assert(argumentTypesOfAllWildCard(exampleFn) == expected) | ||
assert(argumentTypesOfAllWildCard(exampleFn(_, _)) == expected) | ||
} | ||
} |