-
Notifications
You must be signed in to change notification settings - Fork 21
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
Unexpected literal widening without a Singleton upperbound (post-SIP23) #10838
Comments
/cc @milessabin |
It sounds like you'd want For a trickier case in Dotty, see scala/scala3#4032 and |
How is it different than the following code?
I don't see why see why literal singleton widening should be semantically different than singleton object widening. |
Currently I have a macro that enforces this for singleton-ops. It checks the tree of an argument instead if the type, and the tree preserves the true narrowness. Why shouldn't this be a language feature? |
Did I say the semantics makes sense? No. But I'm talking about compatible changes. Your macro is compatible because it doesn't modify existing behavior. If somebody changes it now, would somebody volunteer to fix any community build breakage? FWIW, historically, you needed object's singleton types to use objects for modules. And even now, for a generic |
That for me felt like something that should have been changed as part of the SIP. I'm not hung on changing the current semantics. I can accept other alternatives. One that I suggested was a |
No objection to other keywords. I think such annotations might be preferrable to |
@alexknvl has caused problems with When would |
As I understand it:
And while were at it, I would also add |
@hrhino right, that's what I was hinting at, sorry for forgetting attribution to @alexknvl I just had forgot.
Yeah that was the idea, which was built for the use-case in the OP, since @soronpo's OP is essentially asking for something like def fooInt[@narrow T <: Int](t : T) : T = t
val x: Int = 3
fooInt(3) // Infers fooInt[3](3)
fooInt(x) // Infers fooInt[Int](3) Given that this is just "don't widen the argument", it's not unreasonable. But I'm now wondering whether the annotation should be placed on the argument whose type you want inferred: def fooInt[T <: Int](x : T @narrow) : T = x
// semantics here:
// given a call `fooInt(t)`, infer the type `T` of `t` using the typer without an expected type (that is, in "synthesis" mode) and without any widening, check if the inferred type respects the bounds for type variable `T`, and output `fooInt[T](t)` But here's a trick question: what's the type inference semantics of |
|
that's a rough question indeed. In the absence of variance it's probably meaningless, because the type of def bar[@narrow T <: Int](xs: List[T]): List[T] = xs
bar(1 :: Nil) // is this List[1] or List[Int]?
def baz[@narrow T <: Int](f: T => Unit): T => Unit = f
baz((_ : 1) => ()) // this would have to be 1 => Unit
// is there a case where contravariance makes a difference? |
There is no conflict. The constructor for |
Well, in your example that's not "the narrowest type to match the bounds" — that's a nice declarative specification that produces |
So maybe the correct word is def foo[T](@preserve t : T) : T = t
foo(1)
foo(1 :: Nil) is equivalent to: def foo[T](t : T) : T = t // or def foo[T](t : T) : t.type = t ?
final val one = 1
final val oneL = 1 :: Nil
foo(one)
foo(oneL) |
@soronpo I picked up this issue from scala/scala3#4944. No progress for a long time so I am thinking maybe your macro will solve my use case. Does it work for RC1 and later? Can I use it in my code (license)? If so, were can I access it? TIA |
The macro madness is currently only implemented for Scala 2. It's relying on implicit conversions that Odersky is fan on eliminating. Don't know what the future of it will be. I think the language should change to allow us express 'exact' types without this hassle. |
Consider the following behavior, post SIP23 implementation.
The above forces the user to express two different functions, if the narrow literal type information needs to be preserved, in case a literal is used.
Can this be considered a bug? To resolve this we need to either change the widening semantics or add some kind of language construct that forces the narrowed type.
also discussed briefly at: https://gitter.im/typelevel/scala?at=5ad895596bbe1d273902766d
The text was updated successfully, but these errors were encountered: