Skip to content

Commit bdf98c5

Browse files
committed
Fix regression in cyclic constraint handling
This regressed in 50eb0e9 when `current.ensureNonCyclic` was incorrectly replaced by `validBoundsFor` which operates on `this`, not `current`. This isn't the first time we make this error (cf a8641c5), maybe we should refactor OrderingConstraint so that operations on `current` are done in the companion object where `this` isn't accessible. Fixes scala#16471.
1 parent 5929a50 commit bdf98c5

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
693693
def replaceParamIn(other: TypeParamRef) =
694694
val oldEntry = current.entry(other)
695695
val newEntry = oldEntry.substParam(param, replacement) match
696-
case tp: TypeBounds => validBoundsFor(other, tp)
696+
case tp: TypeBounds => current.validBoundsFor(other, tp)
697697
case tp => tp
698698
current = boundsLens.update(this, current, other, newEntry)
699699
var oldDepEntry = oldEntry

tests/pos-deep-subtype/i16471.scala

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
object tag {
2+
type Tag[U]
3+
opaque type Tagged[U] = Tag[U]
4+
type @@[+T, U] = (T & Tagged[U]) | Null
5+
}
6+
import tag.*
7+
8+
trait FromInput[Val]
9+
object FromInput {
10+
trait CoercedScalaResult
11+
implicit def optionInput[T](implicit ev: FromInput[T]): FromInput[Option[T]] = ???
12+
implicit def coercedScalaInput[T]: FromInput[T @@ CoercedScalaResult] = ???
13+
}
14+
import FromInput.CoercedScalaResult
15+
16+
object schema {
17+
trait InputType[+T] // This is critical! Making InputType invariant allows to compile
18+
19+
case class OptionInputType[T](ofType: InputType[T]) extends InputType[Option[T]]
20+
class ScalarType[T] extends InputType[T @@ CoercedScalaResult]
21+
implicit val IntType: ScalarType[Int] = ???
22+
}
23+
export schema.*
24+
25+
trait WithoutInputTypeTags[T] { type Res }
26+
object WithoutInputTypeTags {
27+
implicit def coercedArgTpe[T]: WithoutInputTypeTags[T @@ CoercedScalaResult] { type Res = T } = ???
28+
implicit def coercedOptArgTpe[T]: WithoutInputTypeTags[Option[T @@ CoercedScalaResult]] { type Res = Option[T] } = ???
29+
}
30+
31+
trait Argument[T]
32+
object Argument {
33+
def apply[T](argumentType: InputType[T])(implicit
34+
fromInput: FromInput[T],
35+
res: WithoutInputTypeTags[T]
36+
): Argument[res.Res] = ???
37+
}
38+
39+
@main def Test = {
40+
// Does not compile
41+
val optionalArgument = Argument(
42+
argumentType = OptionInputType(IntType),
43+
)
44+
45+
// // This would compile
46+
// val hintedArg = Argument[Option[Int @@ CoercedScalaResult]](
47+
// argumentType = OptionInputType(IntType)
48+
// )
49+
}

0 commit comments

Comments
 (0)