-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
110 additions
and
84 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
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
31 changes: 31 additions & 0 deletions
31
docs/_docs/reference/experimental/given-loop-prevention.md
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 @@ | ||
--- | ||
layout: doc-page | ||
title: Given Loop Prevention | ||
redirectFrom: /docs/reference/other-new-features/into-modifier.html | ||
nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/into-modifier.html | ||
--- | ||
|
||
Implicit resolution now avoids generating recursive givens that can lead to an infinite loop at runtime. Here is an example: | ||
|
||
```scala | ||
object Prices { | ||
opaque type Price = BigDecimal | ||
|
||
object Price{ | ||
given Ordering[Price] = summon[Ordering[BigDecimal]] // was error, now avoided | ||
} | ||
} | ||
``` | ||
|
||
Previously, implicit resolution would resolve the `summon` to the given in `Price`, leading to an infinite loop (a warning was issued in that case). We now use the underlying given in `BigDecimal` instead. We achieve that by adding the following rule for implicit search: | ||
|
||
- When doing an implicit search while checking the implementation of a `given` definition `G` of the form | ||
``` | ||
given ... = .... | ||
``` | ||
discard all search results that lead back to `G` or to a given with the same owner as `G` that comes later in the source than `G`. | ||
The new behavior is enabled with the `experimental.givenLoopPrevention` language import. If no such import or setting is given, a warning is issued where the behavior would change under that import (for source version 3.4 and later). | ||
Old-style implicit definitions are unaffected by this change. | ||
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 |
---|---|---|
@@ -1,25 +1,29 @@ | ||
-- Error: tests/neg/i15474.scala:6:39 ---------------------------------------------------------------------------------- | ||
6 | given c: Conversion[ String, Int ] = _.toInt // error | ||
| ^ | ||
| Warning: result of implicit search for ?{ toInt: ? } will change. | ||
| Current result Test2.c will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: augmentString. | ||
| To opt into the new rules, use the `experimental.avoidLoopingGivens` language import. | ||
| Result of implicit search for ?{ toInt: ? } will change. | ||
| Current result Test2.c will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: augmentString. | ||
| To opt into the new rules, use the `experimental.givenLoopPrevention` language import. | ||
| | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - rearrange definitions so that Test2.c comes earlier, | ||
| - use an explicit conversion, | ||
| - use an import to get extension method into scope. | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - use a `given ... with` clause as the enclosing given, | ||
| - rearrange definitions so that Test2.c comes earlier, | ||
| - use an explicit conversion, | ||
| - use an import to get extension method into scope. | ||
| This will be an error in Scala 3.5 and later. | ||
-- Error: tests/neg/i15474.scala:12:56 --------------------------------------------------------------------------------- | ||
12 | given Ordering[Price] = summon[Ordering[BigDecimal]] // error | ||
| ^ | ||
| Warning: result of implicit search for Ordering[BigDecimal] will change. | ||
| Current result Prices.Price.given_Ordering_Price will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: scala.math.Ordering.BigDecimal. | ||
| To opt into the new rules, use the `experimental.avoidLoopingGivens` language import. | ||
| Result of implicit search for Ordering[BigDecimal] will change. | ||
| Current result Prices.Price.given_Ordering_Price will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: scala.math.Ordering.BigDecimal. | ||
| To opt into the new rules, use the `experimental.givenLoopPrevention` language import. | ||
| | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - rearrange definitions so that Prices.Price.given_Ordering_Price comes earlier, | ||
| - use an explicit argument. | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - use a `given ... with` clause as the enclosing given, | ||
| - rearrange definitions so that Prices.Price.given_Ordering_Price comes earlier, | ||
| - use an explicit argument. | ||
| This will be an error in Scala 3.5 and later. |
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 |
---|---|---|
@@ -1,12 +1,14 @@ | ||
-- Error: tests/neg/i6716.scala:12:39 ---------------------------------------------------------------------------------- | ||
12 | given Monad[Bar] = summon[Monad[Foo]] // error | ||
| ^ | ||
| Warning: result of implicit search for Monad[Foo] will change. | ||
| Current result Bar.given_Monad_Bar will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: Foo.given_Monad_Foo. | ||
| To opt into the new rules, use the `experimental.avoidLoopingGivens` language import. | ||
| Result of implicit search for Monad[Foo] will change. | ||
| Current result Bar.given_Monad_Bar will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: Foo.given_Monad_Foo. | ||
| To opt into the new rules, use the `experimental.givenLoopPrevention` language import. | ||
| | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - rearrange definitions so that Bar.given_Monad_Bar comes earlier, | ||
| - use an explicit argument. | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - use a `given ... with` clause as the enclosing given, | ||
| - rearrange definitions so that Bar.given_Monad_Bar comes earlier, | ||
| - use an explicit argument. | ||
| This will be an error in Scala 3.5 and later. |
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 |
---|---|---|
@@ -1,23 +1,25 @@ | ||
-- Error: tests/neg/i7294-a.scala:6:10 --------------------------------------------------------------------------------- | ||
6 | case x: T => x.g(10) // error // error | ||
-- [E007] Type Mismatch Error: tests/neg/i7294-a.scala:8:18 ------------------------------------------------------------ | ||
8 | case x: T => x.g(10) // error // error | ||
| ^^^^^^^ | ||
| Found: Any | ||
| Required: T | ||
| | ||
| where: T is a type in given instance f with bounds <: foo.Foo | ||
| | ||
| longer explanation available when compiling with `-explain` | ||
-- Error: tests/neg/i7294-a.scala:8:10 --------------------------------------------------------------------------------- | ||
8 | case x: T => x.g(10) // error // error | ||
| ^ | ||
| Warning: result of implicit search for scala.reflect.TypeTest[Nothing, T] will change. | ||
| Result of implicit search for scala.reflect.TypeTest[Nothing, T] will change. | ||
| Current result foo.i7294-a$package.f will be no longer eligible | ||
| because it is not defined before the search position. | ||
| Result with new rules: No Matching Implicit. | ||
| To opt into the new rules, use the `experimental.avoidLoopingGivens` language import. | ||
| To opt into the new rules, use the `experimental.givenLoopPrevention` language import. | ||
| | ||
| To fix the problem without the language import, you could try one of the following: | ||
| - use a `given ... with` clause as the enclosing given, | ||
| - rearrange definitions so that foo.i7294-a$package.f comes earlier, | ||
| - use an explicit argument. | ||
| This will be an error in Scala 3.5 and later. | ||
| | ||
| where: T is a type in given instance f with bounds <: foo.Foo | ||
-- [E007] Type Mismatch Error: tests/neg/i7294-a.scala:6:18 ------------------------------------------------------------ | ||
6 | case x: T => x.g(10) // error // error | ||
| ^^^^^^^ | ||
| Found: Any | ||
| Required: T | ||
| | ||
| where: T is a type in given instance f with bounds <: foo.Foo | ||
| | ||
| longer explanation available when compiling with `-explain` |
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 |
---|---|---|
@@ -1,3 +1,5 @@ | ||
//> using options -Xfatal-warnings | ||
|
||
package foo | ||
|
||
trait Foo { def g(x: Int): Any } | ||
|
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 |
---|---|---|
@@ -1,3 +1,5 @@ | ||
//> using options -Xfatal-warnings | ||
|
||
package foo | ||
|
||
trait Foo { def g(x: Any): Any } | ||
|
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 |
---|---|---|
@@ -1,3 +1,5 @@ | ||
//> using options -Xfatal-warnings | ||
|
||
class A | ||
class B | ||
|
||
|
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