Skip to content

Commit ff96e56

Browse files
authored
Merge pull request #4128 from dotty-staging/fix/implicit-erased-funs
Various fixes for implicit/erased function types
2 parents eeff384 + f66660a commit ff96e56

File tree

9 files changed

+56
-17
lines changed

9 files changed

+56
-17
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ Standard-Section: "ASTs" TopLevelStat*
163163
BYNAMEtype underlying_Type
164164
PARAMtype Length binder_ASTref paramNum_Nat
165165
POLYtype Length result_Type NamesTypes
166-
METHODtype Length result_Type NamesTypes // needed for refinements
166+
methodType(_, _) Length result_Type NamesTypes // needed for refinements
167167
TYPELAMBDAtype Length result_Type NamesTypes // variance encoded in front of name: +/-/(nothing)
168168
SHAREDtype type_ASTRef
169169
NamesTypes = NameType*
@@ -226,7 +226,7 @@ Standard Section: "Positions" Assoc*
226226
object TastyFormat {
227227

228228
final val header = Array(0x5C, 0xA1, 0xAB, 0x1F)
229-
val MajorVersion = 4
229+
val MajorVersion = 5
230230
val MinorVersion = 0
231231

232232
/** Tags used to serialize names */
@@ -392,14 +392,28 @@ object TastyFormat {
392392
final val ANDtpt = 165
393393
final val ORtype = 166
394394
final val ORtpt = 167
395-
final val METHODtype = 168
396-
final val POLYtype = 169
397-
final val TYPELAMBDAtype = 170
398-
final val LAMBDAtpt = 171
399-
final val PARAMtype = 172
400-
final val ANNOTATION = 173
401-
final val TERMREFin = 174
402-
final val TYPEREFin = 175
395+
final val POLYtype = 168
396+
final val TYPELAMBDAtype = 169
397+
final val LAMBDAtpt = 170
398+
final val PARAMtype = 171
399+
final val ANNOTATION = 172
400+
final val TERMREFin = 173
401+
final val TYPEREFin = 174
402+
403+
// In binary: 101100EI
404+
// I = implicit method type
405+
// E = erased method type
406+
final val METHODtype = 176
407+
final val IMPLICITMETHODtype = 177
408+
final val ERASEDMETHODtype = 178
409+
final val ERASEDIMPLICITMETHODtype = 179
410+
411+
def methodType(isImplicit: Boolean = false, isErased: Boolean = false) = {
412+
val implicitOffset = if (isImplicit) 1 else 0
413+
val erasedOffset = if (isErased) 2 else 0
414+
METHODtype + implicitOffset + erasedOffset
415+
}
416+
403417
final val HOLE = 255
404418

405419
final val firstSimpleTreeTag = UNITconst
@@ -588,6 +602,9 @@ object TastyFormat {
588602
case BYNAMEtpt => "BYNAMEtpt"
589603
case POLYtype => "POLYtype"
590604
case METHODtype => "METHODtype"
605+
case IMPLICITMETHODtype => "IMPLICITMETHODtype"
606+
case ERASEDMETHODtype => "ERASEDMETHODtype"
607+
case ERASEDIMPLICITMETHODtype => "ERASEDIMPLICITMETHODtype"
591608
case TYPELAMBDAtype => "TYPELAMBDAtype"
592609
case LAMBDAtpt => "LAMBDAtpt"
593610
case PARAMtype => "PARAMtype"

compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
8484
}
8585
else if (tag >= firstNatASTTreeTag) {
8686
tag match {
87-
case IDENT | IDENTtpt | SELECT | TERMREF | TYPEREF | SELFDEF => printName()
87+
case IDENT | IDENTtpt | SELECT | SELECTtpt | TERMREF | TYPEREF | SELFDEF => printName()
8888
case _ => printNat()
8989
}
9090
printTree()

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class TreePickler(pickler: TastyPickler) {
251251
case tpe: PolyType if richTypes =>
252252
pickleMethodic(POLYtype, tpe)
253253
case tpe: MethodType if richTypes =>
254-
pickleMethodic(METHODtype, tpe)
254+
pickleMethodic(methodType(isImplicit = tpe.isImplicitMethod, isErased = tpe.isErasedMethod), tpe)
255255
case tpe: ParamRef =>
256256
assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe")
257257
case tpe: LazyRef =>

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,12 @@ class TreeUnpickler(reader: TastyReader,
287287
readMethodic(PolyType, _.toTypeName)
288288
case METHODtype =>
289289
readMethodic(MethodType, _.toTermName)
290+
case IMPLICITMETHODtype =>
291+
readMethodic(ImplicitMethodType, _.toTermName)
292+
case ERASEDMETHODtype =>
293+
readMethodic(ErasedMethodType, _.toTermName)
294+
case ERASEDIMPLICITMETHODtype =>
295+
readMethodic(ErasedImplicitMethodType, _.toTermName)
290296
case TYPELAMBDAtype =>
291297
readMethodic(HKTypeLambda, _.toTypeName)
292298
case PARAMtype =>

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,8 @@ object Parsers {
759759
case Ident(name) if name != tpnme.WILDCARD && in.token == COLON =>
760760
isValParamList = true
761761
funArgTypesRest(
762-
typedFunParam(paramStart, name.toTermName),
763-
() => typedFunParam(in.offset, ident()))
762+
typedFunParam(paramStart, name.toTermName, imods),
763+
() => typedFunParam(in.offset, ident(), imods))
764764
case t =>
765765
funArgTypesRest(t, funArgType)
766766
}
@@ -800,9 +800,9 @@ object Parsers {
800800
}
801801

802802
/** TypedFunParam ::= id ':' Type */
803-
def typedFunParam(start: Offset, name: TermName): Tree = atPos(start) {
803+
def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): Tree = atPos(start) {
804804
accept(COLON)
805-
makeParameter(name, typ(), Modifiers(Param))
805+
makeParameter(name, typ(), mods | Param)
806806
}
807807

808808
/** InfixType ::= RefinedType {id [nl] refinedType}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ class Typer extends Namer
777777
completeParams(params)
778778
val params1 = params.map(typedExpr(_).asInstanceOf[ValDef])
779779
val resultTpt = typed(body)
780-
val companion = if (isImplicit) ImplicitMethodType else MethodType
780+
val companion = MethodType.maker(isImplicit = isImplicit, isErased = isErased)
781781
val mt = companion.fromSymbols(params1.map(_.symbol), resultTpt.tpe)
782782
if (mt.isParamDependent)
783783
ctx.error(i"$mt is an illegal function type because it has inter-parameter dependencies", tree.pos)

compiler/test/dotty/tools/dotc/FromTastyTests.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class FromTastyTests extends ParallelTesting {
4646
// Type miss match after unpickling
4747
"hklub0.scala",
4848

49+
// Closure type miss match
50+
"i4125.scala",
51+
4952
// Missing position
5053
"t1203a.scala",
5154
"t2260.scala",

tests/pos/i4125.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test {
2+
def foo: (erased (x: Int, y: Int) => Int) = erased (x, y) => 1
3+
def bar: (erased implicit (x: Int, y: Int) => Int) = erased implicit (x, y) => 1
4+
}

tests/pos/implicit-dep.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait HasT {
2+
type T
3+
}
4+
5+
object Test {
6+
7+
8+
def foo: implicit Int => implicit (g: HasT) => g.T = ???
9+
}

0 commit comments

Comments
 (0)