scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Can't get my singleton type back from `ensuring` #12804

Open som-snytt opened 1 year ago

som-snytt commented 1 year ago

Reproduction steps

Scala version: 2.13.11

Welcome to Scala 2.13.11 (OpenJDK 64-Bit Server VM, Java 20.0.1).
Type in expressions for evaluation. Or try :help.

scala> val self = "abcd"
val self: String = abcd

scala> val sure: self.type = self.ensuring(_.length > 3)
                                           ^
       error: missing parameter type for expanded function ((<x$1: error>) => x$1.length.$greater(3))

scala>

Problem

ensuring is not defined as returning self.type and inference doesn't support the straightforward expression.

Scala 3 is fine with it, but maybe is assisted by infra for new-style extensions:

Welcome to Scala 3.3.2-RC1-bin-SNAPSHOT-git-e23bc4f (20.0.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> val self = "abcd"
val self: String = abcd

scala> val s: self.type = self.ensuring(_.length > 3)
val s: self.type = abcd

(I'm not sure how it gets away with it, as I don't see self.type inferred anywhere, but I didn't research it.)

som-snytt commented 1 year ago

I had not got around to trying it.

scala> implicit class xxx[A](val a: A) extends AnyVal { def chex(p: A => Boolean): a.type = {assert(p(a)); a} }
class xxx

scala> val sure: self.type = self.chex(_.length > 3)
                                      ^
       error: type mismatch;
        found   : _1.a.type (with underlying type String) where val _1: xxx[String]
        required: self.type

scala> val sure: self.type = xxx[self.type](self).chex(_.length > 3)
val sure: self.type = abcd

well,

scala> implicit class xxx[A <: Singleton](val a: A) extends AnyVal { def chex(p: A => Boolean): a.type = {assert(p(a));
a} }
class xxx

scala> val sure: self.type = self.chex(_.length > 3)
val sure: self.type = abcd

but

scala> implicit class xxx[A <: Singleton](private val a: A) extends AnyVal { def chex(p: A => Boolean): a.type = {assert
(p(a)); a} }
                                                                                                         ^
       error: private value a escapes its defining scope as part of type xxx.this.a.type
SethTisue commented 1 year ago

can we change ensuring?