forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Select local implicits over name-imported over wildcard imported (sca…
- Loading branch information
Showing
6 changed files
with
354 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// scalac: -source:3.0-migration | ||
|
||
// A not-fully-minimal reproduction of the CI failure in http4s | ||
// While implementing the fix to name "shadowing" in implicit lookup. | ||
|
||
import scala.util.control.NoStackTrace | ||
|
||
final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { | ||
def semiflatMap[D](f: B => F[D])(implicit F: Monad[F]): EitherT[F, A, D] = ??? | ||
} | ||
|
||
trait Applicative[F[_]] { | ||
def pure[A](x: A): F[A] | ||
} | ||
trait Monad[F[_]] extends Applicative[F] | ||
trait Async[F[_]] extends Monad[F] | ||
|
||
final class Request[+F[_]] | ||
|
||
final case class RequestCookie(name: String, content: String) | ||
|
||
final class CSRF2[F[_], G[_]](implicit F: Async[F]) { self => | ||
import CSRF2._ | ||
|
||
def signToken[M[_]](rawToken: String)(implicit F: Async[M]): M[CSRFToken] = ??? | ||
|
||
def refreshedToken[M[_]](implicit F: Async[M]): EitherT[M, CSRFCheckFailed, CSRFToken] = | ||
EitherT(extractRaw("")).semiflatMap(signToken[M]) | ||
|
||
def extractRaw[M[_]: Async](rawToken: String): M[Either[CSRFCheckFailed, String]] = ??? | ||
} | ||
|
||
object CSRF2 { | ||
type CSRFToken | ||
|
||
case object CSRFCheckFailed extends Exception("CSRF Check failed") with NoStackTrace | ||
type CSRFCheckFailed = CSRFCheckFailed.type | ||
} |
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,17 @@ | ||
// A minimised reproduction of how an initial change to combineEligibles broke Typer#findRef | ||
case class Foo(n: Int) | ||
|
||
class Test: | ||
import this.toString | ||
|
||
val foo1 = Foo(1) | ||
val foo2 = Foo(2) | ||
|
||
def foo(using Foo): Foo = | ||
import this.* | ||
def bar(using Foo): Foo = summon[Foo] | ||
bar(using foo2) | ||
|
||
object Test extends Test: | ||
def main(args: Array[String]): Unit = | ||
assert(foo(using foo1) eq foo2) |
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,93 @@ | ||
case class Foo(n: Int) | ||
|
||
class Bar(n: Int): | ||
given foo: Foo = new Foo(n) | ||
|
||
class InMethod: | ||
def wild(bar: Bar): Unit = | ||
import bar.* | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def givenWild(bar: Bar): Unit = | ||
import bar.{ given, * } | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def givn(bar: Bar): Unit = | ||
import bar.given | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def givenFoo(bar: Bar): Unit = | ||
import bar.given Foo | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def named(bar: Bar): Unit = | ||
import bar.foo | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def namedGivenWild(bar: Bar, bar2: Bar): Unit = | ||
import bar.foo, bar2.{ given, * } | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def givenWildNamed(bar: Bar, bar2: Bar): Unit = | ||
import bar2.{ given, * }, bar.foo | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def namedWild(bar: Bar, bar2: Bar): Unit = | ||
import bar.foo, bar2.* | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def wildNamed(bar: Bar, bar2: Bar): Unit = | ||
import bar2.*, bar.foo | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
class InClassWild(bar: Bar): | ||
import bar.* | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class InClassGivenWild(bar: Bar): | ||
import bar.{ given, * } | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class InClassGiven(bar: Bar): | ||
import bar.given | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class InClassGivenFoo(bar: Bar): | ||
import bar.given Foo | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class InClassNamed(bar: Bar): | ||
import bar.foo | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val bar = new Bar(1) | ||
val bar2 = new Bar(2) | ||
|
||
new InMethod().wild(bar) | ||
new InMethod().givenWild(bar) // was: error | ||
new InMethod().givn(bar) // was: error | ||
new InMethod().givenFoo(bar) // was: error | ||
new InMethod().named(bar) // was: error | ||
|
||
new InMethod().namedWild(bar, bar2) | ||
new InMethod().wildNamed(bar, bar2) | ||
new InMethod().namedGivenWild(bar, bar2) // was: error | ||
new InMethod().givenWildNamed(bar, bar2) | ||
|
||
new InClassWild(bar) | ||
new InClassGivenWild(bar) // was: error | ||
new InClassGiven(bar) // was: error | ||
new InClassGivenFoo(bar) // was: error | ||
new InClassNamed(bar) // was: error |
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,141 @@ | ||
case class Foo(n: Int) | ||
|
||
class OldBar(n: Int): | ||
implicit val foo: Foo = new Foo(n) | ||
|
||
class NewBar(n: Int): | ||
given foo: Foo = new Foo(n) | ||
|
||
class OldInMethod: | ||
def wild(bar: OldBar): Unit = | ||
import bar.* | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def named(bar: OldBar): Unit = | ||
import bar.foo | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def namedWild(bar: OldBar, bar2: NewBar): Unit = | ||
import bar.foo, bar2.* | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def wildNamed(bar: OldBar, bar2: NewBar): Unit = | ||
import bar2.*, bar.foo | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def namedGivenWild(bar: OldBar, bar2: NewBar): Unit = | ||
import bar.foo | ||
import bar2.{ given, * } | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def givenWildNamed(bar: OldBar, bar2: NewBar): Unit = | ||
import bar2.{ given, * }, bar.foo | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
class OldInClassWild(bar: OldBar): | ||
import bar.* | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class OldInClassNamed(bar: OldBar): | ||
import bar.foo | ||
given foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
|
||
class NewInMethod: | ||
def givenWild(bar: NewBar): Unit = | ||
import bar.{ given, * } | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def wild(bar: NewBar): Unit = | ||
import bar.* | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def givn(bar: NewBar): Unit = | ||
import bar.given | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def givenFoo(bar: NewBar): Unit = | ||
import bar.given Foo | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def named(bar: NewBar): Unit = | ||
import bar.foo | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
def namedWild(bar: NewBar, bar2: OldBar): Unit = | ||
import bar.foo, bar2.* | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
def wildNamed(bar: NewBar, bar2: OldBar): Unit = | ||
import bar2.*, bar.foo | ||
assert(bar.foo eq summon[Foo]) | ||
|
||
class NewInClassGivenWild(bar: NewBar): | ||
import bar.{ given, * } | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class NewInClassWild(bar: NewBar): | ||
import bar.* | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class NewInClassGiven(bar: NewBar): | ||
import bar.given | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class NewInClassGivenFoo(bar: NewBar): | ||
import bar.given Foo | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
class NewInClassNamed(bar: NewBar): | ||
import bar.foo | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq summon[Foo]) | ||
|
||
|
||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val oldBar = new OldBar(1) | ||
val newBar = new NewBar(1) | ||
val oldBar2 = new OldBar(2) | ||
val newBar2 = new NewBar(2) | ||
|
||
|
||
new OldInMethod().wild(oldBar) // was: error | ||
new OldInMethod().named(oldBar) // was: error | ||
|
||
new OldInMethod().namedWild(oldBar, newBar2) | ||
new OldInMethod().wildNamed(oldBar, newBar2) | ||
new OldInMethod().namedGivenWild(oldBar, newBar2) // was: error | ||
new OldInMethod().givenWildNamed(oldBar, newBar2) | ||
|
||
new OldInClassWild(oldBar) // was: error | ||
new OldInClassNamed(oldBar) // was: error | ||
|
||
|
||
new NewInMethod().wild(newBar) | ||
new NewInMethod().givenWild(newBar) // was: error | ||
new NewInMethod().givn(newBar) // was: error | ||
new NewInMethod().givenFoo(newBar) // was: error | ||
new NewInMethod().named(newBar) // was: error | ||
|
||
new NewInMethod().namedWild(newBar, oldBar2) // was: error | ||
new NewInMethod().wildNamed(newBar, oldBar2) | ||
|
||
new NewInClassWild(newBar) | ||
new NewInClassGivenWild(newBar) // was: error | ||
new NewInClassGiven(newBar) // was: error | ||
new NewInClassGivenFoo(newBar) // was: error | ||
new NewInClassNamed(newBar) // was: error |
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,49 @@ | ||
case class Foo(n: Int) | ||
|
||
class Bar(n: Int): | ||
implicit val foo: Foo = new Foo(n) | ||
|
||
class InMethod: | ||
def wild(bar: Bar): Unit = | ||
import bar._ | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq implicitly[Foo]) | ||
|
||
def named(bar: Bar): Unit = | ||
import bar.foo | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq implicitly[Foo]) | ||
|
||
def namedWild(bar: Bar, bar2: Bar): Unit = | ||
import bar.foo | ||
import bar2._ | ||
assert(bar.foo eq implicitly[Foo]) | ||
|
||
def wildNamed(bar: Bar, bar2: Bar): Unit = | ||
import bar2._ | ||
import bar.foo | ||
assert(bar.foo eq implicitly[Foo]) | ||
|
||
class InClassWild(bar: Bar): | ||
import bar._ | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq implicitly[Foo]) | ||
|
||
class InClassNamed(bar: Bar): | ||
import bar.foo | ||
implicit val foo: Foo = new Foo(2) | ||
assert(foo eq implicitly[Foo]) | ||
|
||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val bar = new Bar(1) | ||
val bar2 = new Bar(2) | ||
|
||
new InMethod().wild(bar) // was: error | ||
new InMethod().named(bar) // was: error | ||
|
||
new InMethod().namedWild(bar, bar2) // was: error | ||
new InMethod().wildNamed(bar, bar2) | ||
|
||
new InClassWild(bar) // was: error | ||
new InClassNamed(bar) // was: error |