@@ -577,6 +577,49 @@ trait Checking {
577
577
case _ =>
578
578
}
579
579
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
+
580
623
/** Check that `tp` is a class type and that any top-level type arguments in this type
581
624
* are feasible, i.e. that their lower bound conforms to their upper bound. If a type
582
625
* argument is infeasible, issue and error and continue with upper bound.
@@ -870,6 +913,8 @@ trait NoChecking extends ReChecking {
870
913
override def checkStable (tp : Type , pos : Position )(implicit ctx : Context ): Unit = ()
871
914
override def checkClassType (tp : Type , pos : Position , traitReq : Boolean , stablePrefixReq : Boolean )(implicit ctx : Context ): Type = tp
872
915
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 = ()
873
918
override def checkFeasibleParent (tp : Type , pos : Position , where : => String = " " )(implicit ctx : Context ): Type = tp
874
919
override def checkInlineConformant (tree : Tree , isFinal : Boolean , what : => String )(implicit ctx : Context ) = ()
875
920
override def checkNoDoubleDeclaration (cls : Symbol )(implicit ctx : Context ): Unit = ()
@@ -881,4 +926,5 @@ trait NoChecking extends ReChecking {
881
926
override def checkCaseInheritance (parentSym : Symbol , caseCls : ClassSymbol , pos : Position )(implicit ctx : Context ) = ()
882
927
override def checkNoForwardDependencies (vparams : List [ValDef ])(implicit ctx : Context ): Unit = ()
883
928
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 = ()
884
930
}
0 commit comments