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 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

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 14, 2012

@lrytz said:
this is unrelated to default arguments.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 14, 2012

@paulp said:
Sorry for the poor minimization.

@scabug

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 14, 2012

@paulp said:
Crossed in the night.

I think this is #5399.

@scabug

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug 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@b7b81ca

At least this example compiles with that reverted (actually, just with this line scala/scala@b7b81ca#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

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jun 10, 2012

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

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jun 10, 2012

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jun 12, 2012

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jun 13, 2012

@adriaanm said:
I think scala/scala@fc24db4 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

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug scabug commented Aug 7, 2012

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Aug 8, 2012

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

@scabug

This comment has been minimized.

Copy link
Author

@scabug 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

This comment has been minimized.

Copy link
Author

@scabug scabug commented Oct 26, 2012

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Nov 16, 2012

Sign up for free 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.