@@ -666,13 +666,33 @@ object CaptureSet:
666666 then i " under-approximating the result of mapping $ref to $mapped"
667667 else " "
668668
669- private def capImpliedByCapability (parent : Type )(using Context ): Capability =
670- if parent.derivesFromStateful then GlobalCap .readOnly else GlobalCap
669+ private def capImpliedByCapability (parent : Type , sym : Symbol , variance : Int )(using Context ): Capability =
670+ // Since standard library classes are not compiled with separation checking,
671+ // they treat Array as a Pure class. That means, no effort is made to distinguish
672+ // between exclusive and read-only arrays. To compensate in code compiled under
673+ // strict mutability, we treat contravariant arrays in signatures of stdlib
674+ // members as read-only (so all arrays may be passed to them), and co- and
675+ // invariant arrays as exclusive.
676+ // TODO This scheme should also apply whenever code under strict mutability interfaces
677+ // with code compiled without. To do that we will need to store in the Tasty format
678+ // a flag whether code was compiled with separation checking on. This will have
679+ // to wait until 3.10.
680+ def isArrayFromScalaPackage =
681+ parent.classSymbol == defn.ArrayClass
682+ && ccConfig.strictMutability
683+ && variance >= 0
684+ && sym.isContainedIn(defn.ScalaPackageClass )
685+ if parent.derivesFromStateful && ! isArrayFromScalaPackage
686+ then GlobalCap .readOnly
687+ else GlobalCap
671688
672689 /* The same as {cap} but generated implicitly for references of Capability subtypes.
690+ * @param parent the type to which the capture set will be attached
691+ * @param sym the symbol carrying that type
692+ * @param variance the variance in which `parent` appears in the type of `sym`
673693 */
674- class CSImpliedByCapability (parent : Type )(using @ constructorOnly ctx : Context )
675- extends Const (SimpleIdentitySet (capImpliedByCapability(parent)))
694+ class CSImpliedByCapability (parent : Type , sym : Symbol , variance : Int )(using @ constructorOnly ctx : Context )
695+ extends Const (SimpleIdentitySet (capImpliedByCapability(parent, sym, variance )))
676696
677697 /** A special capture set that gets added to the types of symbols that were not
678698 * themselves capture checked, in order to admit arbitrary corresponding capture
0 commit comments