Skip to content

Conversation

@mbovel
Copy link
Member

@mbovel mbovel commented Nov 18, 2025

Closes #24321.

This PR changes the type of inline vals to be the exact type of the right-hand side if it is a literal, such that in following snippet, x would have type (4: Int):

inline val x: Int = 4
> scalac -Xprint:typer test.scala
...
[[syntax trees at end of                     typer]] // test.scala
...
    inline val x: (4 : Int) = 4
...

Previously, it would not compile:

$ scala -S 3.7.3 test.scala
Compiling project (Scala 3.7.3, JVM (17))
[error] ./test.scala:1:15
[error] inline value must have a literal constant type
[error] inline val x: Int = 4
[error]               ^^^
Error compiling project (Scala 3.7.3, JVM (17))
Compilation failed

@mbovel mbovel force-pushed the mb/inline-val-refined branch 2 times, most recently from 6713020 to 1de787a Compare November 18, 2025 14:21
@mbovel
Copy link
Member Author

mbovel commented Nov 18, 2025

@sjrd do you think that would require a SIP?

@mbovel mbovel marked this pull request as ready for review November 18, 2025 19:35
@hamzaremmal hamzaremmal added the needs-minor-release This PR cannot be merged until the next minor release label Nov 18, 2025
@hamzaremmal
Copy link
Member

@sjrd do you think that would require a SIP?

At least a minor release.

@sjrd
Copy link
Member

sjrd commented Nov 19, 2025

It definitely needs a minor release.

In theory this is SIP material ... but IMO the SIP process is way too heavy for this. Let's add it to the next agenda, and hopefully there will be quick consensus.

Copy link
Member

@hamzaremmal hamzaremmal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we have just reused the tracked system?

Nevermind, but I think it's worth checking the interactions between the two.

@mbovel
Copy link
Member Author

mbovel commented Nov 19, 2025

I think it's worth checking the interactions between the two.

I added a test that checks that: https://github.com/dotty-staging/dotty/blob/345fcba592e8e9e276fc0cbcd4396682cb8739e7/tests/neg/inline-tracked-val.scala

@mbovel mbovel added the needs-squashing PR whose commits should be squashed by the author or via the "Squash and Merge" button label Nov 19, 2025
@odersky
Copy link
Contributor

odersky commented Nov 26, 2025

Not sure we have tests for these:

  1. What happens for inline val x = 100: Byte? This should be equivalent to inline val x: Byte = 100.
  2. What happens for inline val x: Byte = 1000? This should be a static error

@sjrd
Copy link
Member

sjrd commented Nov 26, 2025

Possible alternative: add the toX methods to the set of constant-foldable methods. This is equally (in)compatible, but has a smaller footprint on our overall spec. We can keep the general rule that an explicit type is a real boundary (from an elaboration perspective).

inline val x = 4.toByte

would thus be Byte(4).

@odersky
Copy link
Contributor

odersky commented Nov 26, 2025

The problem is that 1000.toByte would give -24 instead of a static error

@mbovel
Copy link
Member Author

mbovel commented Nov 26, 2025

1. What happens for inline val x = 100: Byte? This should be equivalent to inline val x: Byte = 100.

There is a test in inline-val.scala with Int, which currently expects a failure:

inline val a = 1 : Int // error

Should it pass? I guess it comes back to how powerful the constant-folding of the right-hand side should be. In #24431, I improved constant-folding for inline vals that are inside inline defs to go through ascriptions. We could use the same mechanism to type the right-hand side of inline vals that are not in inline defs as well. But that seems like a separate issue to me.

Note: this mechanism works on typed trees only, and we would need to adapt the untyped version for when there is an explicit ascription (#24321 (comment)), such as in:

inline val a: Int = 1 : Int

2. What happens for inline val x: Byte = 1000? This should be a static error

It is, I added a test.

@sjrd
Copy link
Member

sjrd commented Nov 26, 2025

Half of the time I want wrapping to be able to write 0xff as a Byte. Moreover, there is precedent with the other constant foldable operations: 2000000000 + 2000000000 folds without error as well.

@mbovel mbovel force-pushed the mb/inline-val-refined branch from 83ff0ff to f6cd021 Compare November 26, 2025 13:48
@mbovel mbovel added the needs-sip A SIP needs to be raised to move this issue/PR along. label Nov 26, 2025
@mbovel
Copy link
Member Author

mbovel commented Nov 27, 2025

Note from core meeting of 26.11.2025:

The change should go through a SIP process, since there is no consensus in the Core team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-minor-release This PR cannot be merged until the next minor release needs-sip A SIP needs to be raised to move this issue/PR along. needs-squashing PR whose commits should be squashed by the author or via the "Squash and Merge" button stat:do not merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wrong manipulation of byte constants

4 participants