Skip to content

Commit 977f8ff

Browse files
committed
Fix dependent function type building
Need to record function modifiers in parameters, or they will get lost in pickling. Fixes failing pickling test pos/depfuntype.scala.
1 parent b5c525d commit 977f8ff

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -757,26 +757,27 @@ class Typer extends Namer
757757

758758
def typedFunctionType(tree: untpd.Function, pt: Type)(implicit ctx: Context): Tree = {
759759
val untpd.Function(args, body) = tree
760-
val (isContextual, isErased) = tree match {
761-
case tree: untpd.FunctionWithMods =>
762-
val isContextual = tree.mods.is(Contextual)
763-
var isErased = tree.mods.is(Erased)
764-
if (isErased && args.isEmpty) {
765-
ctx.error("An empty function cannot not be erased", tree.pos)
766-
isErased = false
767-
}
768-
(isContextual, isErased)
769-
case _ => (false, false)
760+
var funFlags = tree match {
761+
case tree: untpd.FunctionWithMods => tree.mods.flags
762+
case _ => EmptyFlags
763+
}
764+
if (funFlags.is(Erased) && args.isEmpty) {
765+
ctx.error("An empty function cannot not be erased", tree.pos)
766+
funFlags = funFlags &~ Erased
770767
}
771768

772-
val funCls = defn.FunctionClass(args.length, isContextual, isErased)
769+
val funCls = defn.FunctionClass(args.length,
770+
isContextual = funFlags.is(Contextual), isErased = funFlags.is(Erased))
773771

774772
/** Typechecks dependent function type with given parameters `params` */
775773
def typedDependent(params: List[ValDef])(implicit ctx: Context): Tree = {
776774
completeParams(params)
777775
val params1 = params.map(typedExpr(_).asInstanceOf[ValDef])
776+
if (!funFlags.isEmpty)
777+
params1.foreach(_.symbol.setFlag(funFlags))
778778
val resultTpt = typed(body)
779-
val companion = MethodType.maker(isContextual = isContextual, isErased = isErased)
779+
val companion = MethodType.maker(
780+
isContextual = funFlags.is(Contextual), isErased = funFlags.is(Erased))
780781
val mt = companion.fromSymbols(params1.map(_.symbol), resultTpt.tpe)
781782
if (mt.isParamDependent)
782783
ctx.error(i"$mt is an illegal function type because it has inter-parameter dependencies", tree.pos)
@@ -2271,6 +2272,7 @@ class Typer extends Namer
22712272

22722273
def adaptToArgs(wtp: Type, pt: FunProto): Tree = wtp match {
22732274
case wtp: MethodOrPoly =>
2275+
def methodStr = methPart(tree).symbol.showLocated
22742276
if (matchingApply(wtp, pt))
22752277
if (pt.args.lengthCompare(1) > 0 && isUnary(wtp) && ctx.canAutoTuple)
22762278
adapt(tree, pt.tupled, locked)
@@ -2279,7 +2281,7 @@ class Typer extends Namer
22792281
else if (wtp.isContextual)
22802282
adaptNoArgs(wtp) // insert arguments implicitly
22812283
else
2282-
errorTree(tree, em"Missing arguments for ${methPart(tree).symbol.showLocated}")
2284+
errorTree(tree, em"Missing arguments for $methodStr")
22832285
case _ => tryInsertApplyOrImplicit(tree, pt, locked) {
22842286
errorTree(tree, MethodDoesNotTakeParameters(tree))
22852287
}

compiler/test-resources/repl/3932

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
scala> def fun[T](x: T): implicit List[T] => Int = ???
2-
def fun[T](x: T): implicit List[T] => Int
1+
scala> def fun[T](x: T): List[T] |=> Int = ???
2+
def fun[T](x: T): List[T] |=> Int

0 commit comments

Comments
 (0)