Skip to content

Avoid necessaryEither because it could constrain too much #12316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
}
val tp1norm = simplifyAndTypeWithFallback(tp11, tp12, tp1)
if (tp1 ne tp1norm) recur(tp1norm, tp2)
else either(recur(tp11, tp2), recur(tp12, tp2))
else
if useNecessaryEither && !frozenConstraint then
if tp11 frozen_<:< tp12 then recur(tp11, tp2)
else if tp12 frozen_<:< tp11 then recur(tp12, tp2)
else false
else
val saved = constraint
either(recur(tp11, tp2), recur(tp12, tp2))
.showing(i"constraining andtype $tp11 & $tp12 <: $tp2 in $saved ----> $constraint", subtyping)
case tp1: MatchType =>
def compareMatch = tp2 match {
case tp2: MatchType =>
Expand Down
22 changes: 22 additions & 0 deletions tests/pos/i12306.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Record(elems: Map[String, Any]) extends Selectable:
val fields = elems.toMap
def selectDynamic(name: String): Any = fields(name)

extension [A <: Record] (a:A) {
def join[B <: Record] (b:B): A & B = {
Record(a.fields ++ b.fields).asInstanceOf[A & B]
}
}

type Person = Record { val name: String; val age: Int }
type Child = Record { val parent: String }
type PersonAndChild = Record { val name: String; val age: Int; val parent: String }

@main def hello = {
val person = Record(Map("name" -> "Emma", "age" -> 42)).asInstanceOf[Person]
val child = Record(Map("parent" -> "Alice")).asInstanceOf[Child]
//val personAndChild = person.join(child)

//val v1: PersonAndChild = personAndChild
val v2: PersonAndChild = person.join(child)
}