scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Make opaque type refinements of inline proxy objects abstract type constructors

Open EugeneFlesselle opened this issue 1 year ago • 4 comments

Change the rhs of the added refinements from TypeAliases to RealTypeBoundss. This allows the opaque types to remain abstract type constructors, which is necessary for the MatchTypeCasePattern.AbstractTypeConstructor logic.

In particular, an AppliedType where the tycon was a reference to the refinement, used to dealias before proceeding with the comparison of the tycons, which is a requirement of the aforementioned AbstractTypeConstructor case of the MatchReducer.

Fixes #20427 Alternative to #20457

EugeneFlesselle avatar Jul 01 '24 11:07 EugeneFlesselle

This bound (ah ah!) to be break something. There are very real things we can do with type aliases that we cannot do with abstract type members of equal bounds. For example, manipulating arrays:

scala> class Foo { type T = Int }
// defined class Foo
                                                                                                    
scala> val foo = new Foo
val foo: Foo = Foo@2ca54da9
                                                                                                    
scala> val a: Array[Int] = { val b = new Array[foo.T](1); b }
val a: Array[Int] = Array(0)
                                                                                                    
scala> class Foo { type T >: Int <: Int }
// defined class Foo
                                                                                                    
scala> val foo = new Foo
val foo: Foo = Foo@2bfc2f8b
                                                                                                    
scala> val a: Array[Int] = { val b = new Array[foo.T](1); b }
-- [E172] Type Error: ----------------------------------------------------------
1 |val a: Array[Int] = { val b = new Array[foo.T](1); b }
  |                                                 ^
  |                                           No ClassTag available for foo.T
1 error found

sjrd avatar Jul 01 '24 14:07 sjrd

@sjrd Indeed, but that (specific issue) should not be a problem for inlining right ? since implicit resolution is already done by that point. i.e. val b = Array[foo.T](1) is an error, but val b = Array[foo.T](1)(using evidence$1$proxy1 : ClassTag[Int]) is ok.

I am by no means claiming there is nothing else that could be impacted though.

EugeneFlesselle avatar Jul 01 '24 14:07 EugeneFlesselle

Perhaps. There are definitely other things that require an actual type alias. Extending or instantiating an aliased class, for example. And that will remain through inlining.

sjrd avatar Jul 01 '24 14:07 sjrd

Again, just an empirical observation, but they both seem to work in the following simple test:

object A:
  opaque type W[T] = T

  inline def foo[T: ClassTag](x: T): Array[W[T]] =
    Array[W[T]](x)

  class Bar
  inline def bar =
    class Baz extends W[Bar]
    new W[Bar]

def Test =
  A.foo[Int](0) // ok
  A.bar // ok

EugeneFlesselle avatar Jul 01 '24 15:07 EugeneFlesselle

It would be great to know if the changes break anything in the openCB, @WojciechMazur would it be possible to test that ?

EugeneFlesselle avatar Jul 02 '24 22:07 EugeneFlesselle

I've started the OpenCB, I'll report the results when it's done

WojciechMazur avatar Jul 03 '24 07:07 WojciechMazur

I've started the OpenCB, I'll report the results when it's done

Cool, thank you!

EugeneFlesselle avatar Jul 03 '24 07:07 EugeneFlesselle

We've tested 1591 projects, 61 of them were already failing in last week nightly (3.5.1-RC1-bin-20240626-41f1489-NIGHTLY) and there are no new regressions found since that nightly version

WojciechMazur avatar Jul 03 '24 12:07 WojciechMazur