8000 Proof of concept fix for SI-7046 · scala/scala@facf243 · GitHub
[go: up one dir, main page]

Skip to content

Commit facf243

Browse files
committed
Proof of concept fix for SI-7046
1 parent 4e564ef commit facf243

File tree

7 files changed

+90
-11
lines changed

7 files changed

+90
-11
lines changed

src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,9 +654,6 @@ trait ContextErrors {
654654
def ParentFinalInheritanceError(parent: Tree, mixin: Symbol) =
655655
NormalTypeError(parent, "illegal inheritance from final "+mixin)
656656

657-
def ParentSealedInheritanceError(parent: Tree, psym: Symbol) =
658-
NormalTypeError(parent, "illegal inheritance from sealed " + psym )
659-
660657
def ParentSelfTypeConformanceError(parent: Tree, selfType: Type) =
661658
NormalTypeError(parent,
662659
"illegal inheritance;\n self-type "+selfType+" does not conform to "+
@@ -1175,6 +1172,9 @@ trait ContextErrors {
11751172
def MissingParameterOrValTypeError(vparam: Tree) =
11761173
issueNormalTypeError(vparam, "missing parameter type")
11771174

1175+
def ParentSealedInheritanceError(parent: Tree, psym: Symbol) =
1176+
NormalTypeError(parent, "illegal inheritance from sealed " + psym )
1177+
11781178
def RootImportError(tree: Tree) =
11791179
issueNormalTypeError(tree, "_root_ cannot be imported")
11801180

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,12 +907,33 @@ trait Namers extends MethodSynthesis {
907907

908908
private def templateSig(templ: Template): Type = {
909909
val clazz = context.owner
910+
911+
val parentTrees = typer.typedParentTypes(templ)
912+
913+
val pending = mutable.ListBuffer[AbsTypeError]()
914+
parentTrees foreach { tpt =>
915+
val ptpe = tpt.tpe
916+
if(!ptpe.isError) {
917+
val psym = ptpe.typeSymbol
918+
val sameSourceFile = context.unit.source.file == psym.sourceFile
919+
920+
if (psym.isSealed && !phase.erasedTypes)
921+
if (sameSourceFile)
922+
psym addChild context.owner
923+
else
924+
pending += ParentSealedInheritanceError(tpt, psym)
925+
if (psym.isLocalToBlock && !phase.erasedTypes)
926+
psym addChild context.owner
927+
}
928+
}
929+
pending.foreach(ErrorUtils.issueTypeError)
930+
910931
def checkParent(tpt: Tree): Type = {
911932
if (tpt.tpe.isError) AnyRefTpe
912933
else tpt.tpe
913934
}
914935

915-
val parents = typer.typedParentTypes(templ) map checkParent
936+
val parents = parentTrees map checkParent
916937

917938
enterSelf(templ.self)
918939

@@ -1675,6 +1696,9 @@ trait Namers extends MethodSynthesis {
16751696

16761697
abstract class TypeCompleter extends LazyType {
16771698
val tree: Tree
1699+
override def forceDirectSuperclasses: Unit = {
1700+
tree.foreach(t => Option(t.symbol).map(_.maybeInitialize))
1701+
}
16781702
}
16791703

16801704
def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new LockingTypeCompleter with FlagAgnosticCompleter {

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,13 +1711,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
17111711
context.deprecationWarning(parent.pos, psym, report, version)
17121712
}
17131713

1714-
if (psym.isSealed && !phase.erasedTypes)
1715-
if (sameSourceFile)
1716-
psym addChild context.owner
1717-
else
1718-
pending += ParentSealedInheritanceError(parent, psym)
1719-
if (psym.isLocalToBlock && !phase.erasedTypes)
1720-
psym addChild context.owner
17211714
val parentTypeOfThis = parent.tpe.dealias.typeOfThis
17221715

17231716
if (!(selfType <:< parentTypeOfThis) &&

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
113113
def knownDirectSubc 57AE lasses = {
114114
// See `getFlag` to learn more about the `isThreadsafe` call in the body of this method.
115115
if (!isCompilerUniverse && !isThreadsafe(purpose = AllOps)) initialize
116+
117+
enclosingPackage.info.decls.foreach { sym =>
118+
if(sourceFile == sym.sourceFile) {
119+
sym.rawInfo.forceDirectSuperclasses
120+
}
121+
}
122+
116123
children
117124
}
118125

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@ trait Types
310310
/** If this is a lazy type, assign a new type to `sym`. */
311311
def complete(sym: Symbol) {}
312312

313+
/** If this is a lazy type corresponding to a subclass add it to its
314+
* parents children
315+
*/
316+
def forceDirectSuperclasses: Unit = ()
317+
313318
/** The term symbol associated with the type
314319
* Note that the symbol of the normalized type is returned (@see normalize)
315320
*/

test/files/run/t7046-1/Macros_1.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import scala.language.experimental.macros
2+
import scala.reflect.macros.blackbox.Context
3+
4+
object Macros {
5+
def impl[T](c: Context)(implicit ttag: c.WeakTypeTag[T]): c.Expr[List[String]] = {
6+
import c.universe._;
7+
val ttpe = ttag.tpe
8+
val tsym = ttpe.typeSymbol.asClass
9+
val subclasses = tsym.knownDirectSubclasses.toList.map(_.name.toString)
10+
11+
c.Expr[List[String]](q"$subclasses")
12+
}
13+
14+
def knownDirectSubclasses[T]: List[String] = macro impl[T]
15+
}

test/files/run/t7046-1/Test_2.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
object Test extends App {
2+
val subs = Macros.knownDirectSubclasses[Foo]
3+
assert(subs == List("Wibble", "Wobble", "Bar", "Baz"))
4+
}
5+
6+
sealed trait Foo
7+
object Foo {
8+
trait Wibble extends Foo
9+
case object Wobble extends Foo
10+
}
11+
12+
trait Bar extends Foo
13+
14+
object Blah {
15+
type Quux = Foo
16+
}
17+
18+
import Blah._
19+
20+
trait Baz extends Quux
21+
22+
class Boz[T](t: T)
23+
class Unrelated extends Boz(Test.subs)
24+
25+
object Enigma {
26+
locally {
27+
// local class not seen
28+
class Local extends Foo
29+
}
30+
31+
def foo: Unit = {
32+
// local class not seen
33+
class Riddle extends Foo
34+
}
35+
}

0 commit comments

Comments
 (0)
0