Skip to content

Fix #4350: Do not check prefix of class type parameters #4363

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

Merged
merged 4 commits into from
Apr 27, 2018
Merged
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
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/quoted/TreeCleaner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ class TreeCleaner extends tpd.TreeMap {
/** List of symbols and their types for type aliases `type T = U` */
private[this] var aliasesSyms: List[Symbol] = Nil
private[this] var aliasesTypes: List[Type] = Nil
private[this] val aliases = newMutableSymbolMap[Tree]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file are not relevant to the fix right? BTW can we add a comment for the aliases var just for symmetry? 😛


override def transform(tree: Tree)(implicit ctx: Context): Tree = {
val tree0 = tree match {
case TypeDef(_, TypeBoundsTree(lo, hi)) if lo == hi =>
aliasesSyms = tree.symbol :: aliasesSyms
aliasesTypes = lo.tpe :: aliasesTypes
aliases(tree.symbol) = ref(lo.tpe.typeSymbol)
Literal(Constant(()))
case _ => tree
}
Expand All @@ -40,6 +42,7 @@ class TreeCleaner extends tpd.TreeMap {
case expr3 => Block(flatStats, expr3)
}
case tree1: TypeTree => TypeTree(tree1.tpe.subst(aliasesSyms, aliasesTypes))
case tree1: Ident => aliases.get(tree1.symbol).getOrElse(tree1)
case tree1 => tree1
}
}
Expand Down
14 changes: 9 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,10 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
explicitTags.clear()

// Maps type splices to type references of tags e.g., ~t -> some type T$1
val map: Map[Type, Type] = tagsExplicitTypeDefsPairs.map(x => (x._1, x._2.symbol.typeRef)).toMap
val map: Map[Type, Type] = {
tagsExplicitTypeDefsPairs.map(x => (x._1, x._2.symbol.typeRef)) ++
(itags.map(_._1) zip typeDefs.map(_.symbol.typeRef))
}.toMap
val tMap = new TypeMap() {
override def apply(tp: Type): Type = map.getOrElse(tp, mapOver(tp))
}
Expand Down Expand Up @@ -245,7 +248,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
l == level ||
sym.is(Inline) && sym.owner.is(Macro) && sym.info.isValueType && l - 1 == level
case None =>
true
level == 0
}

/** Issue a "splice outside quote" error unless we ar in the body of an inline method */
Expand Down Expand Up @@ -289,12 +292,12 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
if (!isThis) sym.show
else if (sym.is(ModuleClass)) sym.sourceModule.show
else i"${sym.name}.this"
if (!isThis && sym.maybeOwner.isType)
if (!isThis && sym.maybeOwner.isType && !sym.is(Param))
check(sym.owner, sym.owner.thisType, pos)
else if (sym.exists && !sym.isStaticOwner && !levelOK(sym))
for (errMsg <- tryHeal(tp, pos))
ctx.error(em"""access to $symStr from wrong staging level:
| - the definition is at level ${levelOf(sym)},
| - the definition is at level ${levelOf.getOrElse(sym, 0)},
| - but the access is at level $level.$errMsg""", pos)
}

Expand All @@ -313,7 +316,8 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
}
case tp: NamedType =>
check(tp.symbol, tp, pos)
foldOver(acc, tp)
if (!tp.symbol.is(Param))
foldOver(acc, tp)
case tp: ThisType =>
check(tp.cls, tp, pos)
foldOver(acc, tp)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ trait Implicits { self: Typer =>
}

def synthesizedTypeTag(formal: Type): Tree = formal.argInfos match {
case arg :: Nil =>
case arg :: Nil if !arg.typeSymbol.is(Param) =>
object bindFreeVars extends TypeMap {
var ok = true
def apply(t: Type) = t match {
Expand Down
5 changes: 5 additions & 0 deletions tests/neg/i4350.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import scala.quoted.Type

class Foo[T] {
'(null.asInstanceOf[T]) // error
}
5 changes: 5 additions & 0 deletions tests/pos/i4350.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import scala.quoted.Type

class Foo[T: Type] {
'(null.asInstanceOf[T])
}
6 changes: 6 additions & 0 deletions tests/run-with-compiler/i4350.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
null.asInstanceOf[Object]
}
{
null.asInstanceOf[String]
}
14 changes: 14 additions & 0 deletions tests/run-with-compiler/i4350.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import dotty.tools.dotc.quoted.Toolbox._

import scala.quoted.Type

class Foo[T: Type] {
def q = '(null.asInstanceOf[T])
}

object Test {
def main(args: Array[String]): Unit = {
println((new Foo[Object]).q.show)
println((new Foo[String]).q.show)
}
}