Skip to content

Simplify super call handling: remove inConstrCall, remove InSuperCall #8591

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 3 commits into from
Mar 22, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class JUnitBootstrappers extends MiniPhase {
val sym = ctx.newDefaultConstructor(owner).entered
DefDef(sym, {
Block(
Super(This(owner), nme.EMPTY.toTypeName, inConstrCall = true).select(defn.ObjectClass.primaryConstructor).appliedToNone :: Nil,
Super(This(owner), tpnme.EMPTY).select(defn.ObjectClass.primaryConstructor).appliedToNone :: Nil,
unitLiteral
)
})
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def This(cls: ClassSymbol)(implicit ctx: Context): This =
untpd.This(untpd.Ident(cls.name)).withType(cls.thisType)

def Super(qual: Tree, mix: untpd.Ident, inConstrCall: Boolean, mixinClass: Symbol)(implicit ctx: Context): Super =
ta.assignType(untpd.Super(qual, mix), qual, inConstrCall, mixinClass)
def Super(qual: Tree, mix: untpd.Ident, mixinClass: Symbol)(implicit ctx: Context): Super =
ta.assignType(untpd.Super(qual, mix), qual, mixinClass)

def Super(qual: Tree, mixName: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
Super(qual, if (mixName.isEmpty) untpd.EmptyTypeIdent else untpd.Ident(mixName), inConstrCall, mixinClass)
def Super(qual: Tree, mixName: TypeName, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super =
Super(qual, if (mixName.isEmpty) untpd.EmptyTypeIdent else untpd.Ident(mixName), mixinClass)

def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = {
assert(fn.isInstanceOf[RefTree] || fn.isInstanceOf[GenericApply[_]] || fn.isInstanceOf[Inlined])
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,6 @@ object Contexts {
* - as owner: The primary constructor of the class
* - as outer context: The context enclosing the class context
* - as scope: The parameter accessors in the class context
* - with additional mode: InSuperCall
*
* The reasons for this peculiar choice of attributes are as follows:
*
Expand Down Expand Up @@ -394,7 +393,7 @@ object Contexts {
var classCtx = outersIterator.dropWhile(!_.isClassDefContext).next()
classCtx.outer.fresh.setOwner(owner)
.setScope(locals)
.setMode(classCtx.mode | Mode.InSuperCall)
.setMode(classCtx.mode)
}

/** The context of expression `expr` seen as a member of a statement sequence */
Expand Down
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/core/Mode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ object Mode {

val CheckCyclic: Mode = newMode(5, "CheckCyclic")

/** We are looking at the arguments of a supercall */
val InSuperCall: Mode = newMode(6, "InSuperCall")

/** We are in a pattern alternative */
val InPatternAlternative: Mode = newMode(7, "InPatternAlternative")

Expand Down
10 changes: 4 additions & 6 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ class TreeUnpickler(reader: TastyReader,
readByte()
val end = readEnd()
val tp = readType()
val lazyAnnotTree = readLaterWithOwner(end, rdr => ctx => rdr.readTerm()(ctx))
val lazyAnnotTree = readLaterWithOwner(end, rdr => implicit ctx => rdr.readTerm())
Copy link
Contributor

Choose a reason for hiding this comment

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

I propose we go to the new syntax (using ctx) => rdr.readTerm().

Copy link
Member Author

Choose a reason for hiding this comment

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

That doesn't work because the expected type is not a context function type but a regular function type, and I was hesitant to change this since it'll make it harder to port code between the Scala 2 and 3 readers.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK


owner =>
Annotation.deferredSymAndTree(tp.typeSymbol)(lazyAnnotTree(owner).complete)
Expand Down Expand Up @@ -780,7 +780,7 @@ class TreeUnpickler(reader: TastyReader,
def complete(implicit ctx: Context) = typer.Inliner.bodyToInline(sym)
}
else
readLater(end, rdr => ctx => rdr.readTerm()(ctx.retractMode(Mode.InSuperCall)))
readLater(end, rdr => implicit ctx => rdr.readTerm())
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto


def ValDef(tpt: Tree) =
ta.assignType(untpd.ValDef(sym.name.asTermName, tpt, readRhs(localCtx)), sym)
Expand Down Expand Up @@ -1032,9 +1032,7 @@ class TreeUnpickler(reader: TastyReader,
}

def completeSelect(name: Name, sig: Signature): Select = {
val localCtx =
if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx
val qual = readTerm()(localCtx)
val qual = readTerm()(ctx)
var qualType = qual.tpe.widenIfUnstable
val denot = accessibleDenot(qualType, name, sig)
val owner = denot.symbol.maybeOwner
Expand Down Expand Up @@ -1098,7 +1096,7 @@ class TreeUnpickler(reader: TastyReader,
case SUPER =>
val qual = readTerm()
val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType))
tpd.Super(qual, mixId, ctx.mode.is(Mode.InSuperCall), mixTpe.typeSymbol)
tpd.Super(qual, mixId, mixTpe.typeSymbol)
case APPLY =>
val fn = readTerm()
tpd.Apply(fn, until(end)(readTerm()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
setSym()
val qual = readTreeRef()
val mix = readTypeNameRef()
Super(qual, mix, inConstrCall = false) // todo: revise
Super(qual, mix)

case THIStree =>
setSym()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
def Super_id(self: Super)(using ctx: Context): Option[Id] = optional(self.mix)

def Super_apply(qual: Term, mix: Option[Id])(using ctx: Context): Super =
withDefaultPos(tpd.Super(qual, mix.getOrElse(untpd.EmptyTypeIdent), false, NoSymbol))
withDefaultPos(tpd.Super(qual, mix.getOrElse(untpd.EmptyTypeIdent), NoSymbol))

def Super_copy(original: Tree)(qual: Term, mix: Option[Id])(using ctx: Context): Super =
tpd.cpy.Super(original)(qual, mix.getOrElse(untpd.EmptyTypeIdent))
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/MixinOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ class MixinOps(cls: ClassSymbol, thisPhase: DenotTransformer)(implicit ctx: Cont

def superRef(target: Symbol, span: Span = cls.span): Tree = {
val sup = if (target.isConstructor && !target.owner.is(Trait))
Super(This(cls), tpnme.EMPTY, true)
Super(This(cls), tpnme.EMPTY)
else
Super(This(cls), target.owner.name.asTypeName, false, target.owner)
Super(This(cls), target.owner.name.asTypeName, target.owner)
//println(i"super ref $target on $sup")
ast.untpd.Select(sup.withSpan(span), target.name)
.withType(NamedType(sup.tpe, target))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ParamForwarding extends MiniPhase with IdentityDenotTransformer:
info = sym.info.ensureMethodic
).installAfter(thisPhase)
val superAcc =
Super(This(currentClass), tpnme.EMPTY, inConstrCall = false)
Super(This(currentClass), tpnme.EMPTY)
.withSpan(mdef.span)
.select(alias)
.ensureApplied
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ class Namer { typer: Typer =>
class ClassCompleter(cls: ClassSymbol, original: TypeDef)(ictx: Context) extends Completer(original)(ictx) {
withDecls(newScope)

protected implicit val ctx: Context = localContext(cls).setMode(ictx.mode &~ Mode.InSuperCall)
protected implicit val ctx: Context = localContext(cls)

private var localCtx: Context = _

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ trait TypeAssigner {
else errorType("not a legal qualifying class for this", tree.sourcePos))
}

def assignType(tree: untpd.Super, qual: Tree, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super = {
def assignType(tree: untpd.Super, qual: Tree, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super = {
val mix = tree.mix
qual.tpe match {
case err: ErrorType => untpd.cpy.Super(tree)(qual, mix).withType(err)
Expand All @@ -386,7 +386,7 @@ trait TypeAssigner {
val owntype =
if (mixinClass.exists) mixinClass.appliedRef
else if (!mix.isEmpty) findMixinSuper(cls.info)
else if (inConstrCall || ctx.erasedTypes) cls.info.firstParent.typeConstructor
else if (ctx.erasedTypes) cls.info.firstParent.typeConstructor
else {
val ps = cls.classInfo.parents
if (ps.isEmpty) defn.AnyType else ps.reduceLeft((x: Type, y: Type) => x & y)
Expand Down
13 changes: 4 additions & 9 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,9 @@ class Typer extends Namer
return ref(defn.XMLTopScopeModule.termRef)
else if (name.toTermName == nme.ERROR)
UnspecifiedErrorType
else if (ctx.owner.isConstructor && ctx.mode.is(Mode.InSuperCall) &&
else if (ctx.owner.isConstructor && !ctx.owner.isPrimaryConstructor &&
ctx.owner.owner.unforcedDecls.lookup(tree.name).exists)
// When InSuperCall mode and in a constructor we are in the arguments
// of a this(...) constructor call
// we are in the arguments of a this(...) constructor call
errorType(ex"$tree is not accessible from constructor arguments", tree.sourcePos)
else
errorType(new MissingIdent(tree, kind, name.show), tree.sourcePos)
Expand Down Expand Up @@ -539,18 +538,14 @@ class Typer extends Namer

def typedSuper(tree: untpd.Super, pt: Type)(implicit ctx: Context): Tree = {
val qual1 = typed(tree.qual)
val inConstrCall = pt match {
case pt: SelectionProto if pt.name == nme.CONSTRUCTOR => true
case _ => false
}
val enclosingInlineable = ctx.owner.ownersIterator.findSymbol(_.isInlineMethod)
if (enclosingInlineable.exists && !PrepareInlineable.isLocal(qual1.symbol, enclosingInlineable))
ctx.error(SuperCallsNotAllowedInlineable(enclosingInlineable), tree.sourcePos)
pt match {
case pt: SelectionProto if pt.name.isTypeName =>
qual1 // don't do super references for types; they are meaningless anyway
case _ =>
assignType(cpy.Super(tree)(qual1, tree.mix), qual1, inConstrCall)
assignType(cpy.Super(tree)(qual1, tree.mix), qual1)
}
}

Expand Down Expand Up @@ -2195,7 +2190,7 @@ class Typer extends Namer
typer1.typedDefDef(tree, sym)(ctx.localContext(tree, sym).setTyper(typer1))
case tree: untpd.TypeDef =>
if (tree.isClassDef)
typedClassDef(tree, sym.asClass)(ctx.localContext(tree, sym).setMode(ctx.mode &~ Mode.InSuperCall))
typedClassDef(tree, sym.asClass)(ctx.localContext(tree, sym))
else
typedTypeDef(tree, sym)(ctx.localContext(tree, sym).setNewScope)
case tree: untpd.Labeled => typedLabeled(tree)
Expand Down