File tree Expand file tree Collapse file tree 5 files changed +51
-13
lines changed
compiler/src/dotty/tools/dotc Expand file tree Collapse file tree 5 files changed +51
-13
lines changed Original file line number Diff line number Diff line change @@ -948,11 +948,26 @@ class Definitions {
948948 false
949949 })
950950
951-
952951 def functionArity (tp : Type )(implicit ctx : Context ) = tp.dealias.argInfos.length - 1
953952
954- def isImplicitFunctionType (tp : Type )(implicit ctx : Context ) =
955- isFunctionType(tp) && tp.dealias.typeSymbol.name.isImplicitFunction
953+ /** Return underlying immplicit function type (i.e. instance of an ImplicitFunctionN class)
954+ * or NoType if none exists. The following types are considered as underlying types:
955+ * - the alias of an alias type
956+ * - the instance or origin of a TypeVar (i.e. the result of a stripTypeVar)
957+ * - the upper bound of a TypeParamRef in the current constraint
958+ */
959+ def asImplicitFunctionType (tp : Type )(implicit ctx : Context ): Type =
960+ tp.stripTypeVar.dealias match {
961+ case tp1 : TypeParamRef if ctx.typerState.constraint.contains(tp1) =>
962+ asImplicitFunctionType(ctx.typeComparer.bounds(tp1).hiBound)
963+ case tp1 =>
964+ if (isFunctionType(tp1) && tp1.typeSymbol.name.isImplicitFunction) tp1
965+ else NoType
966+ }
967+
968+ /** Is `tp` an implicit function type? */
969+ def isImplicitFunctionType (tp : Type )(implicit ctx : Context ): Boolean =
970+ asImplicitFunctionType(tp).exists
956971
957972 // ----- primitive value class machinery ------------------------------------------
958973
Original file line number Diff line number Diff line change @@ -467,8 +467,8 @@ object ProtoTypes {
467467 case et : ExprType =>
468468 normalize(et.resultType, pt)
469469 case wtp =>
470- if ( defn.isImplicitFunctionType (wtp)) normalize(wtp.dealias.argInfos.last, pt )
471- else tp
470+ val iftp = defn.asImplicitFunctionType (wtp)
471+ if (iftp.exists) normalize(iftp.argInfos.last, pt) else tp
472472 }
473473 }
474474
Original file line number Diff line number Diff line change @@ -1678,12 +1678,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
16781678 case _ => typedUnadapted(desugar(tree), pt)
16791679 }
16801680
1681- if (defn.isImplicitFunctionType(pt) &&
1681+ val ifpt = defn.asImplicitFunctionType(pt)
1682+ if (ifpt.exists &&
16821683 xtree.isTerm &&
16831684 ! untpd.isImplicitClosure(xtree) &&
16841685 ! ctx.mode.is(Mode .ImplicitShadowing ) &&
16851686 ! ctx.isAfterTyper)
1686- makeImplicitFunction(xtree, pt )
1687+ makeImplicitFunction(xtree, ifpt )
16871688 else xtree match {
16881689 case xtree : untpd.NameTree => typedNamed(xtree, pt)
16891690 case xtree => typedUnnamed(xtree)
Original file line number Diff line number Diff line change @@ -65,12 +65,6 @@ object Test extends App {
6565 import Configs ._
6666 import Exceptions ._
6767
68- type PC [T ] = Possibly [Configured [T ]]
69-
70- val names : PC [List [Name ]] = readName :: Nil
71- val firstNames : PC [List [String ]] = names.map(_.first)
72- val longest : PC [String ] = firstNames.maxBy(_.length)
73-
7468 def readName : Configured [Possibly [Name ]] = {
7569 val parts = config.name.split(" " )
7670 require(parts.length >= 2 )
@@ -121,3 +115,18 @@ object OptionTest extends App {
121115 println(readPerson(config1))
122116 println(readPerson(config2))
123117}
118+
119+ object FancyStuff {
120+ import Configs ._
121+ import Exceptions ._
122+ import Test ._
123+
124+ type PC [T ] = Possibly [Configured [T ]]
125+
126+ val names : PC [List [Name ]] = readName :: Nil
127+ val firstNames : PC [List [String ]] = names.map(_.first)
128+ val longest : PC [String ] = firstNames.maxBy(_.length)
129+
130+ val xs : List [PC [String ]] = List (longest)
131+ val ys : PC [List [String ]] = xs.map(x => x)
132+ }
Original file line number Diff line number Diff line change 1+ object Test extends App {
2+
3+ case class C (x : Int )
4+ type IF [T ] = implicit C => T
5+
6+ val x : IF [Int ] = implicitly[C ].x
7+
8+ val xs0 : List [IF [Int ]] = List (implicit _ => x)
9+ val xs : List [IF [Int ]] = List (x)
10+ val ys : IF [List [Int ]] = xs.map(x => x)
11+ val zs = ys(C (22 ))
12+ assert(zs == List (22 ))
13+ }
You can’t perform that action at this time.
0 commit comments