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 @@ -942,11 +942,26 @@ class Definitions {
942
942
false
943
943
})
944
944
945
-
946
945
def functionArity (tp : Type )(implicit ctx : Context ) = tp.dealias.argInfos.length - 1
947
946
948
- def isImplicitFunctionType (tp : Type )(implicit ctx : Context ) =
949
- isFunctionType(tp) && tp.dealias.typeSymbol.name.isImplicitFunction
947
+ /** Return underlying immplicit function type (i.e. instance of an ImplicitFunctionN class)
948
+ * or NoType if none exists. The following types are considered as underlying types:
949
+ * - the alias of an alias type
950
+ * - the instance or origin of a TypeVar (i.e. the result of a stripTypeVar)
951
+ * - the upper bound of a TypeParamRef in the current constraint
952
+ */
953
+ def asImplicitFunctionType (tp : Type )(implicit ctx : Context ): Type =
954
+ tp.stripTypeVar.dealias match {
955
+ case tp1 : TypeParamRef if ctx.typerState.constraint.contains(tp1) =>
956
+ asImplicitFunctionType(ctx.typeComparer.bounds(tp1).hiBound)
957
+ case tp1 =>
958
+ if (isFunctionType(tp1) && tp1.typeSymbol.name.isImplicitFunction) tp1
959
+ else NoType
960
+ }
961
+
962
+ /** Is `tp` an implicit function type? */
963
+ def isImplicitFunctionType (tp : Type )(implicit ctx : Context ): Boolean =
964
+ asImplicitFunctionType(tp).exists
950
965
951
966
// ----- primitive value class machinery ------------------------------------------
952
967
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 @@ -1668,12 +1668,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1668
1668
case _ => typedUnadapted(desugar(tree), pt)
1669
1669
}
1670
1670
1671
- if (defn.isImplicitFunctionType(pt) &&
1671
+ val ifpt = defn.asImplicitFunctionType(pt)
1672
+ if (ifpt.exists &&
1672
1673
xtree.isTerm &&
1673
1674
! untpd.isImplicitClosure(xtree) &&
1674
1675
! ctx.mode.is(Mode .ImplicitShadowing ) &&
1675
1676
! ctx.isAfterTyper)
1676
- makeImplicitFunction(xtree, pt )
1677
+ makeImplicitFunction(xtree, ifpt )
1677
1678
else xtree match {
1678
1679
case xtree : untpd.NameTree => typedNamed(xtree, pt)
1679
1680
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