@@ -1087,13 +1087,11 @@ following changes are permitted:
1087
1087
- Removing any non-public, non-versioned member.
1088
1088
- Changing the body of any methods, initializers, or accessors.
1089
1089
1090
- .. admonition :: TODO
1091
-
1092
- How does "adding any new member" square with the restrictions on adding
1093
- initializers to classes? Are they inherently convenience initializers?
1090
+ .. note ::
1094
1091
1095
- What about everything else? New members in protocols can result in new
1096
- overridable members in classes. How does that work?
1092
+ Although it is not related to evolution, it is worth noting that members of
1093
+ protocol extensions that do *not * satisfy protocol requirements are not
1094
+ overrideable, even when the conforming type is a class.
1097
1095
1098
1096
1099
1097
Operators
@@ -1454,6 +1452,104 @@ Because this tool would require a fair amount of additional work, it is not
1454
1452
part of this initial model. It is something we may decide to add in the future.
1455
1453
1456
1454
1455
+ Open Issues
1456
+ ===========
1457
+
1458
+ There are still a number of known issues with the model described in this
1459
+ document. We should endeavour to account for each of them, and if we can't come
1460
+ up with a satisfactory implementation we should at least make sure that they
1461
+ will not turn into pitfalls for library or client developers.
1462
+
1463
+
1464
+ Subclass and base both conform to protocol
1465
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1466
+
1467
+ ::
1468
+
1469
+ // Library, version 1
1470
+ class Base {}
1471
+ protocol P {}
1472
+
1473
+ ::
1474
+
1475
+ // Client, version 1
1476
+ class Subclass : Base, P {}
1477
+
1478
+ ::
1479
+
1480
+ // Library, version 2
1481
+ @available(2.0)
1482
+ extension Base : P {}
1483
+
1484
+ Now ``Subclass `` conforms to ``P `` two different ways, which may be
1485
+ incompatible (especially if ``P `` has associated types or requirements
1486
+ involving ``Self ``).
1487
+
1488
+ Additionally, the client can't even remove ``Subclass ``'s conformance to ``P ``,
1489
+ because it may itself be a library with other code depending on it. We could
1490
+ fix that with an annotation to explicitly inherent the conformance of ``P ``
1491
+ from the base class, but even that may not be possible if there are
1492
+ incompatible associated types involved (because changing a member typealias is
1493
+ not a safe change).
1494
+
1495
+ One solution is to disallow adding a conformance for an existing protocol to a
1496
+ publicly-subclassable class.
1497
+
1498
+
1499
+ Recompiling changes a protocol's implementation
1500
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1501
+
1502
+ ::
1503
+
1504
+ // Library, version 1
1505
+ protocol P {}
1506
+ protocol Q {}
1507
+ func use<T: P>(value: T) {}
1508
+
1509
+ ::
1510
+
1511
+ // Client, version 1
1512
+ struct S : P, Q {}
1513
+ use(S())
1514
+
1515
+ ::
1516
+
1517
+ // Library, version 2
1518
+ protocol P {
1519
+ @available(2.0)
1520
+ func foo() { print("default") }
1521
+ }
1522
+
1523
+ extension P where Self: Q {
1524
+ @available(2.0)
1525
+ func foo() { print("constrained") }
1526
+ }
1527
+
1528
+ func use<T: P>(value: T) { value.foo() }
1529
+
1530
+ Before the client is recompiled, the implementation of ``foo() `` used for ``S ``
1531
+ instances can only be the default implementation, i.e. the one that prints
1532
+ "default". However, recompiling the client will result in the constrained
1533
+ implementation being considered a "better" match for the protocol requirement,
1534
+ thus changing the behavior of the program.
1535
+
1536
+ This should never change the *meaning * of a program, since the default
1537
+ implementation for a newly-added requirement should always be *correct. *
1538
+ However, it may have significantly different performance characteristics or
1539
+ side effects that would make the difference in behavior a surprise.
1540
+
1541
+ This is similar to adding a new overload to an existing set of functions, which
1542
+ can also change the meaning of client code just by recompiling. However, the
1543
+ difference here is that the before-recompilation behavior was never requested
1544
+ or acknowledged by the client; it's just the best the library can do.
1545
+
1546
+ A possible solution here is to require the client to acknowledge the added
1547
+ requirement in some way when it is recompiled.
1548
+
1549
+ (We do not want to perform overload resolution at run time to find the best
1550
+ possible default implementation for a given type.)
1551
+
1552
+
1457
1553
Summary
1458
1554
=======
1459
1555
0 commit comments