@@ -577,6 +577,49 @@ trait Checking {
577577 case _ =>
578578 }
579579
580+ /** If `sym` is an implicit conversion, check that implicit conversions are enabled.
581+ * @pre sym.is(Implicit)
582+ */
583+ def checkImplicitConversionDefOK (sym : Symbol )(implicit ctx : Context ): Unit = sym.info.stripPoly match {
584+ case mt @ MethodType (_ :: Nil )
585+ if ! mt.isImplicitMethod && ! sym.is(Synthetic ) => // it's a conversion
586+ checkFeature(
587+ defn.LanguageModuleClass , nme.implicitConversions,
588+ i " Definition of implicit conversion $sym" ,
589+ ctx.owner.topLevelClass,
590+ sym.pos)
591+ case _ =>
592+ }
593+
594+ /** If `sym` is an implicit conversion, check that that implicit conversions are enabled, unless
595+ * - it is synthetic
596+ * - it is has the same owner as one of the classes it converts to (modulo companions)
597+ * - it is defined in Predef
598+ * - it is the scala.reflect.Selectable.reflectiveSelectable conversion
599+ */
600+ def checkImplicitConversionUseOK (sym : Symbol , pos : Position )(implicit ctx : Context ): Unit = {
601+ val conversionOK =
602+ ! sym.exists ||
603+ sym.is(Synthetic ) ||
604+ sym.info.finalResultType.classSymbols.exists(_.owner.isLinkedWith(sym.owner)) ||
605+ defn.isPredefClass(sym.owner) ||
606+ sym.name == nme.reflectiveSelectable && sym.maybeOwner.maybeOwner.maybeOwner == defn.ScalaPackageClass
607+ if (! conversionOK)
608+ checkFeature(defn.LanguageModuleClass , nme.implicitConversions,
609+ i " Use of implicit conversion ${sym.showLocated}" , NoSymbol , pos)
610+ }
611+
612+ /** Issue a feature warning if feature is not enabled */
613+ def checkFeature (base : ClassSymbol ,
614+ name : TermName ,
615+ description : => String ,
616+ featureUseSite : Symbol ,
617+ pos : Position )(implicit ctx : Context ): Unit =
618+ if (! ctx.featureEnabled(base, name))
619+ ctx.featureWarning(name.toString, description,
620+ isScala2Feature = base.isContainedIn(defn.LanguageModuleClass ),
621+ featureUseSite, required = false , pos)
622+
580623 /** Check that `tp` is a class type and that any top-level type arguments in this type
581624 * are feasible, i.e. that their lower bound conforms to their upper bound. If a type
582625 * argument is infeasible, issue and error and continue with upper bound.
@@ -870,6 +913,8 @@ trait NoChecking extends ReChecking {
870913 override def checkStable (tp : Type , pos : Position )(implicit ctx : Context ): Unit = ()
871914 override def checkClassType (tp : Type , pos : Position , traitReq : Boolean , stablePrefixReq : Boolean )(implicit ctx : Context ): Type = tp
872915 override def checkImplicitParamsNotSingletons (vparamss : List [List [ValDef ]])(implicit ctx : Context ): Unit = ()
916+ override def checkImplicitConversionDefOK (sym : Symbol )(implicit ctx : Context ): Unit = ()
917+ override def checkImplicitConversionUseOK (sym : Symbol , pos : Position )(implicit ctx : Context ): Unit = ()
873918 override def checkFeasibleParent (tp : Type , pos : Position , where : => String = " " )(implicit ctx : Context ): Type = tp
874919 override def checkInlineConformant (tree : Tree , isFinal : Boolean , what : => String )(implicit ctx : Context ) = ()
875920 override def checkNoDoubleDeclaration (cls : Symbol )(implicit ctx : Context ): Unit = ()
@@ -881,4 +926,5 @@ trait NoChecking extends ReChecking {
881926 override def checkCaseInheritance (parentSym : Symbol , caseCls : ClassSymbol , pos : Position )(implicit ctx : Context ) = ()
882927 override def checkNoForwardDependencies (vparams : List [ValDef ])(implicit ctx : Context ): Unit = ()
883928 override def checkMembersOK (tp : Type , pos : Position )(implicit ctx : Context ): Type = tp
929+ override def checkFeature (base : ClassSymbol , name : TermName , description : => String , featureUseSite : Symbol , pos : Position )(implicit ctx : Context ): Unit = ()
884930}
0 commit comments