Skip to content

Commit 2c0d406

Browse files
committed
Revert "Allow a witness's noescape parameter to match a requirement's escaping parameter"
This reverts commit 44e230b.
1 parent 0d93b39 commit 2c0d406

File tree

5 files changed

+18
-56
lines changed

5 files changed

+18
-56
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,6 @@ static std::tuple<Type, Type, OptionalAdjustmentKind>
138138
getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
139139
Type witnessType, bool witnessTypeIsIUO,
140140
VarianceKind variance) {
141-
// If the witness type is noescape but the requirement type is not,
142-
// adjust the witness type to be escaping. This permits a limited form of
143-
// covariance.
144-
bool reqNoescapeToEscaping = false;
145-
(void)adjustInferredAssociatedType(reqtType, reqNoescapeToEscaping);
146-
bool witnessNoescapeToEscaping = false;
147-
Type adjustedWitnessType =
148-
adjustInferredAssociatedType(witnessType, witnessNoescapeToEscaping);
149-
if (witnessNoescapeToEscaping && !reqNoescapeToEscaping)
150-
witnessType = adjustedWitnessType;
151-
152141
// For @objc protocols, deal with differences in the optionality.
153142
// FIXME: It probably makes sense to extend this to non-@objc
154143
// protocols as well, but this requires more testing.
@@ -163,7 +152,8 @@ getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
163152
reqtType = reqtValueType;
164153
}
165154
bool witnessIsOptional = false;
166-
if (Type witnessValueType = witnessType->getOptionalObjectType()) {
155+
if (Type witnessValueType =
156+
witnessType->getOptionalObjectType()) {
167157
witnessIsOptional = true;
168158
witnessType = witnessValueType;
169159
}

lib/Sema/TypeCheckProtocol.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -852,13 +852,6 @@ RequirementMatch matchWitness(TypeChecker &tc,
852852
AssociatedTypeDecl *getReferencedAssocTypeOfProtocol(Type type,
853853
ProtocolDecl *proto);
854854

855-
/// Perform any necessary adjustments to the inferred associated type to
856-
/// make it suitable for later use.
857-
///
858-
/// \param noescapeToEscaping Will be set \c true if this operation performed
859-
/// the noescape-to-escaping adjustment.
860-
Type adjustInferredAssociatedType(Type type, bool &noescapeToEscaping);
861-
862855
}
863856

864857
#endif // SWIFT_SEMA_PROTOCOL_H

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -607,11 +607,13 @@ AssociatedTypeInference::inferTypeWitnessesViaAssociatedType(
607607
return result;
608608
}
609609

610-
Type swift::adjustInferredAssociatedType(Type type, bool &noescapeToEscaping) {
610+
/// Perform any necessary adjustments to the inferred associated type to
611+
/// make it suitable for later use.
612+
static Type adjustInferredAssociatedType(Type type) {
611613
// If we have an optional type, adjust its wrapped type.
612614
if (auto optionalObjectType = type->getOptionalObjectType()) {
613615
auto newOptionalObjectType =
614-
adjustInferredAssociatedType(optionalObjectType, noescapeToEscaping);
616+
adjustInferredAssociatedType(optionalObjectType);
615617
if (newOptionalObjectType.getPointer() == optionalObjectType.getPointer())
616618
return type;
617619

@@ -621,11 +623,14 @@ Type swift::adjustInferredAssociatedType(Type type, bool &noescapeToEscaping) {
621623
// If we have a noescape function type, make it escaping.
622624
if (auto funcType = type->getAs<FunctionType>()) {
623625
if (funcType->isNoEscape()) {
624-
noescapeToEscaping = true;
625626
return FunctionType::get(funcType->getParams(), funcType->getResult(),
626627
funcType->getExtInfo().withNoEscape(false));
627628
}
628629
}
630+
631+
// We can only infer materializable types.
632+
if (!type->isMaterializable()) return nullptr;
633+
629634
return type;
630635
}
631636

@@ -684,11 +689,8 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitness(ValueDecl *req,
684689
if (secondType->hasError())
685690
return true;
686691

687-
// Adjust the type to a type that can be written explicitly.
688-
bool noescapeToEscaping = false;
689-
Type inferredType =
690-
adjustInferredAssociatedType(secondType, noescapeToEscaping);
691-
if (!inferredType->isMaterializable())
692+
Type inferredType = adjustInferredAssociatedType(secondType);
693+
if (!inferredType)
692694
return true;
693695

694696
auto proto = Conformance->getProtocol();

test/SILGen/witnesses.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,3 @@ class CrashableBase {
510510
// CHECK-NEXT: return [[RESULT]] : $()
511511

512512
class GenericCrashable<T> : CrashableBase, Crashable {}
513-
514-
// rdar://problem/35297911: allow witness with a noescape parameter to
515-
// match a requirement with an escaping paameter.
516-
protocol EscapingReq {
517-
func f(_: @escaping (Int) -> Int)
518-
}
519-
520-
// CHECK-LABEL: sil private [transparent] [thunk] @$S9witnesses18EscapingCovarianceVAA0B3ReqA2aDP1fyyS2icFTW : $@convention(witness_method: EscapingReq) (@owned @callee_guaranteed (Int) -> Int, @in_guaranteed EscapingCovariance) -> ()
521-
// CHECK-NOT: return
522-
// CHECK: convert_escape_to_noescape %0
523-
struct EscapingCovariance: EscapingReq {
524-
func f(_: (Int) -> Int) { }
525-
}

test/decl/protocol/conforms/associated_type.swift

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ protocol P1 {
3838
associatedtype A
3939

4040
func f(_: A)
41+
// expected-note@-1 {{protocol requires function 'f' with type '(X1c.A) -> ()' (aka '((Int) -> Int) -> ()'); do you want to add a stub?}}
42+
// expected-note@-2 {{protocol requires function 'f' with type '((Int) -> Int) -> ()'; do you want to add a stub?}}
4143
}
4244

4345
struct X1a : P1 {
@@ -50,24 +52,12 @@ struct X1b : P1 {
5052
func f(_: @escaping (Int) -> Int) { }
5153
}
5254

53-
struct X1c : P1 {
55+
struct X1c : P1 { // expected-error{{type 'X1c' does not conform to protocol 'P1'}}
5456
typealias A = (Int) -> Int
5557

56-
func f(_: (Int) -> Int) { }
58+
func f(_: (Int) -> Int) { } // expected-note{{candidate has non-matching type '((Int) -> Int) -> ()'}}
5759
}
5860

59-
struct X1d : P1 {
60-
func f(_: (Int) -> Int) { }
61-
}
62-
63-
protocol P2 {
64-
func f(_: (Int) -> Int) // expected-note{{protocol requires function 'f' with type '((Int) -> Int) -> ()'; do you want to add a stub?}}
65-
}
66-
67-
struct X2a : P2 {
68-
func f(_: (Int) -> Int) { }
69-
}
70-
71-
struct X2b : P2 { // expected-error{{type 'X2b' does not conform to protocol 'P2'}}
72-
func f(_: @escaping (Int) -> Int) { } // expected-note{{candidate has non-matching type '(@escaping (Int) -> Int) -> ()'}}
61+
struct X1d : P1 { // expected-error{{type 'X1d' does not conform to protocol 'P1'}}
62+
func f(_: (Int) -> Int) { } // expected-note{{candidate has non-matching type '((Int) -> Int) -> ()' [with A = (Int) -> Int]}}
7363
}

0 commit comments

Comments
 (0)