-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix type inference for HLists and HMaps #2045
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
Changes from 15 commits
f449d9d
e4775b8
c3a90a4
0baeb8e
1d124e9
860fd56
42fd456
76d9748
f7a5071
e01ca04
58b71ca
1d237bb
0a839b8
4c6a69e
10d868c
c7f1f35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1312,23 +1312,28 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { | |
case tp1: RefinedType => | ||
tp2 match { | ||
case tp2: RefinedType if tp1.refinedName == tp2.refinedName => | ||
// Given two refinements `T1 { X = S1 }` and `T2 { X = S2 }`, if `S1 =:= S2` | ||
// (possibly by instantiating type parameters), rewrite to `T1 & T2 { X = S1 }`. | ||
// Otherwise rewrite to `T1 & T2 { X B }` where `B` is the conjunction of | ||
// the bounds of `X` in `T1` and `T2`. | ||
// The first rule above is contentious because it cuts the constraint set. | ||
// But without it we would replace the two aliases by | ||
// `T { X >: S1 | S2 <: S1 & S2 }`, which looks weird and is probably | ||
// not what's intended. | ||
// Given two refinements `T1 { X = S1 }` and `T2 { X = S2 }` rewrite to | ||
// `T1 & T2 { X B }` where `B` is the conjunction of the bounds of `X` in `T1` and `T2`. | ||
// | ||
// However, if `homogenizeArgs` is set, and both aliases `X = Si` are | ||
// nonvariant, and `S1 =:= S2` (possibly by instantiating type parameters), | ||
// rewrite instead to `T1 & T2 { X = S1 }`. This rule is contentious because | ||
// it cuts the constraint set. On the other hand, without it we would replace | ||
// the two aliases by `T { X >: S1 | S2 <: S1 & S2 }`, which looks weird | ||
// and is probably not what's intended. | ||
val rinfo1 = tp1.refinedInfo | ||
val rinfo2 = tp2.refinedInfo | ||
val parent = tp1.parent & tp2.parent | ||
val rinfo = | ||
if (rinfo1.isAlias && rinfo2.isAlias && isSameType(rinfo1, rinfo2)) | ||
rinfo1 | ||
else | ||
rinfo1 & rinfo2 | ||
tp1.derivedRefinedType(parent, tp1.refinedName, rinfo) | ||
|
||
def isNonvariantAlias(tp: Type) = tp match { | ||
case tp: TypeAlias => tp.variance == 0 | ||
case _ => false | ||
} | ||
if (homogenizeArgs && | ||
isNonvariantAlias(rinfo1) && isNonvariantAlias(rinfo2)) | ||
isSameType(rinfo1, rinfo2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, we perform sameType only for its effect on the constraint |
||
|
||
tp1.derivedRefinedType(parent, tp1.refinedName, rinfo1 & rinfo2) | ||
case _ => | ||
NoType | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
object Sessions { | ||
def ?[T <: AnyRef](implicit w: T): w.type = w | ||
|
||
// session states | ||
sealed case class Stop() | ||
|
@@ -18,7 +17,7 @@ object Sessions { | |
|
||
// friendly interface to the theory | ||
def runSession[S, D: Session[S]#HasDual](session: S, dual: D) = | ||
?[Session[S]#HasDual[D]].run(session, dual) | ||
implicitly[Session[S]#HasDual[D]].run(session, dual) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was keeping this test pending intentional? Does this PR change how I remember seeing something similar to this trait A { type Out }
implicit val a = new A { type Out = String }
val i1: A { type Out = String } = implicitly[A]
// error: type mismatch;
// found : A
// required: A{type Out = String}
def ?[T <: AnyRef](implicit w: T): w.type = w
val i2: A { type Out = String } = ?[A] // works fine! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, that's an oversight. We should keep the test as it was in pending. It worked after the first commits but then stopped working again after the final commits. Given the error message it could well be something related to existential types which dotty no longer supports, so I did not investigate further. I'll change the test to what it was an add a comment. |
||
|
||
// facts in the theory: | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
object TupledEvidenceTest { | ||
|
||
abstract class TupledEvidence[M[_], T0] { type T = T0 } | ||
|
||
implicit def witnessTuple2[M[_], T1, T2](implicit ev1: M[T1], ev2: M[T2]): | ||
TupledEvidence[M, (T1, T2)] { type T = (T1, T2) } = sys.error("") | ||
|
||
class GetResult[T] | ||
|
||
implicit val getString: GetResult[String] = new GetResult[String] | ||
|
||
implicit def getTuple[T](implicit w: TupledEvidence[GetResult, T]): GetResult[w.T] = sys.error("") | ||
|
||
def f[T : GetResult] = "" | ||
|
||
f[(String,String)](getTuple[(String, String)]) | ||
|
||
f[(String,String)] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
1 | ||
A | ||
true | ||
true | ||
HCons(1,HCons(A,HCons(true,HNil))) | ||
1 | ||
A | ||
true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this state be stored in
Context
instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would make the logic more complicated.