File tree 5 files changed +51
-13
lines changed
compiler/src/dotty/tools/dotc
5 files changed +51
-13
lines changed Original file line number Diff line number Diff line change @@ -948,11 +948,26 @@ class Definitions {
948
948
false
949
949
})
950
950
951
-
952
951
def functionArity (tp : Type )(implicit ctx : Context ) = tp.dealias.argInfos.length - 1
953
952
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
956
971
957
972
// ----- primitive value class machinery ------------------------------------------
958
973
Original file line number Diff line number Diff line change @@ -467,8 +467,8 @@ object ProtoTypes {
467
467
case et : ExprType =>
468
468
normalize(et.resultType, pt)
469
469
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
472
472
}
473
473
}
474
474
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
1678
1678
case _ => typedUnadapted(desugar(tree), pt)
1679
1679
}
1680
1680
1681
- if (defn.isImplicitFunctionType(pt) &&
1681
+ val ifpt = defn.asImplicitFunctionType(pt)
1682
+ if (ifpt.exists &&
1682
1683
xtree.isTerm &&
1683
1684
! untpd.isImplicitClosure(xtree) &&
1684
1685
! ctx.mode.is(Mode .ImplicitShadowing ) &&
1685
1686
! ctx.isAfterTyper)
1686
- makeImplicitFunction(xtree, pt )
1687
+ makeImplicitFunction(xtree, ifpt )
1687
1688
else xtree match {
1688
1689
case xtree : untpd.NameTree => typedNamed(xtree, pt)
1689
1690
case xtree => typedUnnamed(xtree)
Original file line number Diff line number Diff line change @@ -65,12 +65,6 @@ object Test extends App {
65
65
import Configs ._
66
66
import Exceptions ._
67
67
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
-
74
68
def readName : Configured [Possibly [Name ]] = {
75
69
val parts = config.name.split(" " )
76
70
require(parts.length >= 2 )
@@ -121,3 +115,18 @@ object OptionTest extends App {
121
115
println(readPerson(config1))
122
116
println(readPerson(config2))
123
117
}
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