Skip to content

Disallow refinements in GivenTypes #6290

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

Merged
merged 7 commits into from
Apr 11, 2019

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Apr 11, 2019

Test case is i2567.scala. We would like to write

class Foo given T {
  ...
}

But previously this mistook the class body as a refinement for T.

odersky added 2 commits April 11, 2019 12:31
Test case is i2567.scala. We would like to write
```
class Foo given T {
  ...
}
```
But previously this mistook the class body as a refinement for `T`.
I believe there might be something wrong with how given parameters are treated in tasty reflect.
@anatoliykmetyuk
Copy link
Contributor

anatoliykmetyuk commented Apr 11, 2019

I am not sure... Refinement types are allowed in the given part of the methods:

trait User
trait Order

trait TableName { type forEntity; val name: String }
object Instances {
  implied userTbl for TableName {
    type forEntity = User
    val name = "user"
  }

  implied orderTbl for TableName {
    type forEntity = Order
    val name = "order"
  }
}

object statements {
  def select[T] given TableName { type forEntity = T } =
    s"select * from ${the[TableName].name}"
}

import implied Instances._
println(statements.select[User ])  // select * from user
println(statements.select[Order])  // select * from order

So not allowing them in the constructors brings inconsistency. This can invite the following pattern:

  // class Statements[T] given TableName { type forEntity = T } {
  //   def select = s"select * from ${the[TableName].name}"
  //   def selectWhere(where: String) = s"select * from ${the[TableName].name} where ${where}"
  // }

  class Statements[T](tn: TableName { type forEntity = T }) {
    implied for TableName = tn
    def select = s"select * from ${the[TableName].name}"
    def selectWhere(where: String) = s"select * from ${the[TableName].name} where ${where}"
  }
  def Statements[T] given TableName { type forEntity = T } = new Statements[T](the[TableName])

  import implied Instances._
  println(Statements[User].selectWhere("id = 1"))

One thing that comes to mind is to allow for an optional syntax for class definitions as follows:

  class Statements[T] given TableName { type forEntity = T } = {
     /*...*/
  }

@odersky
Copy link
Contributor Author

odersky commented Apr 11, 2019

Good point. We could do one of two things:

  1. Leave the PR as is, which means we require a named parameter list:
def select[T] given (ev: TableName { type forEntity = T })
  1. Require AnnotTypes only for classes. This is more flexible since select can be written like this:
def select[T] given TableName { type forEntity = T }

But that would make it inconsistent between def parameters and class parameters. My tendency would be to pick (1).

@smarter
Copy link
Member

smarter commented Apr 11, 2019

Can we allow the following ?

  class Statements[T] given (TableName { type forEntity = T }) {
    // ...
  }

@odersky
Copy link
Contributor Author

odersky commented Apr 11, 2019

Can we allow the following ?

  class Statements[T] given (TableName { type forEntity = T }) {
    // ...
  }

Currently no. An opening ( starts a regular parameter list. But maybe we can fix the parser to allow it.

@anatoliykmetyuk
Copy link
Contributor

Option 1 feels reasonable to me. Though the (TableName { type forEntity = T }) would also be nice to have.

@odersky odersky merged commit 1b55f8e into scala:master Apr 11, 2019
@allanrenucci allanrenucci deleted the fix-given-syntax branch April 11, 2019 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants