mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Previously, validateDecl() would check if the declaration had an interface type and use that as an indication not to proceed. However for functions we can only set an interface type after checking the generic signature, so a recursive call to validateDecl() on a function would "steal" the outer call and complete validation. For generic types, this meant we could have a declaration with a valid interface type but no generic signature. Both cases were problematic, so narrow workarounds were put in place with additional new flags. This made the code harder to reason about. This patch consolidates the flags and establishes new invariants: - If validateDecl() returns and the declaration has no interface type and the isBeingValidated() flag is not set, it means one of the parent contexts is being validated by an outer recursive call. - If validateDecl() returns and the declaration has the isBeingValidated() flag set, it may or may not have an interface type. In this case, the declaration itself is being validated by an outer recursive call. - If validateDecl() returns and the declaration has an interface type and the isBeingValidated() flag is not set, it means the declaration and all of its parent contexts are fully validated and ready for use. In general, we still want name lookup to find things that have an interface type but are not in a valid generic context, so for this reason nominal types and associated types get an interface type as early as possible. Most other code only wants to see fully formed decls, so a new hasValidSignature() method returns true iff the interface type is set and the isBeingValidated() flag is not set. For example, while resolving a type, we can resolve an unqualified reference to a nominal type without a valid signature. However, when applying generic parameters, the hasValidSignature() flag is used to ensure we error out instead of crashing if the generic signature has not yet been formed.
82 lines
2.9 KiB
Swift
82 lines
2.9 KiB
Swift
// RUN: %target-typecheck-verify-swift
|
|
|
|
class HasFunc {
|
|
func HasFunc(_: HasFunc) {
|
|
}
|
|
func HasFunc() -> HasFunc {
|
|
return HasFunc()
|
|
}
|
|
func SomethingElse(_: SomethingElse) { // expected-error {{use of undeclared type 'SomethingElse'}}
|
|
return nil
|
|
}
|
|
func SomethingElse() -> SomethingElse? { // expected-error {{use of undeclared type 'SomethingElse'}}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
class HasGenericFunc {
|
|
func HasGenericFunc<HasGenericFunc : HasGenericFunc>(x: HasGenericFunc) -> HasGenericFunc { // expected-error {{inheritance from non-protocol, non-class type 'HasGenericFunc'}}
|
|
return x
|
|
}
|
|
func SomethingElse<SomethingElse : SomethingElse>(_: SomethingElse) -> SomethingElse? { // expected-error {{inheritance from non-protocol, non-class type 'SomethingElse'}}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
class HasProp {
|
|
var HasProp: HasProp {
|
|
return HasProp() // expected-error {{cannot call value of non-function type 'HasProp'}}{{19-21=}}
|
|
}
|
|
var SomethingElse: SomethingElse? { // expected-error 2 {{use of undeclared type 'SomethingElse'}}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
protocol SomeProtocol {}
|
|
protocol ReferenceSomeProtocol {
|
|
var SomeProtocol: SomeProtocol { get }
|
|
}
|
|
|
|
func TopLevelFunc(x: TopLevelFunc) -> TopLevelFunc { return x } // expected-error 2 {{use of undeclared type 'TopLevelFunc'}}'
|
|
func TopLevelGenericFunc<TopLevelGenericFunc : TopLevelGenericFunc>(x: TopLevelGenericFunc) -> TopLevelGenericFunc { return x } // expected-error {{inheritance from non-protocol, non-class type 'TopLevelGenericFunc'}}
|
|
func TopLevelGenericFunc2<T : TopLevelGenericFunc2>(x: T) -> T { return x} // expected-error {{use of undeclared type 'TopLevelGenericFunc2'}}
|
|
var TopLevelVar: TopLevelVar? { return nil } // expected-error 2 {{use of undeclared type 'TopLevelVar'}}
|
|
|
|
|
|
protocol AProtocol {
|
|
associatedtype e : e
|
|
// expected-error@-1 {{type 'e' references itself}}
|
|
// expected-note@-2 {{type declared here}}
|
|
}
|
|
|
|
|
|
|
|
// <rdar://problem/15604574> Protocol conformance checking needs to be delayed
|
|
protocol P15604574 {
|
|
associatedtype FooResult
|
|
func foo() -> FooResult
|
|
}
|
|
|
|
class AcceptsP<T : P15604574> { }
|
|
|
|
class X {
|
|
func foo() -> AcceptsP<X> { } // expected-error {{type 'X' does not conform to protocol 'P15604574'}}
|
|
}
|
|
|
|
// <rdar://problem/17144076> recursive typealias causes a segfault in the type checker
|
|
struct SomeStruct<A> {
|
|
typealias A = A // expected-error {{type alias 'A' references itself}}
|
|
// expected-note@-1 {{type declared here}}
|
|
}
|
|
|
|
// <rdar://problem/27680407> Infinite recursion when using fully-qualified associatedtype name that has not been defined with typealias
|
|
protocol rdar27680407Proto {
|
|
associatedtype T // expected-note {{protocol requires nested type 'T'; do you want to add it?}}
|
|
|
|
init(value: T)
|
|
}
|
|
|
|
struct rdar27680407Struct : rdar27680407Proto { // expected-error {{type 'rdar27680407Struct' does not conform to protocol 'rdar27680407Proto'}}
|
|
init(value: rdar27680407Struct.T) {}
|
|
}
|