Skip to content

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

# Incorrect inferred type in contravariant position #4881

Open
opened this issue Aug 6, 2011 · 10 comments
Open

# Incorrect inferred type in contravariant position#4881

opened this issue Aug 6, 2011 · 10 comments
Labels
Milestone

## Comments

### scabug commented Aug 6, 2011

 ```class Contra[-T] trait A trait B extends A trait C extends B def contraLBUB[a >: C <: A](): Contra[a] = null def contraLB[a >: C](): Contra[a] = null contraLBUB() //inferred Contra[C] instead of Contra[A] contraLB() //inferred Contra[C] instead of Contra[Any]``` According to Language specification (6.26.4 Case 2): If several substitutions exist, local-type inference will choose for each type variable ai a minimal or maximal type Ti of the solution space. A maximal type Ti will be chosen if the type parameter ai appears contravariantly (§4.5) in the type T of the expression. A minimal type Ti will be chosen in all other situations, i.e. if the variable appears covariantly, nonvariantly or not at all in the type T. What we can see here. Value has Type Contra[a]. So position of a is contravariant. There is no covariant or invariant positions of a => maximal solution should be chosen.

### scabug commented Aug 6, 2011

 Imported From: https://issues.scala-lang.org/browse/SI-4881?orig=1 Reporter: @Alefas Affected Versions: 2.9.0-1

### scabug commented Aug 6, 2011

 @retronym said: Actually, it works as expected as a Value (Case 2) ```scala> contraLBUB res9: Contra[A] = null scala> contraLB res10: Contra[Any] = null``` So the question is, does "Case 3: Methods" explain these? ```scala> contraLBUB() res11: Contra[C] = null scala> contraLB() res12: Contra[C] = null```

### scabug commented Aug 7, 2011

 @Alefas said: I'm sure this is wrong if it's different: ```foo foo()```

### scabug commented Aug 7, 2011

 @paulp said: Yeah, that's a bit hard to defend: `````` scala> contraLBUB res1: Contra[A] = null scala> contraLBUB() res2: Contra[C] = null scala> (contraLBUB _)() res3: Contra[A] = null ``````

### scabug commented Jun 21, 2012

 @retronym said: Without having checked the consequences (sky falling, etc), but this is enough to restore consistency between inference for the value and method application: ```diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.s index 688dcd9..a34b93d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -575,8 +575,9 @@ trait Infer { "argument expression's type is not compatible with formal parameter type" + foundReqMsg(tp1, pt1)) } } val targs = solvedTypes( - tvars, tparams, tparams map varianceInTypes(formals), + tvars, tparams, tparams map varianceInTypes(restpe +: formals), false, lubDepth(formals) max lubDepth(argtpes) ) adjustTypeArgs(tparams, tvars, targs, restpe)``` Compare with: https://github.com/scala/scala/blob/039d826e/src/compiler/scala/tools/nsc/typechecker/Infer.scala#L384

### scabug commented Jun 21, 2012

 @adriaanm said (edited on Jun 21, 2012 8:09:59 AM UTC): I think that needs to be adjusted slightly since the variance in formals should be flipped (arguments = contravariant), whereas restpe is in covariant position (the flipping is achieved by the up=false argument to solvedTypes, off the top of my head)

### scabug commented Sep 29, 2012

 @paulp said: This is being reverted for causing #6311.

### scabug commented Sep 30, 2012

 @Blaisorblade said: Fixing this means that `Coll` would be inferred differently for these two signatures, which look instead equivalent: ```def f[T, Coll <: Traversable[T]](p0: String)(p1: Traversable[T]): (Coll => Traversable[T]) = ??? //Here Coll would be maximized. def f[T, Coll <: Traversable[T]](p0: String)(p1: Traversable[T])(p2: Coll): Traversable[T] = ??? //Here Coll would be minimized.``` This is if I get the new expected behavior right, which says that (ignoring mixed variance) a type argument must be minimized (made most specific) if it appears either: (a) covariantly in the result type (per 4881), hence covariantly in the method type or (b) covariantly in argument types, hence contravariantly in the method type.

### scabug commented Oct 15, 2013

 @gkossakowski said: Unassigning and rescheduling to M7 as previous deadline was missed.
added labels Apr 7, 2017
added this to the Backlog milestone Apr 7, 2017
This was referenced Apr 7, 2017
removed the label Jul 27, 2017
to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.