You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If we have a function def[A <: B]foo(...) = ..., the ordering A <: B are not properly recorded if B has been instantiated. Instead, A <: B will be recorded as a /non-param bound/ of A.
Compiler version
The main branch
Minimized code
enumTag[A]:caseData[A]() extendsTag[A]
deffoo0[A](e: Tag[A]) = e.match {
case_: Tag.Data[a] =>defbar[C>:Int<: a]() =valt1: a =0// fails
}
deffoo1[A, C>:Int<:A]() =valt1:A=0// works
Output
-- [E007] TypeMismatchError: issues/gadt-inst-dep.scala:8:18-------------------------------------------------------------------------------------------------------------------------------------------8|valt1: a =0// fails| ^
|Found: (0:Int)
|Required: a
||where: a is a typein method foo0 which is an alias of A|| longer explanation available when compiling with`-explain`
Expectation
The code should compile without error.
In foo0 and foo1 we introduce the type parameter C with bounds >: Int <: a (or A). In foo1 the ordering between C and A is properly handled (so the bound >: Int gets propagated to A), but it is not the case in foo0. The main difference between foo0 and foo1 is that a in foo0 has been instantiated.
The reason why the ordering is not recorded in foo0 is that when processing the newly-defined type parameter C, the OrderingConstraint class will check whether a is a constrained parameter by calling constraint.contains(a). However, since the a has been instantiated and the related type lambda gets removed in the constraint, constraint.contains(a) returns false. So OrderingConstraint will keep a in the non-param bounds of C, without recording the orderings.
This is an issue discovered while developing #14754. #14754 already contains a fix for this issue that tries to check whether a has been instantiated and strips the type variable to its instance if possible. See this commit.
The text was updated successfully, but these errors were encountered:
If we have a function
def[A <: B]foo(...) = ...
, the orderingA <: B
are not properly recorded ifB
has been instantiated. Instead,A <: B
will be recorded as a /non-param bound/ ofA
.Compiler version
The
main
branchMinimized code
Output
Expectation
The code should compile without error.
In
foo0
andfoo1
we introduce the type parameterC
with bounds>: Int <: a (or A)
. Infoo1
the ordering betweenC
andA
is properly handled (so the bound>: Int
gets propagated toA
), but it is not the case infoo0
. The main difference betweenfoo0
andfoo1
is thata
infoo0
has been instantiated.The reason why the ordering is not recorded in
foo0
is that when processing the newly-defined type parameterC
, theOrderingConstraint
class will check whethera
is a constrained parameter by callingconstraint.contains(a)
. However, since thea
has been instantiated and the related type lambda gets removed in the constraint,constraint.contains(a)
returns false. SoOrderingConstraint
will keepa
in the non-param bounds ofC
, without recording the orderings.This is an issue discovered while developing #14754. #14754 already contains a fix for this issue that tries to check whether
a
has been instantiated and strips the type variable to its instance if possible. See this commit.The text was updated successfully, but these errors were encountered: