Files
swift-mirror/test/decl/nested/protocol.swift
Jordan Rose 63bc717963 Error when one associated type is constrained to another. (#10053)
(...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.
2017-06-01 19:45:34 -07:00

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}}
}