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

Scalacheck Prop.forAll with > 8 arbitraries eta-expands under -Xsource:3 #13055

Open
som-snytt opened this issue Oct 30, 2024 · 1 comment · May be fixed by scala/scala#10907
Open

Scalacheck Prop.forAll with > 8 arbitraries eta-expands under -Xsource:3 #13055

som-snytt opened this issue Oct 30, 2024 · 1 comment · May be fixed by scala/scala#10907
Assignees
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) has PR
Milestone

Comments

@som-snytt
Copy link

Questions are not bug reports

Miles had a question:

TIL that if you ask Prop.forAll for more than 8 arbitraries in a test the test will silently succeed no matter what.
If you hand Prop.forAll a function with > 8 arguments, then instead of getting back a Prop you get back an ... => Prop which is typically silently discarded in a test.
Is this widely known?
It really ought not to compile.

and an answer:

This appears to be specific to Scala 2.13.x with -Xsource:3.0.0.

Reproduction steps

Scala version: 2.13.15

import org.scalacheck._, Prop._

object Main extends App {

  def what() = forAll {
    (a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int,
     a8: Int,
     a9: Int,
    ) => false
  }

}

Normally, scalac correctly says

[error] Unapplied methods are only converted to functions when a function type is expected.
[error] You can make this conversion explicit by writing `forAll _` or `forAll(_)(_)(_,_,_)` instead of `forAll`.

Problem

Incorrectly fails to fail compilation under -Xsource:3, but instead decides to eta-expand "unconditionally".

Probably that condition should fall under -Xsource-features. Probably it should find a way not to compile.

Dotty chooses the correct overload of forAll due to parameter untupling. Can we have that? It's almost Christmas (say the major retailers who are already discounting Halloween decorations).

via https://discord.com/channels/632277896739946517/841617753513263144/1296796824262283347

@som-snytt som-snytt added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Oct 30, 2024
@som-snytt som-snytt changed the title Scalacheck Prop.forAll with > 8 arbitraries eta-expands under -Xsource;3 Scalacheck Prop.forAll with > 8 arbitraries eta-expands under -Xsource:3 Oct 30, 2024
@som-snytt
Copy link
Author

som-snytt commented Oct 30, 2024

  class Prop
  class Gen[A]
  object Gen {
    implicit def const[T](x: T): Gen[T] = ???
  }

  def forAll[T1, P](g: Gen[T1])(f: T1 => P)(implicit p: P => Prop): Prop = ???
  def forAll[A1, P](f: A1 => P)(implicit p: P => Prop): Prop = ???

  def what() = forAll {
    (a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int,
     a8: Int,
     a9: Int,
    ) => false
  }

The successful typecheck infers P as Nothing:

forAll(Gen.const(f))(_)(conforms)

Dotty infers P as Any, so it rejects this alternative.

If -Xsource-features could support both tupling and flipped bound inference, then it could more safely support "unexpected" eta expansion (that is, without an expected type). Or perhaps improved parameter type inference would also be needed, and extended overload resolution for multiple param lists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) has PR
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants