Skip to content

Commit 8885abd

Browse files
committed
Another scheme to mark implicit methods that were synthetic
Find other scheme to know whether some method is a structural given instance or an implicit conversion associated with an implicit class. Previously we characterized these methods by their Synthetic flag, but that meant that they were not automatically exported. So we now drop Synthetic and use a flag `GivenClass` on the class half of the pair. The old scheme is still recognized in order to maintain Tasty backwards compatibility.
1 parent 2564692 commit 8885abd

File tree

5 files changed

+24
-7
lines changed

5 files changed

+24
-7
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,10 @@ object desugar {
809809
Nil
810810
}
811811
}
812-
val classMods = if mods.is(Given) then mods &~ Given | Synthetic else mods
812+
val classMods =
813+
if mods.is(Given) then mods &~ Given | Synthetic | GivenClass
814+
else if mods.is(Implicit) then mods &~ Implicit | GivenClass
815+
else mods
813816
cpy.TypeDef(cdef: TypeDef)(
814817
name = className,
815818
rhs = cpy.Template(impl)(constr, parents1, clsDerived, self1,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ object Flags {
314314
/** A Scala 2x super accessor / an unpickled Scala 2.x class */
315315
val (SuperParamAliasOrScala2x @ _, SuperParamAlias @ _, Scala2x @ _) = newFlags(26, "<super-param-alias>", "<scala-2.x>")
316316

317-
/** A parameter with a default value */
318-
val (_, HasDefault @ _, _) = newFlags(27, "<hasdefault>")
317+
/** A parameter with a default value / A structural given class or an implicit class */
318+
val (_, HasDefault @ _, GivenClass @ _) = newFlags(27, "<hasdefault/given-class>")
319319

320320
/** An extension method, or a collective extension instance */
321321
val (Extension @ _, ExtensionMethod @ _, _) = newFlags(28, "<extension>")
@@ -568,6 +568,7 @@ object Flags {
568568
val FinalOrSealed: FlagSet = Final | Sealed
569569
val GivenOrImplicit: FlagSet = Given | Implicit
570570
val GivenOrImplicitVal: FlagSet = GivenOrImplicit.toTermFlags
571+
val GivenMethod: FlagSet = Given | Method
571572
val InlineOrProxy: FlagSet = Inline | InlineProxy // An inline method or inline argument proxy */
572573
val InlineMethod: FlagSet = Inline | Method
573574
val InlineParam: FlagSet = Inline | Param
@@ -600,7 +601,6 @@ object Flags {
600601
val Scala2Trait: FlagSet = Scala2x | Trait
601602
val SyntheticArtifact: FlagSet = Synthetic | Artifact
602603
val SyntheticCase: FlagSet = Synthetic | Case
603-
val SyntheticGivenMethod: FlagSet = Synthetic | Given | Method
604604
val SyntheticModule: FlagSet = Synthetic | Module
605605
val SyntheticOpaque: FlagSet = Synthetic | Opaque
606606
val SyntheticParam: FlagSet = Synthetic | Param

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,19 @@ object SymDenotations {
711711
}
712712
)
713713

714+
/** Do this symbol and `cls` represent a pair of a given or implicit method and
715+
* its associated class that were defined by a single definition?
716+
* This can mean one of two things:
717+
* - the method and class are defined in a structural given instance, or
718+
* - the class is an implicit class and the method is its implicit conversion.
719+
*/
720+
final def isCoDefinedGiven(cls: Symbol)(using Context): Boolean =
721+
is(Method) && isOneOf(GivenOrImplicit)
722+
&& ( is(Synthetic) // previous scheme used in 3.0
723+
|| cls.is(GivenClass) // new scheme from 3.1
724+
)
725+
&& name == cls.name.toTermName && owner == cls.owner
726+
714727
/** Is this a denotation of a stable term (or an arbitrary type)?
715728
* Terms are stable if they are idempotent (as in TreeInfo.Idempotent): that is, they always return the same value,
716729
* if any.

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,8 +1648,8 @@ trait Applications extends Compatibility {
16481648
mt.derivedLambdaType(mt.paramNames, mt.paramInfos, widenGiven(mt.resultType, alt))
16491649
case pt: PolyType =>
16501650
pt.derivedLambdaType(pt.paramNames, pt.paramInfos, widenGiven(pt.resultType, alt))
1651-
case _ =>
1652-
if (alt.symbol.isAllOf(SyntheticGivenMethod)) tp.widenToParents
1651+
case rt =>
1652+
if alt.symbol.isCoDefinedGiven(rt.typeSymbol) then tp.widenToParents
16531653
else tp
16541654
}
16551655

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,8 @@ trait Checking {
847847

848848
sym.info.stripPoly match {
849849
case mt @ MethodType(_ :: Nil)
850-
if !mt.isImplicitMethod && !sym.is(Synthetic) => // it's an old-styleconversion
850+
if !mt.isImplicitMethod && !sym.isCoDefinedGiven(mt.finalResultType.typeSymbol) =>
851+
// it's an old-style conversion
851852
check()
852853
case _ =>
853854
}

0 commit comments

Comments
 (0)