Skip to content

Commit e778d52

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 8041083 commit e778d52

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
@@ -1649,8 +1649,8 @@ trait Applications extends Compatibility {
16491649
mt.derivedLambdaType(mt.paramNames, mt.paramInfos, widenGiven(mt.resultType, alt))
16501650
case pt: PolyType =>
16511651
pt.derivedLambdaType(pt.paramNames, pt.paramInfos, widenGiven(pt.resultType, alt))
1652-
case _ =>
1653-
if (alt.symbol.isAllOf(SyntheticGivenMethod)) tp.widenToParents
1652+
case rt =>
1653+
if alt.symbol.isCoDefinedGiven(rt.typeSymbol) then tp.widenToParents
16541654
else tp
16551655
}
16561656

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

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

872872
sym.info.stripPoly match {
873873
case mt @ MethodType(_ :: Nil)
874-
if !mt.isImplicitMethod && !sym.is(Synthetic) => // it's an old-styleconversion
874+
if !mt.isImplicitMethod && !sym.isCoDefinedGiven(mt.finalResultType.typeSymbol) =>
875+
// it's an old-style conversion
875876
check()
876877
case _ =>
877878
}

0 commit comments

Comments
 (0)