Skip to content

Commit 8ffed08

Browse files
authored
Merge pull request #6497 from dotty-staging/simplify-implicit-flags
Simplify implicit flags
2 parents 9be57ca + f2c80b2 commit 8ffed08

33 files changed

+158
-163
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

+12-13
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,17 @@ object desugar {
173173
vparamss = (setterParam :: Nil) :: Nil,
174174
tpt = TypeTree(defn.UnitType),
175175
rhs = setterRhs
176-
).withMods((mods | Accessor) &~ (CaseAccessor | Implicit | Given | Lazy))
176+
).withMods((mods | Accessor) &~ (CaseAccessor | ImplicitOrGiven | Lazy))
177177
Thicket(vdef, setter)
178178
}
179179
else vdef
180180
}
181181

182-
def makeImplicitParameters(tpts: List[Tree], contextualFlag: FlagSet = EmptyFlags, forPrimaryConstructor: Boolean = false)(implicit ctx: Context): List[ValDef] =
182+
def makeImplicitParameters(tpts: List[Tree], implicitFlag: FlagSet, forPrimaryConstructor: Boolean = false)(implicit ctx: Context): List[ValDef] =
183183
for (tpt <- tpts) yield {
184184
val paramFlags: FlagSet = if (forPrimaryConstructor) PrivateLocalParamAccessor else Param
185185
val epname = EvidenceParamName.fresh()
186-
ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | Implicit | contextualFlag)
186+
ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | implicitFlag)
187187
}
188188

