Some warnings in inlined code show up at the callsite
Opened this issue · 5 comments
Some warnings in inlined code show up at the callsite, some don't. It depends on the compiler phase in which the warning is issued. That seems arbitrary.
For example, this definition triggers two warnings:
scala> inline def foo = { 1; Stream(1).head }
2 warnings found
-- [E129] Potential Issue Warning: ---------------------------------------------
1 |inline def foo = { 1; Stream(1).head }
| ^
| A pure expression does nothing in statement position
|
| longer explanation available when compiling with `-explain`
-- Deprecation Warning: --------------------------------------------------------
1 |inline def foo = { 1; Stream(1).head }
| ^^^^^^
|value Stream in package scala is deprecated since 2.13.0: Use LazyList instead of Stream
def foo: IntOne of them shows up when using the inline method:
scala> foo
1 warning found
-- Deprecation Warning: --------------------------------------------------------
1 |inline def foo = { 1; Stream(1).head }
| ^^^^^^
|value Stream in package scala is deprecated since 2.13.0: Use LazyList instead of Stream
val res0: Int = 1The recent #22682 makes sure that messages filtered by @nowarn in the inline def don't leak to the callsite.
But does it ever make sense to see warnings in inlined code? Should that be configurable with a flag?
Sometimes it makes sense to have them, especially if we consider macros (where warnings can be dynamically created, either by directly reporting a warning, or creating a specific tree, and we only get those at the inline call site). It could be argued that the deprecation warning could be useful if we are using an inlined method from another library, where we would also only get that warning at a call site (but I don't know if that's a good argument). I agree it's probably currently a bit arbitrary which ones are supported, but there were certain checks/warnings already that were turned off for inline methods.
Somewhat amusingly, I wanted to show how useful a deprecation warning could be in the context of a macro, but I ended up with an issue ticket: #22795
I don't see the point of configuring that with a flag, especially that the way the reporter works now, duplicate warnings are not reported (so outside of repl, we would not see that second one).
especially if we consider macros
Scala 2 has, for unused warnings:
Usage: -Wmacros:<mode> where <mode> choices are none, before, after, both, default (default: default).
none Do not inspect expansions or their original trees when generating unused symbol warnings.
before Only inspect unexpanded user-written code for unused symbols.
after Only inspect expanded trees when generating unused symbol warnings.
both Inspect both user-written code and expanded trees when generating unused symbol warnings.
default Only inspect unexpanded user-written code for unused symbols but include usages in expansions.
duplicate warnings are not reported (so outside of repl, we would not see that second one).
If we have two files and compile the definition and the usage separately, the deprecation shows when compiling the usage.
The warning position could actually be pretty confusing for users. They will see a warning pointing to a source file that they don't actually have if the inline definition is in a dependency.
Porting -Wmacros is a TODO; there is commented code for hypothetical -Winlined.
My example for warning at call site is that implicit search can induce a warning. (The warning is context-dependent.)
I observed the "foreign position" problem but haven't given it thought.