Skip to content

Commit

Permalink
Fix regression in cyclic constraint handling
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
smarter committed Dec 13, 2022
1 parent 5929a50 commit bdf98c5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def replaceParamIn(other: TypeParamRef) =
val oldEntry = current.entry(other)
val newEntry = oldEntry.substParam(param, replacement) match
case tp: TypeBounds => validBoundsFor(other, tp)
case tp: TypeBounds => current.validBoundsFor(other, tp)
case tp => tp
current = boundsLens.update(this, current, other, newEntry)
var oldDepEntry = oldEntry
Expand Down
49 changes: 49 additions & 0 deletions tests/pos-deep-subtype/i16471.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
object tag {
type Tag[U]
opaque type Tagged[U] = Tag[U]
type @@[+T, U] = (T & Tagged[U]) | Null
}
import tag.*

trait FromInput[Val]
object FromInput {
trait CoercedScalaResult
implicit def optionInput[T](implicit ev: FromInput[T]): FromInput[Option[T]] = ???
implicit def coercedScalaInput[T]: FromInput[T @@ CoercedScalaResult] = ???
}
import FromInput.CoercedScalaResult

object schema {
trait InputType[+T] // This is critical! Making InputType invariant allows to compile

case class OptionInputType[T](ofType: InputType[T]) extends InputType[Option[T]]
class ScalarType[T] extends InputType[T @@ CoercedScalaResult]
implicit val IntType: ScalarType[Int] = ???
}
export schema.*

trait WithoutInputTypeTags[T] { type Res }
object WithoutInputTypeTags {
implicit def coercedArgTpe[T]: WithoutInputTypeTags[T @@ CoercedScalaResult] { type Res = T } = ???
implicit def coercedOptArgTpe[T]: WithoutInputTypeTags[Option[T @@ CoercedScalaResult]] { type Res = Option[T] } = ???
}

trait Argument[T]
object Argument {
def apply[T](argumentType: InputType[T])(implicit
fromInput: FromInput[T],
res: WithoutInputTypeTags[T]
): Argument[res.Res] = ???
}

@main def Test = {
// Does not compile
val optionalArgument = Argument(
argumentType = OptionInputType(IntType),
)

// // This would compile
// val hintedArg = Argument[Option[Int @@ CoercedScalaResult]](
// argumentType = OptionInputType(IntType)
// )
}

0 comments on commit bdf98c5

Please sign in to comment.