189189
/** 1. Expand context bounds to evidence params. E.g.,
@@ -219,7 +219,7 @@ object desugar {
219219
val epbuf = new ListBuffer[ValDef]
220220
def desugarContextBounds(rhs: Tree): Tree = rhs match {
221221
case ContextBounds(tbounds, cxbounds) =>
222-
epbuf ++= makeImplicitParameters(cxbounds, forPrimaryConstructor = isPrimaryConstructor)
222+
epbuf ++= makeImplicitParameters(cxbounds, Implicit, forPrimaryConstructor = isPrimaryConstructor)
223223
tbounds
224224
case LambdaTypeTree(tparams, body) =>
225225
cpy.LambdaTypeTree(rhs)(tparams, desugarContextBounds(body))
@@ -322,7 +322,7 @@ object desugar {
322322
meth
323323
case evidenceParams =>
324324
val vparamss1 = meth.vparamss.reverse match {
325-
case (vparams @ (vparam :: _)) :: rvparamss if vparam.mods is Implicit =>
325+
case (vparams @ (vparam :: _)) :: rvparamss if vparam.mods is ImplicitOrGiven =>
326326
((evidenceParams ++ vparams) :: rvparamss).reverse
327327
case _ =>
328328
meth.vparamss :+ evidenceParams
@@ -333,7 +333,7 @@ object desugar {
333333
/** The implicit evidence parameters of `meth`, as generated by `desugar.defDef` */
334334
private def evidenceParams(meth: DefDef)(implicit ctx: Context): List[ValDef] =
335335
meth.vparamss.reverse match {
336-
case (vparams @ (vparam :: _)) :: _ if vparam.mods is Implicit =>
336+
case (vparams @ (vparam :: _)) :: _ if vparam.mods is ImplicitOrGiven =>
337337
vparams.dropWhile(!_.name.is(EvidenceParamName))
338338
case _ =>
339339
Nil
@@ -344,7 +344,7 @@ object desugar {
344344
private def toDefParam(tparam: TypeDef): TypeDef =
345345
tparam.withMods(tparam.rawMods & EmptyFlags | Param)
346346
private def toDefParam(vparam: ValDef): ValDef =
347-
vparam.withMods(vparam.rawMods & (Implicit | Erased) | Param)
347+
vparam.withMods(vparam.rawMods & (ImplicitOrGiven | Erased) | Param)
348348

349349
/** The expansion of a class definition. See inline comments for what is involved */
350350
def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = {
@@ -412,7 +412,7 @@ object desugar {
412412
if (isCaseClass && originalTparams.isEmpty)
413413
ctx.error(CaseClassMissingParamList(cdef), namePos)
414414
ListOfNil
415-
} else if (isCaseClass && originalVparamss.head.exists(_.mods.is(Implicit))) {
415+
} else if (isCaseClass && originalVparamss.head.exists(_.mods.is(ImplicitOrGiven))) {
416416
ctx.error("Case classes should have a non-implicit parameter list", namePos)
417417
ListOfNil
418418
}
@@ -507,18 +507,17 @@ object desugar {
507507
// new C[Ts](paramss)
508508
lazy val creatorExpr = {
509509
val vparamss = constrVparamss match {
510-
case (vparam :: _) :: _ if vparam.mods.is(Implicit) => // add a leading () to match class parameters
510+
case (vparam :: _) :: _ if vparam.mods.is(ImplicitOrGiven) => // add a leading () to match class parameters
511511
Nil :: constrVparamss
512512
case _ =>
513513
constrVparamss
514514
}
515515
val nu = (makeNew(classTypeRef) /: vparamss) { (nu, vparams) =>
516516
val app = Apply(nu, vparams.map(refOfDef))
517517
vparams match {
518-
case vparam :: _ if vparam.mods.is(Given) => app.pushAttachment(ApplyGiven, ())
519-
case _ =>
518+
case vparam :: _ if vparam.mods.is(Given) => app.setGivenApply()
519+
case _ => app
520520
}
521-
app
522521
}
523522
ensureApplied(nu)
524523
}
@@ -1196,7 +1195,7 @@ object desugar {
11961195
def makeContextualFunction(formals: List[Type], body: Tree, isErased: Boolean)(implicit ctx: Context): Tree = {
11971196
val mods = if (isErased) Given | Erased else Given
11981197
val params = makeImplicitParameters(formals.map(TypeTree), mods)
1199-
new FunctionWithMods(params, body, Modifiers(Implicit | mods))
1198+
new FunctionWithMods(params, body, Modifiers(mods))
12001199
}
12011200

12021201
/** Add annotation to tree:

compiler/src/dotty/tools/dotc/ast/Trees.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,8 @@ object Trees {
436436
extends GenericApply[T] {
437437
type ThisTree[-T >: Untyped] = Apply[T]
438438

439-
def isContextual = getAttachment(untpd.ApplyGiven).nonEmpty
439+
def isGivenApply = getAttachment(untpd.ApplyGiven).nonEmpty
440+
def setGivenApply() = { pushAttachment(untpd.ApplyGiven, ()); this }
440441
}
441442

442443
/** fun[args] */

compiler/src/dotty/tools/dotc/ast/tpd.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
231231

232232
def valueParam(name: TermName, origInfo: Type): TermSymbol = {
233233
val maybeImplicit =
234-
if (tp.isContextual) Implicit | Given
234+
if (tp.isContextualMethod) Given
235235
else if (tp.isImplicitMethod) Implicit
236236
else EmptyFlags
237237
val maybeErased = if (tp.isErasedMethod) Erased else EmptyFlags

compiler/src/dotty/tools/dotc/ast/untpd.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
143143

144144
case class Implicit()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Implicit)
145145

146-
case class Given()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Implicit | Flags.Given)
146+
case class Given()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Given)
147147

148148
case class Erased()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Erased)
149149

compiler/src/dotty/tools/dotc/core/Contexts.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Scopes._
1313
import Uniques._
1414
import ast.Trees._
1515
import ast.untpd
16-
import Flags.ImplicitOrImplied
16+
import Flags.ImplicitOrImpliedOrGiven
1717
import util.{FreshNameCreator, NoSource, SimpleIdentityMap, SourceFile}
1818
import typer.{Implicits, ImportInfo, Inliner, NamerContextOps, SearchHistory, SearchRoot, TypeAssigner, Typer}
1919
import Implicits.ContextualImplicits
@@ -214,7 +214,7 @@ object Contexts {
214214
implicitsCache = {
215215
val implicitRefs: List[ImplicitRef] =
216216
if (isClassDefContext)
217-
try owner.thisType.implicitMembers(ImplicitOrImplied)
217+
try owner.thisType.implicitMembers(ImplicitOrImpliedOrGiven)
218218
catch {
219219
case ex: CyclicReference => Nil
220220
}

compiler/src/dotty/tools/dotc/core/Definitions.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,10 @@ class Definitions {
128128
enterTypeParam(cls, paramNamePrefix ++ "T" ++ (i + 1).toString, Contravariant, decls).typeRef
129129
}
130130
val resParamRef = enterTypeParam(cls, paramNamePrefix ++ "R", Covariant, decls).typeRef
131-
val methodType = MethodType.maker(
131+
val methodType = MethodType.companion(
132132
isJava = false,
133-
isImplicit = name.isImplicitFunction,
134133
isContextual = name.isImplicitFunction,
134+
isImplicit = false,
135135
isErased = name.isErasedFunction)
136136
decls.enter(newMethod(cls, nme.apply, methodType(argParamRefs, resParamRef), Deferred))
137137
denot.info =

compiler/src/dotty/tools/dotc/core/Denotations.scala

+3-4
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,8 @@ object Denotations {
624624
tp2 match {
625625
case tp2: PolyType =>
626626
tp1
627-
case tp2: MethodType if ctx.typeComparer.matchingMethodParams(tp1, tp2) &&
628-
tp1.isImplicitMethod == tp2.isImplicitMethod =>
627+
case tp2: MethodType
628+
if ctx.typeComparer.matchingMethodParams(tp1, tp2) && (tp1.companion eq tp2.companion) =>
629629
tp1.derivedLambdaType(
630630
mergeParamNames(tp1, tp2),
631631
tp1.paramInfos,
@@ -683,8 +683,7 @@ object Denotations {
683683
case tp1: MethodType =>
684684
tp2 match {
685685
case tp2: MethodType
686-
if ctx.typeComparer.matchingMethodParams(tp1, tp2) &&
687-
tp1.isImplicitMethod == tp2.isImplicitMethod =>
686+
if ctx.typeComparer.matchingMethodParams(tp1, tp2) && (tp1.companion eq tp2.companion) =>
688687
tp1.derivedLambdaType(
689688
mergeParamNames(tp1, tp2),
690689
tp1.paramInfos,

compiler/src/dotty/tools/dotc/core/Flags.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ object Flags {
487487
HigherKinded.toCommonFlags | Param | ParamAccessor.toCommonFlags |
488488
Scala2ExistentialCommon | MutableOrOpaque | Touched | JavaStatic |
489489
CovariantOrOuter | ContravariantOrLabel | CaseAccessor.toCommonFlags |
490-
Extension.toCommonFlags | NonMember | Implicit | Implied | Permanent | Synthetic |
490+
Extension.toCommonFlags | NonMember | Implicit | Given | Implied | Permanent | Synthetic |
491491
SuperAccessorOrScala2x | Inline
492492

493493
/** Flags that are not (re)set when completing the denotation, or, if symbol is
@@ -589,8 +589,10 @@ object Flags {
589589
final val InlineOrProxy: FlagSet = Inline | InlineProxy
590590

591591
final val ImplicitOrImplied = Implicit | Implied
592+
final val ImplicitOrImpliedOrGiven = Implicit | Implied | Given
593+
final val ImplicitOrGiven = Implicit | Given
592594

593-
final val ImplicitOrImpliedTerm = ImplicitOrImplied.toTermFlags
595+
final val ImplicitOrImpliedOrGivenTerm = ImplicitOrImpliedOrGiven.toTermFlags
594596

595597
/** Assumed to be pure */
596598
final val StableOrErased: FlagSet = StableRealizable | Erased

compiler/src/dotty/tools/dotc/core/Scopes.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ object Scopes {
409409
var irefs = new mutable.ListBuffer[TermRef]
410410
var e = lastEntry
411411
while (e ne null) {
412-
if (e.sym is ImplicitOrImplied) {
412+
if (e.sym is ImplicitOrImpliedOrGiven) {
413413
val d = e.sym.denot
414414
irefs += TermRef(NoPrefix, d.symbol.asTerm).withDenot(d)
415415
}

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1904,7 +1904,7 @@ object SymDenotations {
19041904
if (keepOnly eq implicitFilter)
19051905
if (this is Package) Iterator.empty
19061906
// implicits in package objects are added by the overriding `memberNames` in `PackageClassDenotation`
1907-
else info.decls.iterator filter (_ is ImplicitOrImplied)
1907+
else info.decls.iterator filter (_ is ImplicitOrImpliedOrGiven)
19081908
else info.decls.iterator
19091909
for (sym <- ownSyms) maybeAdd(sym.name)
19101910
names

compiler/src/dotty/tools/dotc/core/TypeErrors.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class CyclicReference private (val denot: SymDenotation) extends TypeError {
142142
}
143143
}
144144
// Give up and give generic errors.
145-
else if (cycleSym.is(ImplicitOrImplied, butNot = Method) && cycleSym.owner.isTerm)
145+
else if (cycleSym.is(ImplicitOrImpliedOrGiven, butNot = Method) && cycleSym.owner.isTerm)
146146
CyclicReferenceInvolvingImplicit(cycleSym)
147147
else
148148
CyclicReferenceInvolving(denot)

compiler/src/dotty/tools/dotc/core/Types.scala

+12-16
Original file line numberDiff line numberDiff line change
@@ -333,19 +333,16 @@ object Types {
333333
/** Is this an alias TypeBounds? */
334334
final def isTypeAlias: Boolean = this.isInstanceOf[TypeAlias]
335335

336-
/** Is this a MethodType which is from Java */
336+
/** Is this a MethodType which is from Java? */
337337
def isJavaMethod: Boolean = false
338338

339-
/** Is this a MethodType which has implicit or contextual parameters */
339+
/** Is this a Method or PolyType which has implicit or contextual parameters? */
340340
def isImplicitMethod: Boolean = false
341341

342342
/** Is this a Method or PolyType which has contextual parameters as first value parameter list? */
343-
def isContextual: Boolean = false
343+
def isContextualMethod: Boolean = false
344344

345-
/** Is this a Method or PolyType which has implicit parameters as first value parameter list? */
346-
def isImplicit: Boolean = false
347-
348-
/** Is this a MethodType for which the parameters will not be used */
345+
/** Is this a MethodType for which the parameters will not be used? */
349346
def isErasedMethod: Boolean = false
350347

351348
/** Is this a match type or a higher-kinded abstraction of one?
@@ -789,12 +786,12 @@ object Types {
789786
}
790787

791788
/** The set of implicit term members of this type
792-
* @param kind A subset of {Implicit, Implied} that sepcifies what kind of implicit should
789+
* @param kind A subset of {Implicit, Implied} that specifies what kind of implicit should
793790
* be returned
794791
*/
795792
final def implicitMembers(kind: FlagSet)(implicit ctx: Context): List[TermRef] = track("implicitMembers") {
796793
memberDenots(implicitFilter,
797-
(name, buf) => buf ++= member(name).altsWith(_.is(ImplicitOrImpliedTerm & kind)))
794+
(name, buf) => buf ++= member(name).altsWith(_.is(ImplicitOrImpliedOrGivenTerm & kind)))
798795
.toList.map(d => TermRef(this, d.symbol.asTerm))
799796
}
800797

@@ -1507,7 +1504,7 @@ object Types {
15071504
def toFunctionType(dropLast: Int = 0)(implicit ctx: Context): Type = this match {
15081505
case mt: MethodType if !mt.isParamDependent =>
15091506
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
1510-
val isContextual = mt.isContextual && !ctx.erasedTypes
1507+
val isContextual = mt.isContextualMethod && !ctx.erasedTypes
15111508
val isErased = mt.isErasedMethod && !ctx.erasedTypes
15121509
val result1 = mt.nonDependentResultApprox match {
15131510
case res: MethodType => res.toFunctionType()
@@ -3188,15 +3185,14 @@ object Types {
31883185
final override def isImplicitMethod: Boolean =
31893186
companion.eq(ImplicitMethodType) ||
31903187
companion.eq(ErasedImplicitMethodType) ||
3191-
isContextual
3188+
isContextualMethod
31923189
final override def isErasedMethod: Boolean =
31933190
companion.eq(ErasedMethodType) ||
31943191
companion.eq(ErasedImplicitMethodType) ||
31953192
companion.eq(ErasedContextualMethodType)
3196-
final override def isContextual: Boolean =
3193+
final override def isContextualMethod: Boolean =
31973194
companion.eq(ContextualMethodType) ||
31983195
companion.eq(ErasedContextualMethodType)
3199-
final override def isImplicit = isImplicitMethod
32003196

32013197
def computeSignature(implicit ctx: Context): Signature = {
32023198
val params = if (isErasedMethod) Nil else paramInfos
@@ -3289,7 +3285,7 @@ object Types {
32893285
}
32903286

32913287
object MethodType extends MethodTypeCompanion("MethodType") {
3292-
def maker(isJava: Boolean = false, isImplicit: Boolean = false, isErased: Boolean = false, isContextual: Boolean = false): MethodTypeCompanion = {
3288+
def companion(isJava: Boolean = false, isContextual: Boolean = false, isImplicit: Boolean = false, isErased: Boolean = false): MethodTypeCompanion = {
32933289
if (isJava) {
32943290
assert(!isImplicit)
32953291
assert(!isErased)
@@ -3388,8 +3384,8 @@ object Types {
33883384

33893385
def computeSignature(implicit ctx: Context): Signature = resultSignature
33903386

3391-
override def isContextual = resType.isContextual
3392-
override def isImplicit = resType.isImplicit
3387+
override def isContextualMethod = resType.isContextualMethod
3388+
override def isImplicitMethod = resType.isImplicitMethod
33933389

33943390
/** Merge nested polytypes into one polytype. nested polytypes are normally not supported
33953391
* but can arise as temporary data structures.

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ Standard Section: "Comments" Comment*
249249
object TastyFormat {
250250

251251
final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F)
252-
val MajorVersion: Int = 13
252+
val MajorVersion: Int = 14
253253
val MinorVersion: Int = 0
254254

255255
/** Tags used to serialize names */
@@ -441,7 +441,7 @@ object TastyFormat {
441441
final val MATCHtype = 190
442442
final val MATCHtpt = 191
443443

444-
def methodType(isContextual: Boolean, isImplicit: Boolean, isErased: Boolean): Int = {
444+
def methodTypeTag(isContextual: Boolean, isImplicit: Boolean, isErased: Boolean): Int = {
445445
val implicitOffset =
446446
if (isContextual) 2
447447
else if (isImplicit) { assert(!isErased); 4 }

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

+5-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,11 @@ class TreePickler(pickler: TastyPickler) {
259259
case tpe: PolyType if richTypes =>
260260
pickleMethodic(POLYtype, tpe)
261261
case tpe: MethodType if richTypes =>
262-
pickleMethodic(methodType(tpe.isContextual, tpe.isImplicitMethod, tpe.isErasedMethod), tpe)
262+
val tag = methodTypeTag(
263+
isContextual = tpe.isContextualMethod,
264+
isImplicit = tpe.isImplicitMethod && !tpe.isContextualMethod,
265+
isErased = tpe.isErasedMethod)
266+
pickleMethodic(tag, tpe)
263267
case tpe: ParamRef =>
264268
assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe")
265269
case tpe: LazyRef =>

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

+2-4
Original file line numberDiff line numberDiff line change
@@ -767,10 +767,8 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
767767
case METHODtpe | IMPLICITMETHODtpe =>
768768
val restpe = readTypeRef()
769769
val params = until(end, () => readSymbolRef())
770-
def isImplicit =
771-
tag == IMPLICITMETHODtpe ||
772-
params.nonEmpty && (params.head is Implicit)
773-
val maker = MethodType.maker(isImplicit = isImplicit)
770+
val maker = MethodType.companion(
771+
isImplicit = tag == IMPLICITMETHODtpe || params.nonEmpty && params.head.is(Implicit))
774772
maker.fromSymbols(params, restpe)
775773
case POLYtpe =>
776774
val restpe = readTypeRef()

0 commit comments

Comments
 (0)