Files
swift-mirror/test/decl/protocol/req/missing_conformance.swift
Slava Pestov 6d84c18ba4 Sema: Check 'where' clause requirements on type witnesses
In the included test case, conformance checking of Wrapper : B would
pick up typealias Foo as a witness for the associated type B.Foo.

However, this typealias Foo is defined in a constrained extension where
T : A, and the underlying type references the associated type A.Foo
on T.

The resulting substitution is invalid when the conformance Wrapper : B
is used in a context where T does not conform to A.

Instead, we should ignore this typealias entirely, since it appears
in an unusable constrained extension.

Fixes <rdar://problem/60219705>, <https://bugs.swift.org/browse/SR-12327>,
<https://bugs.swift.org/browse/SR-12663>.
2020-08-15 01:43:13 -04:00

142 lines
5.9 KiB
Swift

// RUN: %target-typecheck-verify-swift
// Test candidates for witnesses that are missing conformances
// in various ways.
protocol LikeSetAlgebra {
func onion(_ other: Self) -> Self // expected-note {{protocol requires function 'onion' with type '(X) -> X'; do you want to add a stub?}}
func indifference(_ other: Self) -> Self // expected-note {{protocol requires function 'indifference' with type '(X) -> X'; do you want to add a stub?}}
}
protocol LikeOptionSet : LikeSetAlgebra, RawRepresentable {}
extension LikeOptionSet where RawValue : FixedWidthInteger {
func onion(_ other: Self) -> Self { return self } // expected-note {{candidate would match if 'X.RawValue' conformed to 'FixedWidthInteger'}}
func indifference(_ other: Self) -> Self { return self } // expected-note {{candidate would match if 'X.RawValue' conformed to 'FixedWidthInteger'}}
}
struct X : LikeOptionSet {}
// expected-error@-1 {{type 'X' does not conform to protocol 'LikeSetAlgebra'}}
// expected-error@-2 {{type 'X' does not conform to protocol 'RawRepresentable'}}
protocol IterProtocol {}
protocol LikeSequence {
associatedtype Iter : IterProtocol // expected-note {{unable to infer associated type 'Iter' for protocol 'LikeSequence'}}
func makeIter() -> Iter
}
extension LikeSequence where Self == Self.Iter {
func makeIter() -> Self { return self } // expected-note {{candidate would match and infer 'Iter' = 'Y' if 'Y' conformed to 'IterProtocol'}}
}
struct Y : LikeSequence {} // expected-error {{type 'Y' does not conform to protocol 'LikeSequence'}}
protocol P1 {
associatedtype Result
func get() -> Result // expected-note {{protocol requires function 'get()' with type '() -> Result'; do you want to add a stub?}}
func got() // expected-note {{protocol requires function 'got()' with type '() -> ()'; do you want to add a stub?}}
}
protocol P2 {
static var singularThing: Self { get }
}
extension P1 where Result : P2 {
func get() -> Result { return Result.singularThing } // expected-note {{candidate would match if 'Result' conformed to 'P2'}}
}
protocol P3 {}
extension P1 where Self : P3 {
func got() {} // expected-note {{candidate would match if 'Z<T1, T2, T3, Result, T4>' conformed to 'P3'}}
}
struct Z<T1, T2, T3, Result, T4> : P1 {} // expected-error {{type 'Z<T1, T2, T3, Result, T4>' does not conform to protocol 'P1'}}
protocol P4 {
func this() // expected-note 2 {{protocol requires function 'this()' with type '() -> ()'; do you want to add a stub?}}
}
protocol P5 {}
extension P4 where Self : P5 {
func this() {} // expected-note {{candidate would match if 'W' conformed to 'P5'}}
//// expected-note@-1 {{candidate would match if 'S<T>.SS' conformed to 'P5'}}
}
struct W : P4 {} // expected-error {{type 'W' does not conform to protocol 'P4'}}
struct S<T> {
struct SS : P4 {} // expected-error {{type 'S<T>.SS' does not conform to protocol 'P4'}}
}
class C {}
protocol P6 {
associatedtype T : C // expected-note {{unable to infer associated type 'T' for protocol 'P6'}}
func f(t: T)
}
struct A : P6 { // expected-error {{type 'A' does not conform to protocol 'P6'}}
func f(t: Int) {} // expected-note {{candidate can not infer 'T' = 'Int' because 'Int' is not a class type and so can't inherit from 'C'}}
}
protocol P7 {}
protocol P8 {
associatedtype T : P7 // expected-note {{unable to infer associated type 'T' for protocol 'P8'}}
func g(t: T)
}
struct B : P8 { // expected-error {{type 'B' does not conform to protocol 'P8'}}
func g(t: (Int, String)) {} // expected-note {{candidate can not infer 'T' = '(Int, String)' because '(Int, String)' is not a nominal type and so can't conform to 'P7'}}
}
protocol P9 {
func foo() // expected-note {{protocol requires function 'foo()' with type '() -> ()'; do you want to add a stub?}}
}
class C2 {}
extension P9 where Self : C2 {
func foo() {} // expected-note {{candidate would match if 'C3' subclassed 'C2'}}
}
class C3 : P9 {} // expected-error {{type 'C3' does not conform to protocol 'P9'}}
protocol P10 {
associatedtype A
func bar() // expected-note {{protocol requires function 'bar()' with type '() -> ()'; do you want to add a stub?}}
}
extension P10 where A == Int {
func bar() {} // expected-note {{candidate would match if 'A' was the same type as 'Int'}}
}
struct S2<A> : P10 {} // expected-error {{type 'S2<A>' does not conform to protocol 'P10'}}
protocol P11 {}
protocol P12 {
associatedtype A : P11 // expected-note {{unable to infer associated type 'A' for protocol 'P12'}}
func bar() -> A
}
extension Int : P11 {}
struct S3 : P12 { // expected-error {{type 'S3' does not conform to protocol 'P12'}}
func bar() -> P11 { return 0 }
// expected-note@-1 {{candidate can not infer 'A' = 'P11' because 'P11' is not a nominal type and so can't conform to 'P11'}}
}
// SR-12759
struct CountSteps1<T> : Collection {
init(count: Int) { self.count = count }
var count: Int
var startIndex: Int { 0 }
var endIndex: Int { count }
func index(after i: Int) -> Int {
totalSteps += 1 // expected-error {{cannot find 'totalSteps' in scope}}
return i + 1
}
subscript(i: Int) -> Int { return i }
}
extension CountSteps1 // expected-error {{type 'CountSteps1<T>' does not conform to protocol 'RandomAccessCollection'}}
// expected-error@-1 {{conditional conformance of type 'CountSteps1<T>' to protocol 'RandomAccessCollection' does not imply conformance to inherited protocol 'BidirectionalCollection'}}
// expected-note@-2 {{did you mean to explicitly state the conformance like 'extension CountSteps1: BidirectionalCollection where ...'?}}
// expected-error@-3 {{type 'CountSteps1<T>' does not conform to protocol 'BidirectionalCollection'}}
: RandomAccessCollection
where T : Equatable
{
typealias Index = Int
// expected-error@-1 {{invalid redeclaration of synthesized implementation for protocol requirement 'Index'}}
func index(_ i: Index, offsetBy d: Int) -> Index {
return i + d
}
}