Skip to content

Commit ad29d1b

Browse files
oderskynoti0na1
authored andcommitted
Reinstantiate restriction to transparent inline methods
Reverts parts of #19922. Fixes #20342, #20297 The logic that we should ignore declared result types of inline methods really only applies to transparent inlines.
1 parent 4dffcc9 commit ad29d1b

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Constants.*
1111
import util.{Stats, SimpleIdentityMap, SimpleIdentitySet}
1212
import Decorators.*
1313
import Uniques.*
14-
import Flags.Method
14+
import Flags.{Method, Transparent}
1515
import inlines.Inlines
1616
import config.Printers.typr
1717
import Inferencing.*
@@ -108,7 +108,7 @@ object ProtoTypes {
108108
res
109109

110110
/** Constrain result with two special cases:
111-
* 1. If `meth` is an inlineable method in an inlineable context,
111+
* 1. If `meth` is a transparent inlineable method in an inlineable context,
112112
* we should always succeed and not constrain type parameters in the expected type,
113113
* because the actual return type can be a subtype of the currently known return type.
114114
* However, we should constrain parameters of the declared return type. This distinction is
@@ -128,11 +128,12 @@ object ProtoTypes {
128128
case _ =>
129129
false
130130

131-
if Inlines.isInlineable(meth) then
131+
if Inlines.isInlineable(meth) && meth.is(Transparent) then
132132
constrainResult(mt, wildApprox(pt))
133133
true
134134
else
135135
constFoldException(pt) || constrainResult(mt, pt)
136+
136137
end constrainResult
137138
end Compatibility
138139

tests/neg/i18123.check

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- [E172] Type Error: tests/neg/i18123.scala:25:33 ---------------------------------------------------------------------
2+
25 | (charClassIntersection.rep() | classItem.rep()) // error
3+
| ^^^^^^^^^^^^^^^
4+
|No given instance of type pkg.Implicits.Repeater[pkg.RegexTree, V] was found.
5+
|I found:
6+
|
7+
| pkg.Implicits.Repeater.GenericRepeaterImplicit[T]
8+
|
9+
|But method GenericRepeaterImplicit in object Repeater does not match type pkg.Implicits.Repeater[pkg.RegexTree, V]
10+
|
11+
|where: V is a type variable with constraint <: Seq[pkg.CharClassIntersection]
12+
|.

tests/neg/i18123.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// may not compile anymore in Scala 3.4+
2+
package pkg
3+
4+
trait P[+T]
5+
6+
extension [T](inline parse0: P[T])
7+
inline def | [V >: T](inline other: P[V]): P[V] = ???
8+
9+
extension [T](inline parse0: => P[T])
10+
inline def rep[V](inline min: Int = 0)(using repeater: Implicits.Repeater[T, V]): P[V] = ???
11+
12+
object Implicits:
13+
trait Repeater[-T, R]
14+
object Repeater:
15+
implicit def GenericRepeaterImplicit[T]: Repeater[T, Seq[T]] = ???
16+
17+
sealed trait RegexTree
18+
abstract class Node extends RegexTree
19+
class CharClassIntersection() extends Node
20+
21+
def classItem: P[RegexTree] = ???
22+
def charClassIntersection: P[CharClassIntersection] = ???
23+
24+
def x =
25+
(charClassIntersection.rep() | classItem.rep()) // error

tests/pos/i18123.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ extension [T](inline parse0: P[T])
77
inline def | [V >: T](inline other: P[V]): P[V] = ???
88

99
extension [T](inline parse0: => P[T])
10-
inline def rep[V](inline min: Int = 0)(using repeater: Implicits.Repeater[T, V]): P[V] = ???
10+
// transparent needed to make this compile in 3.4+
11+
transparent inline def rep[V](inline min: Int = 0)(using repeater: Implicits.Repeater[T, V]): P[V] = ???
1112

1213
object Implicits:
1314
trait Repeater[-T, R]

tests/pos/i20297.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
sealed abstract class Kyo[+T, -S]
2+
opaque type <[+T, -S] >: T = T | Kyo[T, S]
3+
4+
extension [T, S](v: T < S)
5+
inline def map[U, S2](inline f: T => U < S2): U < (S & S2) = ???
6+
7+
class Streams[V]
8+
object Streams:
9+
def emitValue[V](v: V): Unit < Streams[V] = ???
10+
11+
opaque type Stream[+T, V, -S] = T < (Streams[V] & S)
12+
object Stream:
13+
extension [T, V, S](s: Stream[T, V, S])
14+
def reemit[S2, V2](f: V => Unit < (Streams[V2] & S2)): Stream[T, V2, S & S2] = ???
15+
def filter[S2](f: V => Boolean < S2): Stream[T, V, S & S2] = reemit { v =>
16+
f(v).map {
17+
case false => ()
18+
case true => Streams.emitValue(v)
19+
}
20+
}

0 commit comments

Comments
 (0)