Skip to content

Rename unused to ghost #4061

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 1 commit into from
Mar 2, 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
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Compiler {
new ShortcutImplicits, // Allow implicit functions without creating closures
new CrossCastAnd, // Normalize selections involving intersection types.
new Splitter) :: // Expand selections involving union types into conditionals
List(new UnusedDecls, // Removes all unused defs and vals decls (except for parameters)
List(new GhostDecls, // Removes all ghost defs and vals decls (except for parameters)
new VCInlineMethods, // Inlines calls to value class methods
new SeqLiterals, // Express vararg arguments as arrays
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ object desugar {
private def toDefParam(tparam: TypeDef): TypeDef =
tparam.withMods(tparam.rawMods & EmptyFlags | Param)
private def toDefParam(vparam: ValDef): ValDef =
vparam.withMods(vparam.rawMods & (Implicit | Unused) | Param)
vparam.withMods(vparam.rawMods & (Implicit | Ghost) | Param)

/** The expansion of a class definition. See inline comments for what is involved */
def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
* flags set.
*/
private def refPurity(tree: Tree)(implicit ctx: Context): PurityLevel =
if (!tree.tpe.widen.isParameterless || tree.symbol.is(Unused)) SimplyPure
if (!tree.tpe.widen.isParameterless || tree.symbol.is(Ghost)) SimplyPure
else if (!tree.symbol.isStable) Impure
else if (tree.symbol.is(Lazy)) Idempotent // TODO add Module flag, sinxce Module vals or not Lazy from the start.
else SimplyPure
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
case tp: MethodType =>
def valueParam(name: TermName, info: Type): TermSymbol = {
val maybeImplicit = if (tp.isImplicitMethod) Implicit else EmptyFlags
val maybeUnused = if (tp.isUnusedMethod) Unused else EmptyFlags
ctx.newSymbol(sym, name, TermParam | maybeImplicit | maybeUnused, info, coord = sym.coord)
val maybeGhost = if (tp.isGhostMethod) Ghost else EmptyFlags
ctx.newSymbol(sym, name, TermParam | maybeImplicit | maybeGhost, info, coord = sym.coord)
}
val params = (tp.paramNames, tp.paramInfos).zipped.map(valueParam)
val (paramss, rtp) = valueParamss(tp.instantiate(params map (_.termRef)))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {

case class Implicit() extends Mod(Flags.ImplicitCommon)

case class Unused() extends Mod(Flags.Unused)
case class Ghost() extends Mod(Flags.Ghost)

case class Final() extends Mod(Flags.Final)

Expand Down
74 changes: 37 additions & 37 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class Definitions {
newClassSymbol(ScalaPackageClass, name, EmptyFlags, completer).entered
}

/** The trait FunctionN, ImplicitFunctionN, UnusedFunctionN or UnusedImplicitFunction, for some N
/** The trait FunctionN, ImplicitFunctionN, GhostFunctionN or GhostImplicitFunction, for some N
* @param name The name of the trait to be created
*
* FunctionN traits follow this template:
Expand All @@ -107,19 +107,19 @@ class Definitions {
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
* }
*
* UnusedFunctionN traits follow this template:
* GhostFunctionN traits follow this template:
*
* trait UnusedFunctionN[T0,...,T{N-1}, R] extends Object {
* def apply(unused $x0: T0, ..., $x{N_1}: T{N-1}): R
* trait GhostFunctionN[T0,...,T{N-1}, R] extends Object {
* def apply(ghost $x0: T0, ..., $x{N_1}: T{N-1}): R
* }
*
* UnusedImplicitFunctionN traits follow this template:
* GhostImplicitFunctionN traits follow this template:
*
* trait UnusedImplicitFunctionN[T0,...,T{N-1}, R] extends Object with UnusedFunctionN[T0,...,T{N-1}, R] {
* def apply(unused implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
* trait GhostImplicitFunctionN[T0,...,T{N-1}, R] extends Object with GhostFunctionN[T0,...,T{N-1}, R] {
* def apply(ghost implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
* }
*
* UnusedFunctionN and UnusedImplicitFunctionN erase to Function0.
* GhostFunctionN and GhostImplicitFunctionN erase to Function0.
*/
def newFunctionNTrait(name: TypeName): ClassSymbol = {
val completer = new LazyType {
Expand All @@ -132,10 +132,10 @@ class Definitions {
enterTypeParam(cls, paramNamePrefix ++ "T" ++ (i + 1).toString, Contravariant, decls).typeRef
}
val resParamRef = enterTypeParam(cls, paramNamePrefix ++ "R", Covariant, decls).typeRef
val methodType = MethodType.maker(isJava = false, name.isImplicitFunction, name.isUnusedFunction)
val methodType = MethodType.maker(isJava = false, name.isImplicitFunction, name.isGhostFunction)
val parentTraits =
if (!name.isImplicitFunction) Nil
else FunctionType(arity, isUnused = name.isUnusedFunction).appliedTo(argParamRefs ::: resParamRef :: Nil) :: Nil
else FunctionType(arity, isGhost = name.isGhostFunction).appliedTo(argParamRefs ::: resParamRef :: Nil) :: Nil
decls.enter(newMethod(cls, nme.apply, methodType(argParamRefs, resParamRef), Deferred))
denot.info =
ClassInfo(ScalaPackageClass.thisType, cls, ObjectType :: parentTraits, decls)
Expand Down Expand Up @@ -756,14 +756,14 @@ class Definitions {
sym.owner.linkedClass.typeRef

object FunctionOf {
def apply(args: List[Type], resultType: Type, isImplicit: Boolean = false, isUnused: Boolean = false)(implicit ctx: Context) =
FunctionType(args.length, isImplicit, isUnused).appliedTo(args ::: resultType :: Nil)
def apply(args: List[Type], resultType: Type, isImplicit: Boolean = false, isGhost: Boolean = false)(implicit ctx: Context) =
FunctionType(args.length, isImplicit, isGhost).appliedTo(args ::: resultType :: Nil)
def unapply(ft: Type)(implicit ctx: Context) = {
val tsym = ft.typeSymbol
if (isFunctionClass(tsym)) {
val targs = ft.dealias.argInfos
if (targs.isEmpty) None
else Some(targs.init, targs.last, tsym.name.isImplicitFunction, tsym.name.isUnusedFunction)
else Some(targs.init, targs.last, tsym.name.isImplicitFunction, tsym.name.isGhostFunction)
}
else None
}
Expand Down Expand Up @@ -827,18 +827,18 @@ class Definitions {

lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2)

def FunctionClass(n: Int, isImplicit: Boolean = false, isUnused: Boolean = false)(implicit ctx: Context) = {
if (isImplicit && isUnused) {
def FunctionClass(n: Int, isImplicit: Boolean = false, isGhost: Boolean = false)(implicit ctx: Context) = {
if (isImplicit && isGhost) {
require(n > 0)
ctx.requiredClass("scala.UnusedImplicitFunction" + n.toString)
ctx.requiredClass("scala.GhostImplicitFunction" + n.toString)
}
else if (isImplicit) {
require(n > 0)
ctx.requiredClass("scala.ImplicitFunction" + n.toString)
}
else if (isUnused) {
else if (isGhost) {
require(n > 0)
ctx.requiredClass("scala.UnusedFunction" + n.toString)
ctx.requiredClass("scala.GhostFunction" + n.toString)
}
else if (n <= MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n)
else ctx.requiredClass("scala.Function" + n.toString)
Expand All @@ -847,9 +847,9 @@ class Definitions {
lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply)
def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol

def FunctionType(n: Int, isImplicit: Boolean = false, isUnused: Boolean = false)(implicit ctx: Context): TypeRef =
if (n <= MaxImplementedFunctionArity && (!isImplicit || ctx.erasedTypes) && !isUnused) ImplementedFunctionType(n)
else FunctionClass(n, isImplicit, isUnused).typeRef
def FunctionType(n: Int, isImplicit: Boolean = false, isGhost: Boolean = false)(implicit ctx: Context): TypeRef =
if (n <= MaxImplementedFunctionArity && (!isImplicit || ctx.erasedTypes) && !isGhost) ImplementedFunctionType(n)
else FunctionClass(n, isImplicit, isGhost).typeRef

private lazy val TupleTypes: Set[TypeRef] = TupleType.toSet

Expand All @@ -874,22 +874,22 @@ class Definitions {
/** Is a function class.
* - FunctionN for N >= 0
* - ImplicitFunctionN for N > 0
* - UnusedFunctionN for N > 0
* - UnusedImplicitFunctionN for N > 0
* - GhostFunctionN for N > 0
* - GhostImplicitFunctionN for N > 0
*/
def isFunctionClass(cls: Symbol) = scalaClassName(cls).isFunction

/** Is an implicit function class.
* - ImplicitFunctionN for N > 0
* - UnusedImplicitFunctionN for N > 0
* - GhostImplicitFunctionN for N > 0
*/
def isImplicitFunctionClass(cls: Symbol) = scalaClassName(cls).isImplicitFunction

/** Is an unused function class.
* - UnusedFunctionN for N > 0
* - UnusedImplicitFunctionN for N > 0
/** Is an ghost function class.
* - GhostFunctionN for N > 0
* - GhostImplicitFunctionN for N > 0
*/
def isUnusedFunctionClass(cls: Symbol) = scalaClassName(cls).isUnusedFunction
def isGhostFunctionClass(cls: Symbol) = scalaClassName(cls).isGhostFunction

/** Is a class that will be erased to FunctionXXL
* - FunctionN for N >= 22
Expand All @@ -915,13 +915,13 @@ class Definitions {
* - FunctionN for 22 > N >= 0 remains as FunctionN
* - ImplicitFunctionN for N > 22 becomes FunctionXXL
* - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
* - UnusedFunctionN becomes Function0
* - ImplicitUnusedFunctionN becomes Function0
* - GhostFunctionN becomes Function0
* - ImplicitGhostFunctionN becomes Function0
* - anything else becomes a NoSymbol
*/
def erasedFunctionClass(cls: Symbol): Symbol = {
val arity = scalaClassName(cls).functionArity
if (cls.name.isUnusedFunction) FunctionClass(0)
if (cls.name.isGhostFunction) FunctionClass(0)
else if (arity > 22) FunctionXXLClass
else if (arity >= 0) FunctionClass(arity)
else NoSymbol
Expand All @@ -932,13 +932,13 @@ class Definitions {
* - FunctionN for 22 > N >= 0 remains as FunctionN
* - ImplicitFunctionN for N > 22 becomes FunctionXXL
* - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
* - UnusedFunctionN becomes Function0
* - ImplicitUnusedFunctionN becomes Function0
* - GhostFunctionN becomes Function0
* - ImplicitGhostFunctionN becomes Function0
* - anything else becomes a NoType
*/
def erasedFunctionType(cls: Symbol): Type = {
val arity = scalaClassName(cls).functionArity
if (cls.name.isUnusedFunction) FunctionType(0)
if (cls.name.isGhostFunction) FunctionType(0)
else if (arity > 22) FunctionXXLType
else if (arity >= 0) FunctionType(arity)
else NoType
Expand Down Expand Up @@ -1008,7 +1008,7 @@ class Definitions {
def isNonDepFunctionType(tp: Type)(implicit ctx: Context) = {
val arity = functionArity(tp)
val sym = tp.dealias.typeSymbol
arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType(arity, sym.name.isImplicitFunction, sym.name.isUnusedFunction).typeSymbol)
arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType(arity, sym.name.isImplicitFunction, sym.name.isGhostFunction).typeSymbol)
}

/** Is `tp` a representation of a (possibly depenent) function type or an alias of such? */
Expand Down Expand Up @@ -1074,8 +1074,8 @@ class Definitions {
def isImplicitFunctionType(tp: Type)(implicit ctx: Context): Boolean =
asImplicitFunctionType(tp).exists

def isUnusedFunctionType(tp: Type)(implicit ctx: Context) =
isFunctionType(tp) && tp.dealias.typeSymbol.name.isUnusedFunction
def isGhostFunctionType(tp: Type)(implicit ctx: Context) =
isFunctionType(tp) && tp.dealias.typeSymbol.name.isGhostFunction

// ----- primitive value class machinery ------------------------------------------

Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ object Flags {
/** Symbol is a Java enum */
final val Enum = commonFlag(40, "<enum>")

/** Labeled with `unused` modifier (unused value) */
final val Unused = termFlag(42, "unused")
/** Labeled with `ghost` modifier (ghost value) */
final val Ghost = termFlag(42, "ghost")

// Flags following this one are not pickled

Expand Down Expand Up @@ -441,7 +441,7 @@ object Flags {
/** Flags representing source modifiers */
final val SourceModifierFlags =
commonFlags(Private, Protected, Abstract, Final, Inline,
Sealed, Case, Implicit, Override, AbsOverride, Lazy, JavaStatic, Unused)
Sealed, Case, Implicit, Override, AbsOverride, Lazy, JavaStatic, Ghost)

/** Flags representing modifiers that can appear in trees */
final val ModifierFlags =
Expand Down Expand Up @@ -515,7 +515,7 @@ object Flags {
/** Flags that can apply to a module val */
final val RetainedModuleValFlags: FlagSet = RetainedModuleValAndClassFlags |
Override | Final | Method | Implicit | Lazy |
Accessor | AbsOverride | Stable | Captured | Synchronized | Inline | Unused
Accessor | AbsOverride | Stable | Captured | Synchronized | Inline | Ghost

/** Flags that can apply to a module class */
final val RetainedModuleClassFlags: FlagSet = RetainedModuleValAndClassFlags | ImplClass | Enum
Expand Down
28 changes: 14 additions & 14 deletions compiler/src/dotty/tools/dotc/core/NameOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -176,51 +176,51 @@ object NameOps {
functionArityFor(str.Function) max {
val n =
functionArityFor(str.ImplicitFunction) max
functionArityFor(str.UnusedFunction) max
functionArityFor(str.UnusedImplicitFunction)
functionArityFor(str.GhostFunction) max
functionArityFor(str.GhostImplicitFunction)
if (n == 0) -1 else n
}

/** Is a function name
* - FunctionN for N >= 0
* - ImplicitFunctionN for N >= 1
* - UnusedFunctionN for N >= 1
* - UnusedImplicitFunctionN for N >= 1
* - GhostFunctionN for N >= 1
* - GhostImplicitFunctionN for N >= 1
* - false otherwise
*/
def isFunction: Boolean = functionArity >= 0

/** Is a implicit function name
* - ImplicitFunctionN for N >= 1
* - UnusedImplicitFunctionN for N >= 1
* - GhostImplicitFunctionN for N >= 1
* - false otherwise
*/
def isImplicitFunction: Boolean = {
functionArityFor(str.ImplicitFunction) >= 1 ||
functionArityFor(str.UnusedImplicitFunction) >= 1
functionArityFor(str.GhostImplicitFunction) >= 1
}

/** Is a implicit function name
* - UnusedFunctionN for N >= 1
* - UnusedImplicitFunctionN for N >= 1
* - GhostFunctionN for N >= 1
* - GhostImplicitFunctionN for N >= 1
* - false otherwise
*/
def isUnusedFunction: Boolean = {
functionArityFor(str.UnusedFunction) >= 1 ||
functionArityFor(str.UnusedImplicitFunction) >= 1
def isGhostFunction: Boolean = {
functionArityFor(str.GhostFunction) >= 1 ||
functionArityFor(str.GhostImplicitFunction) >= 1
}

/** Is a synthetic function name
* - FunctionN for N > 22
* - ImplicitFunctionN for N >= 1
* - UnusedFunctionN for N >= 1
* - UnusedImplicitFunctionN for N >= 1
* - GhostFunctionN for N >= 1
* - GhostImplicitFunctionN for N >= 1
* - false otherwise
*/
def isSyntheticFunction: Boolean = {
functionArityFor(str.Function) > MaxImplementedFunctionArity ||
functionArityFor(str.ImplicitFunction) >= 1 ||
isUnusedFunction
isGhostFunction
}

/** Parsed function arity for function with some specific prefix */
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ object StdNames {
final val MODULE_INSTANCE_FIELD = "MODULE$"

final val Function = "Function"
final val UnusedFunction = "UnusedFunction"
final val GhostFunction = "GhostFunction"
final val ImplicitFunction = "ImplicitFunction"
final val UnusedImplicitFunction = "UnusedImplicitFunction"
final val GhostImplicitFunction = "GhostImplicitFunction"
final val AbstractFunction = "AbstractFunction"
final val Tuple = "Tuple"
final val Product = "Product"
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
case tp: MethodType =>
def paramErasure(tpToErase: Type) =
erasureFn(tp.isJavaMethod, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
val (names, formals0) = if (tp.isUnusedMethod) (Nil, Nil) else (tp.paramNames, tp.paramInfos)
val (names, formals0) = if (tp.isGhostMethod) (Nil, Nil) else (tp.paramNames, tp.paramInfos)
val formals = formals0.mapConserve(paramErasure)
eraseResult(tp.resultType) match {
case rt: MethodType =>
Expand Down
Loading