diff options
author | Martin Odersky <odersky@gmail.com> | 2014-12-19 15:19:52 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-12-19 15:20:03 +0100 |
commit | 73d008317a6afaa0fea103ec0c84a39386f7d776 (patch) | |
tree | c310910675dae25f5bc24bf95fafd5b4ff6ed067 /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 53cd512eef8f9f28527e7c72d108359f0313d3f5 (diff) | |
download | dotty-73d008317a6afaa0fea103ec0c84a39386f7d776.tar.gz dotty-73d008317a6afaa0fea103ec0c84a39386f7d776.tar.bz2 dotty-73d008317a6afaa0fea103ec0c84a39386f7d776.zip |
Fix NoCyclicReference test
The problem was that, unlike a classDefSig, a higher-kinded typeDefSig did
not get a preset info with its type parameters. So any type-application
of the defined type in its bounds would fail.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 86376356c..323a1100b 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -673,7 +673,15 @@ class Namer { typer: Typer => def typeDefSig(tdef: TypeDef, sym: Symbol)(implicit ctx: Context): Type = { completeParams(tdef.tparams) - sym.info = TypeBounds.empty + val tparamSyms = tdef.tparams map symbolOfTree + val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree] + val toParameterize = tparamSyms.nonEmpty && !isDerived + val needsLambda = sym.allOverriddenSymbols.exists(_ is HigherKinded) && !isDerived + def abstracted(tp: Type): Type = + if (needsLambda) tp.LambdaAbstract(tparamSyms) + else if (toParameterize) tp.parameterizeWith(tparamSyms) + else tp + sym.info = abstracted(TypeBounds.empty) // Temporarily set info of defined type T to ` >: Nothing <: Any. // This is done to avoid cyclic reference errors for F-bounds. // This is subtle: `sym` has now an empty TypeBounds, but is not automatically @@ -684,18 +692,10 @@ class Namer { typer: Typer => // // The scheme critically relies on an implementation detail of isRef, which // inspects a TypeRef's info, instead of simply dealiasing alias types. - val tparamSyms = tdef.tparams map symbolOfTree - val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree] - val toParameterize = tparamSyms.nonEmpty && !isDerived - val needsLambda = sym.allOverriddenSymbols.exists(_ is HigherKinded) && !isDerived val rhsType = typedAheadType(tdef.rhs).tpe - def abstractedRhsType = - if (needsLambda) rhsType.LambdaAbstract(tparamSyms) - else if (toParameterize) rhsType.parameterizeWith(tparamSyms) - else rhsType val unsafeInfo = rhsType match { - case _: TypeBounds => abstractedRhsType.asInstanceOf[TypeBounds] - case _ => TypeAlias(abstractedRhsType, if (sym is Local) sym.variance else 0) + case _: TypeBounds => abstracted(rhsType).asInstanceOf[TypeBounds] + case _ => TypeAlias(abstracted(rhsType), if (sym is Local) sym.variance else 0) } sym.info = NoCompleter checkNonCyclic(sym, unsafeInfo, reportErrors = true) |