Skip to content

Commit 987c590

Browse files
committed
Add assignType for RefinedTypeTrees
If we want to pickle type trees, we need a type assigner for RefinedTypeTree.
1 parent 28c2e04 commit 987c590

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,18 @@ trait TypeAssigner {
431431
def assignType(tree: untpd.OrTypeTree, left: Tree, right: Tree)(implicit ctx: Context) =
432432
tree.withType(left.tpe | right.tpe)
433433

434-
// RefinedTypeTree is missing, handled specially in Typer and Unpickler.
434+
/** Assign type of RefinedType.
435+
* Refinements are typed as if they were members of refinement class `refineCls`.
436+
*/
437+
def assignType(tree: untpd.RefinedTypeTree, parent: Tree, refinements: List[Tree], refineCls: ClassSymbol)(implicit ctx: Context) = {
438+
def addRefinement(parent: Type, refinement: Tree): Type = {
439+
val rsym = refinement.symbol
440+
val rinfo = if (rsym is Accessor) rsym.info.resultType else rsym.info
441+
RefinedType(parent, rsym.name, rinfo)
442+
}
443+
val refined = (parent.tpe /: refinements)(addRefinement)
444+
tree.withType(RecType.closeOver(rt => refined.substThis(refineCls, RecThis(rt))))
445+
}
435446

436447
def assignType(tree: untpd.AppliedTypeTree, tycon: Tree, args: List[Tree])(implicit ctx: Context) = {
437448
val tparams = tycon.tpe.typeParams

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,23 +1008,16 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
10081008
val refineCls = createSymbol(refineClsDef).asClass
10091009
val TypeDef(_, impl: Template) = typed(refineClsDef)
10101010
val refinements1 = impl.body
1011-
val seen = mutable.Set[Symbol]()
10121011
assert(tree.refinements.length == refinements1.length, s"${tree.refinements} != $refinements1")
1013-
def addRefinement(parent: Type, refinement: Tree): Type = {
1012+
val seen = mutable.Set[Symbol]()
1013+
for (refinement <- refinements1) { // TODO: get clarity whether we want to enforce these conditions
10141014
typr.println(s"adding refinement $refinement")
10151015
checkRefinementNonCyclic(refinement, refineCls, seen)
10161016
val rsym = refinement.symbol
10171017
if (rsym.is(Method) && rsym.allOverriddenSymbols.isEmpty)
1018-
ctx.error(i"refinement $rsym without matching type in parent $parent", refinement.pos)
1019-
val rinfo = if (rsym is Accessor) rsym.info.resultType else rsym.info
1020-
RefinedType(parent, rsym.name, rinfo)
1021-
// todo later: check that refinement is within bounds
1018+
ctx.error(i"refinement $rsym without matching type in parent $tpt1", refinement.pos)
10221019
}
1023-
val refined = (tpt1.tpe /: refinements1)(addRefinement)
1024-
val res = cpy.RefinedTypeTree(tree)(tpt1, refinements1).withType(
1025-
RecType.closeOver(rt => refined.substThis(refineCls, RecThis(rt))))
1026-
typr.println(i"typed refinement: ${res.tpe}")
1027-
res
1020+
assignType(cpy.RefinedTypeTree(tree)(tpt1, refinements1), tpt1, refinements1, refineCls)
10281021
}
10291022

10301023
def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): Tree = track("typedAppliedTypeTree") {

0 commit comments

Comments
 (0)