Why is there a warning when scala.language.implicitConversions is not the last import?

In my Scala code, I have an implicit conversion, and I have the necessary import:

import scala.language.implicitConversions 

However, sometimes when another import is performed after this, I get a warning as if the import does not exist at all:

Warning: (112, 18) the implicit pair2Dimension conversion method must be enabled by making the implicit value scala.language.implicitConversions visible.

build.sbt:

 name := "ImplicitSBT" version := "1.0" scalaVersion := "2.11.5" scalacOptions ++= Seq("-deprecation","-feature") libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "1.0.1" 

Main.scala:

 import scala.language.implicitConversions import scala.swing.{Action, _} object Main extends App { implicit def pair2Dimension(pair: (Int, Int)): Dimension = new Dimension(pair._1, pair._2) val dim : Dimension = (0,0) println(dim) } 

Why is this happening? How does import scala.swing.{Action, _} hide implicitConversions import?

+7
import scala warnings implicit-conversion
source share
3 answers

How scala.swing is imported. {Action, _} hides the import of implicitConversions?

Your

 import scala.language.implicitConversions 

... gets the shadow image implicitConversions defined in the scala.swing package scala.swing :

 package scala ... package object swing { ... implicit lazy val implicitConversions = scala.language.implicitConversions ... } 

Since you are using wildcard import here:

 import scala.swing.{Action, _} 

... scala.swing.implicitConversions imported from scala.swing and at the end of the shadow is scala.language.implicitConversions .

An interesting question: why scalac cannot understand that a language function is enabled if in this case there are two “function flags” ( implicitConversions ), one shading the other at the same level.

This may be a mistake, as well as features of how SIP 18 is .

In any case, to solve this problem, I can suggest you to do one of the following:

  • do not import scala.language.implicitConversions (since it is already imported when scala.swing wildcard import)

  • do not import wildcards from scala.swing (do not pollute the scope and do not import what you need)

  • perform another import (which is not obscured by another) implicitConversions at the Main level of the object

+4
source share

As explained in

http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

importing wildcards (as you wrote) gives any implicit Swing definition a pretty high priority and that clearly hides yours.

Since you are compiling with SBT, it would be much easier to pass the following setting

 scalacOptions ++= Seq( "-feature", "-language:implicitConversions" ) 

and stop worrying about where to import scala.language.implicitConversions ?

+3
source share

This is an error in an implicit search.

Here is the same structure in more normal code where the execution context is required implicitly.

(It does not matter whether importing a wildcard from a package object or another package is in the same compilation unit.)

Since the code compiles with explicit global , it must compile with the implicit arg argument.

Implicit is available if it can be accessed without a prefix .

The priority of the binding does not depend on the order of the source code. Shadow works in the usual way; a binding never obscures a higher priority binding.

 /* package object bound2 { implicit lazy val global = scala.concurrent.ExecutionContext.Implicits.global } */ package bound2 { object B { implicit lazy val global: concurrent.ExecutionContextExecutor = scala.concurrent.ExecutionContext.global } } package bound { // the order of these imports in the same scope should not matter import scala.concurrent.ExecutionContext.Implicits.global import bound2.B._ object Test extends App { val f = concurrent.Future(42) //(global) // explicit arg works Console println concurrent.Await.result(f, concurrent.duration.Duration.Inf) } } 

In the sample specification 2.0.1, a line labeled “OK” is added, and you can verify that the order does not matter, but it becomes ambiguous in the inner scope because the “wildcard y” does not obscure “Explicit y” from external area:

  import Xy // `y' bound by explicit import println("L16: "+y) // `y' refers to `QXy' here import PX_ println("OK: "+y) // `y' refers to `QXy' here locally { val x = "abc" // `x' bound by local definition import PX_ // `x' and `y' bound by wildcard import // println("L19: "+y) // reference to `y' is ambiguous here 
+1
source share

All Articles