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

too eager widening of singleton types #102

Closed
scabug opened this issue Sep 17, 2007 · 9 comments
Closed

too eager widening of singleton types #102

scabug opened this issue Sep 17, 2007 · 9 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Sep 17, 2007

I expected the following code to compile:

trait Foo {
  type Arg
  type Prod
  def makeProd(a : Arg): Prod
}

// simulate dependent method types
case class buildProd(foo: Foo) {
  def apply(a: foo.Arg): foo.Prod = foo.makeProd(a)
}

object main {
  val myFoo = new Foo{type Arg=Int; type Prod=(Int, Int); def makeProd(i: Int) = (i, i)}
  
  buildProd(myFoo)(1)
}

Instead, the compiler complains:

15: error: method apply cannot be accessed in buildProd
 because its instance type (Foo#Arg)Foo#Prod contains a malformed type: Foo#Arg
  buildProd(myFoo)(1)
           ^
one error found

It seems foo.type gets approximated to Foo too early..

@scabug
Copy link
Author

scabug commented Sep 17, 2007

Imported From: https://issues.scala-lang.org/browse/SI-102?orig=1
Reporter: @adriaanm

@scabug
Copy link
Author

scabug commented Sep 17, 2007

@odersky said:
This would require dependent method types. They are not currently in Scala. I'll keep the ticket open as a request for enhancement.

@scabug
Copy link
Author

scabug commented Sep 17, 2007

@adriaanm said:
I fiddled with this some more, and adding a type parameter TFoo to buildProd is enough to get the program to type check. This makes me think the original problem is not directly related to dependent method types (in fact, it encodes them, but I don't think it uses them).

case class buildProd[TFoo <: Foo](foo: TFoo) {  // now it works
  def apply(a: foo.Arg): foo.Prod = foo.makeProd(a)
}

@scabug
Copy link
Author

scabug commented Sep 17, 2007

@odersky said:
But don't you need to parameterize the call also, as in:

   buildProd[myFoo.tpe](myFoo)

?

@scabug
Copy link
Author

scabug commented Sep 17, 2007

@adriaanm said:
Replying to [comment:3 odersky]:

But don't you need to parameterize the call also, as in:

    buildProd[myFoo.tpe](myFoo)

?
In a more complicated example, yes -- here, the following is inferred (-Xprint:typer):

    buildProd[java.lang.Object with Foo{type Arg = Int; type Prod = (Int, Int)}](main.this.myFoo).apply(1)

@scabug
Copy link
Author

scabug commented Jan 14, 2009

@odersky said:
Milestone postponed deleted

@scabug
Copy link
Author

scabug commented Apr 7, 2011

@soc said:
In 2.10.0.r24516-b20110320020044 it has changed to just a type mismatch:

scala>   buildProd(myFoo)(1)
<console>:12: error: type mismatch;
 found   : Int(1)
 required: _4.foo.Arg where val _4: buildProd
         buildProd(myFoo)(1)
                          ^

@scabug
Copy link
Author

scabug commented Oct 29, 2011

@paulp said:
I'm adding a test and closing this; if someone thinks there is an interesting space between what the test accomplishes and what we should be accomplishing, go ahead and reopen it.

@scabug
Copy link
Author

scabug commented Oct 29, 2011

Commit Message Bot (anonymous) said:
(extempore in r25907) Test case closes #102.

No review.

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