Skip to content
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

incorrect "implicit numeric widening" warning when evaluating expression #8450

Closed
scabug opened this issue Mar 26, 2014 · 5 comments
Closed
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Mar 26, 2014

when compiling with the scalac option -Ywarn-numeric-widen we get the following odd warning if the expression is not made up of already evaluated numeric terms:

scala> trait Foo
defined trait Foo

scala> implicit class FooLong(l: Long) { def foo = new Foo {} }
defined class FooLong

scala>  def elapsed: Foo = (System.nanoTime - 100L).foo
elapsed: Foo

scala> implicit class FooDouble(d: Double) { def foo = new Foo {} }
defined class FooDouble

scala>  def elapsed: Foo = (System.nanoTime - 100L).foo
<console>:41: warning: implicit numeric widening
        def elapsed: Foo = (System.nanoTime - 100L).foo
                                            ^
elapsed: Foo

scala>  def elapsed: Foo = { val t = (System.nanoTime - 100L); t.foo }
elapsed: Foo

This last one shows that if the expression is assigned then Long is inferred and the typer doesn't complain. But the expression is clearly of the specific type Long, and the warning is unintuitive at best.

This originally came up with the following code:

import scala.concurrent.duration._

class Stopwatch(val start: Long = System.nanoTime) extends AnyVal {
  def elapsed: Duration = ((System.nanoTime - start) / 1000).micros
}
@scabug
Copy link
Author

scabug commented Mar 26, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8450?orig=1
Reporter: Jed Wesley-Smith (jedws)
Affected Versions: 2.10.3, 2.10.4, 2.11.0-RC3

@scabug
Copy link
Author

scabug commented Mar 27, 2014

@adriaanm said:
Interesting. The warning seems to be triggered when trying the FooDouble implicit, even though it doesn't end up being chosen. With -Ywarn-numeric-widen -Ytyper-debug -Xlog-implicits -Xprompt:

|-- System.nanoTime.$minus(100L).foo : pt=Foo EXPRmode (site: method elapsed in $iw) 
|    |-- System.nanoTime.$minus(100L) EXPRmode-POLYmode-QUALmode (site: method elapsed in $iw) 
|    |    |-- System.nanoTime.$minus BYVALmode-EXPRmode-FUNmode-POLYmode (silent: method elapsed in $iw) 
|    |    |    |-- System.nanoTime EXPRmode-POLYmode-QUALmode (silent: method elapsed in $iw) 
|    |    |    |    |-- System EXPRmode-POLYmode-QUALmode (silent: method elapsed in $iw) 
|    |    |    |    |    \-> System.type
|    |    |    |    |-- ()Long EXPRmode (silent: method elapsed in $iw) 
|    |    |    |    |    \-> Long
|    |    |    |    [adapt] ()Long adapted to ()Long
|    |    |    |    \-> Long
|    |    |    \-> (x: Double)Double <and> (x: Float)Float <and> (x: Long)Long <and> (x: Int)Long <and> (x: Char)Long <and> (x: Short)Long <and> (x: Byte)Long
|    |    |-- 100L BYVALmode-EXPRmode (silent: method elapsed in $iw) 
|    |    |    \-> Long(100L)
|    |    \-> Long
|    |-- FooDouble BYVALmode-EXPRmode-FUNmode-POLYmode (silent: method elapsed in $iw) implicits disabled
|    |    \-> (d: Double)FooDouble
<console>:10: warning: implicit numeric widening
       def elapsed: Foo = (System.nanoTime - 100L).foo
                                           ^
|    |-- <argument>.toDouble : pt=Double BYVALmode-EXPRmode (silent: method elapsed in $iw) implicits disabled
|    |    \-> Double
|    [adapt] FooDouble adapted to (d: Double)FooDouble based on pt Long => ?{def foo: ?}
|    |-- FooLong BYVALmode-EXPRmode-FUNmode-POLYmode (silent: method elapsed in $iw) implicits disabled
|    |    \-> (l: Long)FooLong
|    [adapt] FooLong adapted to (l: Long)FooLong based on pt Long => ?{def foo: ?}
$read.$iw.$iw.FooLong, ) List(), List(), List()
|    |-- (l: Long)FooLong EXPRmode-POLYmode-QUALmode (silent: method elapsed in $iw) 
|    |    \-> FooLong
|    |-- $line4.$read.$iw.$iw.FooLong(java.this.lang.System.nanoTi... : pt=Foo EXPRmode (site: method elapsed in $iw) 

@scabug
Copy link
Author

scabug commented Mar 27, 2014

@adriaanm said:
Ah, context.unit.warning is used, which doesn't consider whether we're in silent mode. I believe it should be context.warning.

@scabug
Copy link
Author

scabug commented Mar 27, 2014

@adriaanm said:
scala/scala#3658

@scabug
Copy link
Author

scabug commented Mar 27, 2014

@jrudolph said:
(Sorry for the noise, I seemed to change a field just by clicking around, reverted the change)

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

No branches or pull requests

2 participants