Skip to content

[PROOF-OF-CONCEPT/DO NOT MERGE] Avoid forcing type aliases to get their typeParams #981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions src/dotty/tools/dotc/core/TypeApplications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import util.Positions.Position
import config.Printers._
import collection.mutable
import java.util.NoSuchElementException
import ast.untpd.TypeDef
import typer.Namer

object TypeApplications {

Expand Down Expand Up @@ -63,7 +65,14 @@ class TypeApplications(val self: Type) extends AnyVal {
case self: TypeRef =>
val tsym = self.typeSymbol
if (tsym.isClass) tsym.typeParams
else if (tsym.isAliasType) self.underlying.typeParams
else if (tsym.isAliasType) {
tsym.infoOrCompleter match {
case c: Namer#Completer =>
c.typeParams(tsym)
case _ =>
self.underlying.typeParams
}
}
else {
val lam = LambdaClass(forcing = false)
if (lam.exists) lam.typeParams else Nil
Expand Down Expand Up @@ -200,6 +209,13 @@ class TypeApplications(val self: Type) extends AnyVal {
case nil => tp
}

def canForce(sym: Symbol) = sym.infoOrCompleter match {
case c: Namer#Completer =>
!sym.isAliasType
case _ =>
true
}

/** Instantiate type `tp` with `args`.
* @param original The original type for which we compute the type parameters
* This makes a difference for refinement types, because
Expand All @@ -209,7 +225,7 @@ class TypeApplications(val self: Type) extends AnyVal {
def instantiate(tp: Type, original: Type): Type = tp match {
case tp: TypeRef =>
val tsym = tp.symbol
if (tsym.isAliasType) tp.underlying.appliedTo(args)
if (tsym.isAliasType && canForce(tsym)) tp.underlying.appliedTo(args)
else {
val safeTypeParams =
if (tsym.isClass || !tp.typeSymbol.isCompleting) original.typeParams
Expand Down Expand Up @@ -242,7 +258,7 @@ class TypeApplications(val self: Type) extends AnyVal {
case tp: TypeRef =>
val sym = tp.symbol
if (sym.isClass) sym.isLambdaTrait
else !sym.isAliasType || isKnownHK(tp.info)
else !sym.isAliasType || !canForce(sym) || isKnownHK(tp.info)
case tp: TypeProxy => isKnownHK(tp.underlying)
case _ => false
}
Expand Down
26 changes: 23 additions & 3 deletions src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,8 @@ class Namer { typer: Typer =>

/** The completer of a symbol defined by a member def or import (except ClassSymbols) */
class Completer(val original: Tree)(implicit ctx: Context) extends LazyType {
var completedParams: Boolean = false
var nestedCtx: Context = null

protected def localContext(owner: Symbol) = ctx.fresh.setOwner(owner).setTree(original)

Expand All @@ -491,7 +493,9 @@ class Namer { typer: Typer =>
typer1.defDefSig(original, sym)(localContext(sym).setTyper(typer1))
case original: TypeDef =>
assert(!original.isClassDef)
typeDefSig(original, sym)(localContext(sym).setNewScope)
if (nestedCtx == null)
nestedCtx = localContext(sym).setNewScope
typeDefSig(original, sym, completedParams)(nestedCtx)
case imp: Import =>
try {
val expr1 = typedAheadExpr(imp.expr, AnySelectionProto)
Expand All @@ -503,6 +507,21 @@ class Namer { typer: Typer =>
}
}

def typeParams(sym: Symbol) = original match {
case tdef: TypeDef =>
if (nestedCtx == null)
nestedCtx = localContext(sym).setNewScope

{
implicit val ctx: Context = nestedCtx
if (!completedParams) {
completeParams(tdef.tparams)
completedParams = true
}
tdef.tparams map (symbolOfTree(_).asType)
}
}

final override def complete(denot: SymDenotation)(implicit ctx: Context) = {
if (completions != noPrinter && ctx.typerState != this.ctx.typerState) {
completions.println(completions.getClass.toString)
Expand Down Expand Up @@ -807,8 +826,9 @@ class Namer { typer: Typer =>
else valOrDefDefSig(ddef, sym, typeParams, paramSymss, wrapMethType)
}

def typeDefSig(tdef: TypeDef, sym: Symbol)(implicit ctx: Context): Type = {
completeParams(tdef.tparams)
def typeDefSig(tdef: TypeDef, sym: Symbol, completedParams: Boolean)(implicit ctx: Context): Type = {
if (!completedParams)
completeParams(tdef.tparams)
val tparamSyms = tdef.tparams map symbolOfTree
val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree]
//val toParameterize = tparamSyms.nonEmpty && !isDerived
Expand Down