mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
(...is constrained to be a subtype of another) Previously the compiler would just mark the entry in the inheritance clause invalid and move on without emitting any errors; in certain circumstances in no-asserts builds this could actually lead to everything working "correctly" if all conforming types happened to pick the same concrete type for both associated types. In Swift 4 this can actually be enforced with a same-type requirement, which will guarantee that the two associated types are the same even in generic contexts. This fix avoids assertions and crashes, but the diagnostic is still incorrect, and in the simple case of the inheritance clause it's redundant. Doing something better and possibly even downgrading it to a warning in Swift 3 mode is tracked by rdar://problem/32409449. Initial patch by Slava, fixed up by me.
78 lines
2.8 KiB
Swift
78 lines
2.8 KiB
Swift
// RUN: %target-typecheck-verify-swift -parse-as-library
|
|
|
|
// Protocols cannot be nested inside other types, and types cannot
|
|
// be nested inside protocols
|
|
|
|
struct OuterGeneric<D> {
|
|
protocol InnerProtocol { // expected-error{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
|
|
associatedtype Rooster
|
|
func flip(_ r: Rooster)
|
|
func flop(_ t: D) // expected-error{{use of undeclared type 'D'}}
|
|
}
|
|
}
|
|
|
|
class OuterGenericClass<T> {
|
|
protocol InnerProtocol { // expected-error{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
|
|
associatedtype Rooster
|
|
func flip(_ r: Rooster)
|
|
func flop(_ t: T) // expected-error{{use of undeclared type 'T'}}
|
|
}
|
|
}
|
|
|
|
protocol OuterProtocol {
|
|
associatedtype Hen
|
|
protocol InnerProtocol { // expected-error{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
|
|
// expected-note@-1 {{did you mean 'InnerProtocol'?}}
|
|
associatedtype Rooster
|
|
func flip(_ r: Rooster)
|
|
func flop(_ h: Hen) // expected-error{{use of undeclared type 'Hen'}}
|
|
}
|
|
}
|
|
|
|
struct ConformsToOuterProtocol : OuterProtocol {
|
|
typealias Hen = Int
|
|
|
|
func f() { let _ = InnerProtocol.self }
|
|
// expected-error@-1 {{use of unresolved identifier 'InnerProtocol'}}
|
|
}
|
|
|
|
protocol Racoon {
|
|
associatedtype Stripes
|
|
class Claw<T> { // expected-error{{type 'Claw' cannot be nested in protocol 'Racoon'}}
|
|
func mangle(_ s: Stripes) {}
|
|
}
|
|
struct Fang<T> { // expected-error{{type 'Fang' cannot be nested in protocol 'Racoon'}}
|
|
func gnaw(_ s: Stripes) {}
|
|
}
|
|
enum Fur { // expected-error{{type 'Fur' cannot be nested in protocol 'Racoon'}}
|
|
case Stripes
|
|
}
|
|
}
|
|
|
|
enum SillyRawEnum : SillyProtocol.InnerClass {}
|
|
// expected-error@-1 {{reference to generic type 'SillyProtocol.InnerClass' requires arguments in <...>}}
|
|
// expected-error@-2 {{type 'SillyRawEnum' does not conform to protocol 'RawRepresentable'}}
|
|
|
|
protocol SillyProtocol {
|
|
class InnerClass<T> {} // expected-error {{type 'InnerClass' cannot be nested in protocol 'SillyProtocol'}}
|
|
// expected-note@-1 {{generic type 'InnerClass' declared here}}
|
|
}
|
|
|
|
enum OuterEnum {
|
|
protocol C {} // expected-error{{protocol 'C' cannot be nested inside another declaration}}
|
|
// expected-note@-1{{'C' previously declared here}}
|
|
case C(C) // expected-error{{invalid redeclaration of 'C'}}
|
|
}
|
|
|
|
class OuterClass {
|
|
protocol InnerProtocol : OuterClass { }
|
|
// expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OuterClass'}}
|
|
// expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
|
|
}
|
|
|
|
class OtherGenericClass<T> {
|
|
protocol InnerProtocol : OtherGenericClass { }
|
|
// expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OtherGenericClass<T>'}}
|
|
// expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
|
|
}
|