mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
NCGenerics: ext's might not infer invertible req's
If the extension adds conformance to an invertible protocol, it's confusing for people to also infer conditional requirements on the generic parameters for those invertible protocols. This came up in the review of SE-427.
This commit is contained in:
@@ -2915,6 +2915,18 @@ void PrintAST::printExtendedTypeName(TypeLoc ExtendedTypeLoc) {
|
||||
printTypeLoc(TypeLoc(ExtendedTypeLoc.getTypeRepr(), Ty));
|
||||
}
|
||||
|
||||
/// If an extension adds a conformance for an invertible protocol, then we
|
||||
/// should not print inverses for its generic signature, because no conditional
|
||||
/// requirements are inferred by default for such an extension.
|
||||
static bool isExtensionAddingInvertibleConformance(const ExtensionDecl *ext) {
|
||||
auto conformances = ext->getLocalConformances();
|
||||
for (auto *conf : conformances) {
|
||||
if (conf->getProtocol()->getInvertibleProtocolKind()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrintAST::printSynthesizedExtension(Type ExtendedType,
|
||||
ExtensionDecl *ExtDecl) {
|
||||
@@ -3039,9 +3051,21 @@ void PrintAST::printExtension(ExtensionDecl *decl) {
|
||||
auto baseGenericSig = decl->getExtendedNominal()->getGenericSignature();
|
||||
assert(baseGenericSig &&
|
||||
"an extension can't be generic if the base type isn't");
|
||||
|
||||
auto genSigFlags = defaultGenericRequirementFlags()
|
||||
| IncludeOuterInverses;
|
||||
|
||||
// Disable printing inverses if the extension is adding a conformance
|
||||
// for an invertible protocol itself, as we do not infer any requirements
|
||||
// in such an extension. We need to print the whole signature:
|
||||
// extension S: Copyable where T: Copyable
|
||||
if (isExtensionAddingInvertibleConformance(decl)) {
|
||||
genSigFlags &= ~PrintInverseRequirements;
|
||||
genSigFlags &= ~IncludeOuterInverses;
|
||||
}
|
||||
|
||||
printGenericSignature(genericSig,
|
||||
defaultGenericRequirementFlags()
|
||||
| IncludeOuterInverses,
|
||||
genSigFlags,
|
||||
[baseGenericSig](const Requirement &req) -> bool {
|
||||
// Only include constraints that are not satisfied by the base type.
|
||||
return !baseGenericSig->isRequirementSatisfied(req);
|
||||
|
||||
@@ -782,7 +782,6 @@ InferredGenericSignatureRequest::evaluate(
|
||||
|
||||
unsigned numOuterParams = genericParams.size();
|
||||
if (isExtension) {
|
||||
assert(allowInverses);
|
||||
numOuterParams = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -684,6 +684,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
|
||||
SmallVector<TypeBase *, 2> inferenceSources;
|
||||
SmallVector<Requirement, 2> extraReqs;
|
||||
SourceLoc loc;
|
||||
bool inferInvertibleReqs = true;
|
||||
|
||||
if (auto VD = dyn_cast<ValueDecl>(GC->getAsDecl())) {
|
||||
loc = VD->getLoc();
|
||||
@@ -781,6 +782,35 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
|
||||
} else if (auto *ext = dyn_cast<ExtensionDecl>(GC)) {
|
||||
loc = ext->getLoc();
|
||||
|
||||
// The inherited entries influence the generic signature of the extension,
|
||||
// because if it introduces conformance to invertible protocol IP, we do not
|
||||
// we do not infer any requirements that the generic parameters to conform
|
||||
// to invertible protocols. This forces people to write out the conditions.
|
||||
const unsigned numEntries = ext->getInherited().size();
|
||||
for (unsigned i = 0; i < numEntries; ++i) {
|
||||
InheritedTypeRequest request{ext, i, TypeResolutionStage::Structural};
|
||||
auto result = evaluateOrDefault(ctx.evaluator, request,
|
||||
InheritedTypeResult::forDefault());
|
||||
Type inheritedTy;
|
||||
switch (result) {
|
||||
case InheritedTypeResult::Inherited:
|
||||
inheritedTy = result.getInheritedType();
|
||||
break;
|
||||
case InheritedTypeResult::Suppressed:
|
||||
case InheritedTypeResult::Default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inheritedTy) {
|
||||
if (auto kp = inheritedTy->getKnownProtocol()) {
|
||||
if (getInvertibleProtocolKind(*kp)) {
|
||||
inferInvertibleReqs = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectAdditionalExtensionRequirements(ext->getExtendedType(), extraReqs);
|
||||
|
||||
auto *extendedNominal = ext->getExtendedNominal();
|
||||
@@ -800,7 +830,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
|
||||
genericParams, WhereClauseOwner(GC),
|
||||
extraReqs, inferenceSources, loc,
|
||||
/*isExtension=*/isa<ExtensionDecl>(GC),
|
||||
/*allowInverses=*/true};
|
||||
/*allowInverses=*/inferInvertibleReqs};
|
||||
return evaluateOrDefault(ctx.evaluator, request,
|
||||
GenericSignatureWithError()).getPointer();
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ public enum Optional<Wrapped: ~Copyable>: ~Copyable {
|
||||
case some(Wrapped)
|
||||
}
|
||||
|
||||
extension Optional: Copyable /* where Wrapped: Copyable */ {}
|
||||
extension Optional: Copyable where Wrapped: Copyable {}
|
||||
|
||||
extension Optional: Sendable where Wrapped: ~Copyable & Sendable { }
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public enum Result<Success: ~Copyable, Failure: Error> {
|
||||
case failure(Failure)
|
||||
}
|
||||
|
||||
extension Result: Copyable /* where Success: Copyable */ {}
|
||||
extension Result: Copyable where Success: Copyable {}
|
||||
|
||||
extension Result: Sendable where Success: Sendable & ~Copyable {}
|
||||
|
||||
|
||||
@@ -7,12 +7,15 @@ protocol Q {}
|
||||
class DoggoClass {}
|
||||
|
||||
struct Blah<T: ~Copyable & ~Escapable>: ~Copyable, ~Escapable {}
|
||||
extension Blah: Copyable {} // expected-error {{conditional conformance to suppressible protocol 'Copyable' cannot depend on 'T: Escapable'}}
|
||||
extension Blah: Escapable {} // expected-error {{conditional conformance to suppressible protocol 'Escapable' cannot depend on 'T: Copyable'}}
|
||||
extension Blah: Copyable where T: Copyable & Escapable {}
|
||||
// expected-error@-1 {{conditional conformance to suppressible protocol 'Copyable' cannot depend on 'T: Escapable'}}
|
||||
|
||||
struct Yuck<T: ~Copyable & ~Escapable>: ~Copyable, ~Escapable {}
|
||||
extension Yuck: Copyable where T: ~Escapable {}
|
||||
extension Yuck: Escapable where T: ~Copyable {}
|
||||
extension Blah: Escapable where T: Copyable, T: Escapable {}
|
||||
// expected-error@-1 {{conditional conformance to suppressible protocol 'Escapable' cannot depend on 'T: Copyable'}}
|
||||
|
||||
struct Fixed<T: ~Copyable & ~Escapable>: ~Copyable, ~Escapable {}
|
||||
extension Fixed: Copyable where T: Copyable {}
|
||||
extension Fixed: Escapable where T: Escapable {}
|
||||
|
||||
struct TryConformance<Whatever: ~Copyable>: ~Copyable {}
|
||||
extension TryConformance: Copyable
|
||||
|
||||
@@ -2,11 +2,26 @@
|
||||
// RUN: -enable-experimental-feature NonescapableTypes \
|
||||
// RUN: -enable-experimental-feature SuppressedAssociatedTypes
|
||||
|
||||
// expected-note@+1 {{'T' has '~Copyable' constraint preventing implicit 'Copyable' conformance}}
|
||||
struct AttemptImplicitConditionalConformance<T: ~Copyable>: ~Copyable {
|
||||
var t: T // expected-error {{stored property 't' of 'Copyable'-conforming generic struct 'AttemptImplicitConditionalConformance' has non-Copyable type 'T'}}
|
||||
}
|
||||
extension AttemptImplicitConditionalConformance: Copyable {}
|
||||
// expected-error@-1 {{generic struct 'AttemptImplicitConditionalConformance' required to be 'Copyable' but is marked with '~Copyable'}}
|
||||
|
||||
enum Hello<T: ~Escapable & ~Copyable>: ~Escapable & ~Copyable {}
|
||||
extension Hello: Escapable {} // expected-error {{generic enum 'Hello' required to be 'Escapable' but is marked with '~Escapable'}}
|
||||
extension Hello: Copyable {} // expected-error {{generic enum 'Hello' required to be 'Copyable' but is marked with '~Copyable'}}
|
||||
|
||||
enum HelloExplicitlyFixed<T: ~Escapable & ~Copyable>: Escapable, Copyable {}
|
||||
|
||||
struct NoInverseBecauseNoDefault<T: ~Copyable & ~Escapable>: ~Copyable {}
|
||||
extension NoInverseBecauseNoDefault: Copyable where T: Copyable, T: ~Escapable {}
|
||||
// expected-error@-1 {{cannot suppress '~Escapable' on generic parameter 'T' defined in outer scope}}
|
||||
|
||||
// Check support for explicit conditional conformance
|
||||
public struct ExplicitCond<T: ~Copyable>: ~Copyable {}
|
||||
extension ExplicitCond: Copyable {}
|
||||
extension ExplicitCond: Copyable where T: Copyable {}
|
||||
// expected-note@-1 {{requirement from conditional conformance}}
|
||||
// expected-note@-2 {{requirement from conditional conformance of 'ExplicitCondAlias<NC>' (aka 'ExplicitCond<NC>') to 'Copyable'}}
|
||||
|
||||
@@ -80,7 +95,7 @@ struct ConditionalContainment<T: ~Copyable>: ~Copyable {
|
||||
var y: NC // expected-error {{stored property 'y' of 'Copyable'-conforming generic struct 'ConditionalContainment' has non-Copyable type 'NC'}}
|
||||
}
|
||||
|
||||
extension ConditionalContainment: Copyable {}
|
||||
extension ConditionalContainment: Copyable where T: Copyable {}
|
||||
|
||||
func chk(_ T: RequireCopyable<ConditionalContainment<Int>>) {}
|
||||
|
||||
@@ -126,7 +141,7 @@ enum Maybe<Wrapped: ~Copyable>: ~Copyable {
|
||||
deinit {} // expected-error {{deinitializer cannot be declared in generic enum 'Maybe' that conforms to 'Copyable'}}
|
||||
}
|
||||
|
||||
extension Maybe: Copyable {}
|
||||
extension Maybe: Copyable where Wrapped: Copyable {}
|
||||
|
||||
// expected-note@+4{{requirement specified as 'NC' : 'Copyable'}}
|
||||
// expected-note@+3{{requirement from conditional conformance of 'Maybe<NC>' to 'Copyable'}}
|
||||
@@ -265,7 +280,7 @@ enum MaybeEscapes<T: ~Escapable>: ~Escapable { // expected-note {{generic enum '
|
||||
case none
|
||||
}
|
||||
|
||||
extension MaybeEscapes: Escapable {}
|
||||
extension MaybeEscapes: Escapable where T: Escapable {}
|
||||
|
||||
struct Escapes { // expected-note {{consider adding '~Escapable' to struct 'Escapes'}}
|
||||
let t: MaybeEscapes<NonescapingType> // expected-error {{stored property 't' of 'Escapable'-conforming struct 'Escapes' has non-Escapable type 'MaybeEscapes<NonescapingType>'}}
|
||||
|
||||
@@ -21,7 +21,7 @@ public enum Optional<T: ~Copyable>: ~Copyable {
|
||||
case none
|
||||
}
|
||||
|
||||
extension Optional: Copyable {}
|
||||
extension Optional: Copyable where T: Copyable {}
|
||||
|
||||
public func wrapping<T: ~Copyable>(_ t: consuming T) -> T? {
|
||||
return .some(t)
|
||||
|
||||
@@ -36,7 +36,7 @@ public enum Either<Success: ~Copyable, Failure: Error>: ~Copyable {
|
||||
case failure(Failure)
|
||||
}
|
||||
|
||||
extension Either: Copyable {}
|
||||
extension Either: Copyable where Success: Copyable {}
|
||||
|
||||
extension Either where Failure == Swift.Error {
|
||||
public init(catching body: () throws -> Success) {
|
||||
@@ -77,7 +77,7 @@ public enum Maybe<Wrapped: ~Copyable>: ~Copyable {
|
||||
case just(Wrapped)
|
||||
case nothing
|
||||
}
|
||||
extension Maybe: Copyable {}
|
||||
extension Maybe: Copyable where Wrapped: Copyable {}
|
||||
|
||||
extension Maybe: Show where Wrapped: Show & ~Copyable {
|
||||
public borrowing func show() -> String {
|
||||
|
||||
@@ -136,7 +136,7 @@ enum Maybe<Wrapped: ~Copyable>: ~Copyable {
|
||||
case just(Wrapped)
|
||||
case nothing
|
||||
}
|
||||
extension Maybe: Copyable {}
|
||||
extension Maybe: Copyable where Wrapped: Copyable {}
|
||||
extension Maybe: CustomDebugStringConvertible {
|
||||
var debugDescription: String {
|
||||
"cast succeeded"
|
||||
|
||||
@@ -55,12 +55,12 @@ public struct _Toys {
|
||||
public struct ExplicitHello<T: ~Copyable>: ~Copyable {
|
||||
let thing: T
|
||||
}
|
||||
extension ExplicitHello: Copyable {}
|
||||
extension ExplicitHello: Copyable where T: Copyable {}
|
||||
|
||||
public struct Hello<T: ~Copyable>: ~Copyable, ~Escapable where T: ~Escapable {}
|
||||
|
||||
extension Hello: Escapable where T: ~Copyable {}
|
||||
extension Hello: Copyable where T: ~Escapable {}
|
||||
extension Hello: Escapable where T: Escapable {}
|
||||
extension Hello: Copyable where T: Copyable {}
|
||||
|
||||
public protocol TestAssocTypes {
|
||||
associatedtype A: ~Copyable, _NoCopyP = Int
|
||||
@@ -94,11 +94,11 @@ public struct Outer<A: ~Copyable>: ~Copyable {
|
||||
public struct InnerVariation2<D: ~Escapable>: ~Copyable, ~Escapable {}
|
||||
}
|
||||
|
||||
extension Outer: Copyable {}
|
||||
extension Outer.InnerStruct: Copyable {}
|
||||
extension Outer: Copyable where A: Copyable {}
|
||||
extension Outer.InnerStruct: Copyable where C: Copyable, A: Copyable {}
|
||||
|
||||
extension Outer.InnerVariation1: Copyable {}
|
||||
extension Outer.InnerVariation2: Escapable where A: ~Copyable {}
|
||||
extension Outer.InnerVariation1: Copyable where A: Copyable, D: Copyable & Escapable {}
|
||||
extension Outer.InnerVariation2: Escapable where A: Escapable, D: Escapable {}
|
||||
|
||||
extension Outer.InnerStruct {
|
||||
public func hello<T: ~Escapable>(_ t: T) {}
|
||||
|
||||
@@ -26,14 +26,14 @@ public protocol P: ~Copyable {
|
||||
public struct X<T: ~Copyable>: ~Copyable { }
|
||||
|
||||
// CHECK: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK: extension Test.X : Swift.Copyable {
|
||||
// CHECK: extension Test.X : Swift.Copyable where T : Swift.Copyable {
|
||||
// CHECK-NEXT: func f()
|
||||
// CHECK: }
|
||||
// CHECK: #else
|
||||
// CHECK: extension Test.X {
|
||||
// CHECK-NEXT: func f()
|
||||
// CHECK: }
|
||||
extension X: Copyable {
|
||||
extension X: Copyable where T: Copyable {
|
||||
public func f() { }
|
||||
}
|
||||
|
||||
|
||||
@@ -77,18 +77,18 @@ import NoncopyableGenerics_Misc
|
||||
// CHECK-MISC-NEXT: public struct ExplicitHello<T> : ~Swift.Copyable where T : ~Copyable {
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.ExplicitHello : Swift.Copyable {
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.ExplicitHello : Swift.Copyable where T : Swift.Copyable {
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: public struct Hello<T> : ~Swift.Copyable, ~Swift.Escapable where T : ~Copyable, T : ~Escapable {
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension NoncopyableGenerics_Misc.Hello : Swift.Escapable where T : ~Copyable {
|
||||
// CHECK-MISC-NEXT: extension NoncopyableGenerics_Misc.Hello : Swift.Escapable where T : Swift.Escapable {
|
||||
// CHECK-MISC-NEXT: }
|
||||
// CHECK-MISC: #endif
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension NoncopyableGenerics_Misc.Hello : Swift.Copyable where T : ~Escapable {
|
||||
// CHECK-MISC-NEXT: extension NoncopyableGenerics_Misc.Hello : Swift.Copyable where T : Swift.Copyable {
|
||||
// CHECK-MISC-NEXT: }
|
||||
// CHECK-MISC: #endif
|
||||
|
||||
@@ -121,19 +121,19 @@ import NoncopyableGenerics_Misc
|
||||
// CHECK-MISC: public struct InnerVariation2<D> : ~Swift.Copyable, ~Swift.Escapable where D : ~Escapable
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer : Swift.Copyable {
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer : Swift.Copyable where A : Swift.Copyable {
|
||||
// CHECK-MISC: #endif
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer.InnerStruct : Swift.Copyable {
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer.InnerStruct : Swift.Copyable where A : Swift.Copyable, C : Swift.Copyable {
|
||||
// CHECK-MISC: #endif
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer.InnerVariation1 : Swift.Copyable {
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer.InnerVariation1 : Swift.Copyable where A : Swift.Copyable, D : Swift.Copyable {
|
||||
// CHECK-MISC: #endif
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer.InnerVariation2 : Swift.Escapable where A : ~Copyable {
|
||||
// CHECK-MISC-NEXT: extension {{.*}}.Outer.InnerVariation2 : Swift.Escapable where D : Swift.Escapable {
|
||||
// CHECK-MISC: #endif
|
||||
|
||||
// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
@@ -250,7 +250,7 @@ import Swiftskell
|
||||
// CHECK: #endif
|
||||
|
||||
// CHECK: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-NEXT: extension Swiftskell.Pair : Swift.Copyable {
|
||||
// CHECK-NEXT: extension Swiftskell.Pair : Swift.Copyable where L : Swift.Copyable, R : Swift.Copyable {
|
||||
// CHECK: #endif
|
||||
|
||||
// CHECK: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
@@ -258,7 +258,7 @@ import Swiftskell
|
||||
// CHECK: #endif
|
||||
|
||||
// CHECK: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
// CHECK-NEXT: extension Swiftskell.Maybe : Swift.Copyable {
|
||||
// CHECK-NEXT: extension Swiftskell.Maybe : Swift.Copyable where Wrapped : Swift.Copyable {
|
||||
// CHECK: #endif
|
||||
|
||||
// CHECK: #if compiler(>=5.3) && $NoncopyableGenerics
|
||||
|
||||
@@ -145,7 +145,7 @@ public struct A<T: ~Copyable>: ~Copyable {
|
||||
// CHECK: sil hidden [ossa] @$s4test1AVAARi_zrlEACyxGycfC : $@convention(method) <T where T : ~Copyable> (@thin A<T>.Type) -> @owned A<T> {
|
||||
}
|
||||
|
||||
extension A: Copyable {}
|
||||
extension A: Copyable where T: Copyable {}
|
||||
|
||||
// <T: ~Copyable>
|
||||
extension A where T: ~Copyable {
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
struct G<T: ~Copyable>: ~Copyable { }
|
||||
|
||||
extension G: Copyable {}
|
||||
extension G: Copyable where T: Copyable {}
|
||||
|
||||
@@ -15,14 +15,14 @@ enum RudeEnum<T: ~Copyable>: Copyable {
|
||||
|
||||
struct CondCopyableStruct<T: ~Copyable>: ~Copyable {}
|
||||
|
||||
extension CondCopyableStruct: Copyable {}
|
||||
extension CondCopyableStruct: Copyable where T: Copyable {}
|
||||
|
||||
enum CondCopyableEnum<T: ~Copyable>: ~Copyable {
|
||||
case some(T)
|
||||
case none
|
||||
}
|
||||
|
||||
extension CondCopyableEnum: Copyable {}
|
||||
extension CondCopyableEnum: Copyable where T: Copyable {}
|
||||
|
||||
protocol NoEscapeP: ~Escapable {}
|
||||
|
||||
@@ -39,14 +39,14 @@ enum TooRudeEnum<T: ~Escapable>: Escapable {
|
||||
|
||||
struct CondEscapableStruct<T: ~Escapable>: ~Escapable {}
|
||||
|
||||
extension CondEscapableStruct: Escapable {}
|
||||
extension CondEscapableStruct: Escapable where T: Escapable {}
|
||||
|
||||
enum CondEscapableEnum<T: ~Escapable>: ~Escapable {
|
||||
case some(T)
|
||||
case none
|
||||
}
|
||||
|
||||
extension CondEscapableEnum: Escapable {}
|
||||
extension CondEscapableEnum: Escapable where T: Escapable {}
|
||||
|
||||
// MARK: ensure certain conditionally Copyable types are treated as trivial (no ownership in func signature).
|
||||
|
||||
@@ -142,18 +142,18 @@ struct MyStruct<T: ~Copyable & ~Escapable>: ~Copyable & ~Escapable {
|
||||
var x: T
|
||||
}
|
||||
|
||||
extension MyStruct: Copyable where T: Copyable & ~Escapable {}
|
||||
extension MyStruct: Copyable where T: Copyable {}
|
||||
|
||||
extension MyStruct: Escapable where T: Escapable & ~Copyable {}
|
||||
extension MyStruct: Escapable where T: Escapable {}
|
||||
|
||||
enum MyEnum<T: ~Copyable & ~Escapable>: ~Copyable & ~Escapable {
|
||||
case x(T)
|
||||
case knoll
|
||||
}
|
||||
|
||||
extension MyEnum: Copyable where T: Copyable & ~Escapable {}
|
||||
extension MyEnum: Copyable where T: Copyable {}
|
||||
|
||||
extension MyEnum: Escapable where T: Escapable & ~Copyable {}
|
||||
extension MyEnum: Escapable where T: Escapable {}
|
||||
|
||||
enum Trivial {
|
||||
case a, b, c
|
||||
|
||||
@@ -21,9 +21,9 @@ public enum Nillable<Wrapped: ~Copyable & ~Escapable>: ~Copyable & ~Escapable {
|
||||
case some(Wrapped)
|
||||
}
|
||||
|
||||
extension Nillable: Copyable where Wrapped: ~Escapable /* & Copyable */ {}
|
||||
extension Nillable: Copyable where Wrapped: Copyable {}
|
||||
|
||||
extension Nillable: Escapable where Wrapped: ~Copyable /* & Escapable */ {}
|
||||
extension Nillable: Escapable where Wrapped: Escapable {}
|
||||
|
||||
extension Nillable: Sendable where Wrapped: ~Copyable & ~Escapable & Sendable { }
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
struct G<T: ~Copyable>: ~Copyable {}
|
||||
|
||||
extension G: Copyable {}
|
||||
extension G: Copyable where T: Copyable {}
|
||||
|
||||
protocol Base {}
|
||||
protocol Derived: Base {}
|
||||
|
||||
@@ -25,7 +25,7 @@ public enum Maybe<Wrapped: ~Copyable>: ~Copyable {
|
||||
case none
|
||||
}
|
||||
|
||||
extension Maybe: Copyable {}
|
||||
extension Maybe: Copyable where Wrapped: Copyable {}
|
||||
|
||||
public func ncIdentity<T: ~Copyable>(_ t: consuming T) -> T { return t }
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
// CHECK-PRINT-DAG: protocol Generator<Value> {
|
||||
// CHECK-PRINT-DAG: enum Maybe<Wrapped> : ~Copyable where Wrapped : ~Copyable {
|
||||
// CHECK-PRINT-DAG: extension Maybe : Copyable {
|
||||
// CHECK-PRINT-DAG: extension Maybe : Copyable where Wrapped : Copyable {
|
||||
// CHECK-PRINT-DAG: func ncIdentity<T>(_ t: consuming T) -> T where T : ~Copyable
|
||||
// CHECK-PRINT-DAG: protocol Either<Left, Right> : ~Copyable {
|
||||
// CHECK-PRINT-DAG: associatedtype Left : ~Copyable
|
||||
|
||||
Reference in New Issue
Block a user