Skip to content
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

inference regression with existentials #5330

Closed
scabug opened this issue Dec 20, 2011 · 19 comments
Closed

inference regression with existentials #5330

scabug opened this issue Dec 20, 2011 · 19 comments

Comments

@scabug
Copy link

scabug commented Dec 20, 2011

This compiled in 2.9, no longer.

class CC(xs: List[_ <: AnyRef]) {
  def f(obj: AnyRef, name: String): AnyRef = null
  def g = xs map (x => f(x,""))
}
// t5330.scala:3: error: missing parameter type
//   def g = xs map (x => f(x,""))
//                   ^

If it's a type parameter bounded by AnyRef, compiles.

@scabug
Copy link
Author

scabug commented Dec 20, 2011

Imported From: https://issues.scala-lang.org/browse/SI-5330?orig=1
Reporter: @paulp
Affected Versions: 2.10.0
Other Milestones: 2.11.0-M1

@scabug
Copy link
Author

scabug commented May 14, 2012

@lrytz said:
this is unrelated to default arguments.

@scabug
Copy link
Author

scabug commented May 14, 2012

@paulp said:
Sorry for the poor minimization.

@scabug
Copy link
Author

scabug commented May 14, 2012

@retronym said:
Decoupled from the collections dynasty:

trait FM[A] {
  def map(f: A => Any)
}

trait M[A] extends FM[A] {
  def map(f: A => Any)
}

trait N[A] extends FM[A]

object test {
  def kaboom(xs: M[_]) = xs map (x => ()) // missing parameter type.

  def okay1[A](xs: M[A]) = xs map (x => ())
  def okay2(xs: FM[_]) = xs map (x => ())
  def okay3(xs: N[_]) = xs map (x => ())
}

@scabug
Copy link
Author

scabug commented May 14, 2012

@paulp said:
Here's a better look at it.

// compiles
class CC1(xs: List[_]) {
  def f(x1: Any) = null
  def g = xs map (x => f(x))
}
// does not compile
class CC2(xs: List[_]) {
  def f(x1: Any, x2: Any) = null
  def g = xs map (x => f(x, x))
}

In 2.9, -Xprint:typer for g in CC1 and CC2

def g: List[Null] = CC1.this.xs.map[Null, List[Null]](((x: _$1) => CC1.this.f(x)))(immutable.this.List.canBuildFrom[Null])
def g: List[Null] = CC2.this.xs.map[Null, List[Null]](((x: _$2) => CC2.this.f(x, x)))(immutable.this.List.canBuildFrom[Null])

As similar as one might suppose. In trunk:

def g: List[Null] = CC1.this.xs.map[Null, List[Null]](((x: Any) => CC1.this.f(x)))(immutable.this.List.canBuildFrom[Null]
def g: <error> = CC2.this.xs.map(((x: <error>) => f(x, x)))

So the existential in the function parameter type has been crushed to Any.

@scabug
Copy link
Author

scabug commented May 14, 2012

@paulp said:
Crossed in the night.

I think this is #5399.

@scabug
Copy link
Author

scabug commented May 14, 2012

@retronym said:
In my example:

2.9.2

        typed xs.map: (f: Any => Any)Unit
        adapted xs.map: (f: Any => Any)Unit to ?, 
        typing ((x) => ()): pt = Any => Any: undetparams=, implicitsEnabled=true, silent=true, context.owner=method kaboom
[loaded class file /Users/jason/usr/scala-2.9.1/lib/scala-library.jar(scala/reflect/Code.class) in 2ms]
            typing (): pt = Any: undetparams=, implicitsEnabled=true, silent=true, context.owner=value $anonfun
            typed (): Unit
[loaded class file /Users/jason/usr/scala-2.9.1/lib/scala-library.jar(scala/AnyVal.class) in 2ms]
            adapted (): Unit to Any, 
        typed ((x: Any) => ()): Any => Unit
        adapted ((x: Any) => ()): Any => Unit to Any => Any, 

2.10

        typed xs.map: (f: _$1 => Any)Unit <and> (f: _$1 => Any)Unit
        adapted xs.map: (f: _$1 => Any)Unit <and> (f: _$1 => Any)Unit to ?, 
        typing ((x) => ()): pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode BYVALmode, silent=true, context.owner=method kaboom
            typing (): pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode, silent=true, context.owner=value $anonfun
            typed (): Unit
            adapted (): Unit to ?, 
        typed ((x: <error>) => ()): <error> => Unit
        adapted ((x: <error>) => ()): <error> => Unit to ?, 
    no second try: xs.map and ((x: <error>) => ()) because error not in result:

Disturbingly, map is treated as an overloaded type.

@scabug
Copy link
Author

scabug commented Jun 10, 2012

@retronym said (edited on Jun 10, 2012 9:09:00 AM UTC):
I'm pretty sure this is to blame.
scala/scala@b7b81ca2

At least this example compiles with that reverted (actually, just with this line scala/scala@b7b81ca2#L0L567):

trait FM[A] {
  def map(f: A => Any)
}

trait M[A] extends FM[A] {
  def map(f: A => Any)
}

object test {
  def kaboom(xs: M[_]) = xs map (x => ()) // missing parameter type.

}

Without this, M#map does not match FM#map, as A gets a different existential symbol.

{(f#7469: A#7103 => Any#3533)Unit#1690}.asSeenFrom(xs#8667.type, trait M#9)

tp1 = (f#8670: _$1#8669 => Any#3533)Unit#1690
result = (f#8673: _$1#8671 => Any#3533)Unit#1690

@scabug
Copy link
Author

scabug commented Jun 10, 2012

@retronym said:
See also #3481, which was fixed by b7b81ca2.

@scabug
Copy link
Author

scabug commented Jun 10, 2012

@retronym said:
Here's my attempt to fix this.

https://github.com/retronym/scala/compare/ticket/5330

@scabug
Copy link
Author

scabug commented Jun 12, 2012

@scabug
Copy link
Author

scabug commented Jun 13, 2012

@adriaanm said:
I think scala/scala@fc24db4c is the way to go here as well.
If we skolemize the self type before doing an ASF, the same skolem should turn up on repeated ASF's.

@scabug
Copy link
Author

scabug commented Jun 14, 2012

@retronym said:
Like so? See the questions in the commit comment.

https://github.com/retronym/scala/compare/ticket/5330-4

@scabug
Copy link
Author

scabug commented Jun 19, 2012

@adriaanm said (edited on Jun 19, 2012 1:36:34 PM UTC):
I'm not sure, sorry. I'd have to take it for a spin in the debugger to really see what is going on.
I'll have a look later this week.

@scabug
Copy link
Author

scabug commented Aug 7, 2012

@adriaanm said:
scala/scala#1074

@scabug
Copy link
Author

scabug commented Aug 8, 2012

@adriaanm said:
demoting to major since it's too hard to fix properly for 2.10.0

@scabug
Copy link
Author

scabug commented Sep 9, 2012

@retronym said:
More examples from the mailing list:

val s: Set[_ >: Char] = Set('A')
s forall ("ABC" contains _)
s.forall( c => "ABC".toSeq.contains( c ))

@scabug
Copy link
Author

scabug commented Oct 26, 2012

@paulp said:
scala/scala#1514

@scabug
Copy link
Author

scabug commented Nov 16, 2012

@adriaanm said:
scala/scala#1624

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants