From 00a56fd43cbd04164349a98b605fbc5ce418e804 Mon Sep 17 00:00:00 2001 From: tarunon Date: Thu, 8 Mar 2018 03:24:19 +0900 Subject: [PATCH] [SR7111] allow nested optional overrides --- lib/AST/Type.cpp | 6 ++++-- test/decl/class/override.swift | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 5e5c65e1dfe4a..7630c435a16d1 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -2209,8 +2209,10 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode, if (t1 == t2) return true; // First try unwrapping optionals. - // Make sure we only unwrap at most one layer of optional. - if (insideOptional == OptionalUnwrapping::None) { + // Unwrap optional as much as possible. + if (insideOptional == OptionalUnwrapping::None || + insideOptional == OptionalUnwrapping::OptionalToOptional || + insideOptional == OptionalUnwrapping::ValueToOptional) { // Value-to-optional and optional-to-optional. if (auto obj2 = t2.getOptionalObjectType()) { // Optional-to-optional. diff --git a/test/decl/class/override.swift b/test/decl/class/override.swift index 5a8cb0f620c54..f0cf70295ad7d 100644 --- a/test/decl/class/override.swift +++ b/test/decl/class/override.swift @@ -18,11 +18,11 @@ class A { func ret_subclass_uoptional_rev() -> B { return B() } func ret_subclass_optional_uoptional() -> A? { return .none } func ret_subclass_optional_uoptional_rev() -> B! { return B() } - func ret_nonclass_nested_optional() -> Int?? { return .none } // expected-note{{potential overridden instance method 'ret_nonclass_nested_optional()'}} + func ret_nonclass_nested_optional() -> Int?? { return .none } func ret_nonclass_nested_optional_rev() -> Int { return 0 } - func ret_class_nested_optional() -> B?? { return .none } // expected-note{{potential overridden instance method 'ret_class_nested_optional()'}} + func ret_class_nested_optional() -> B?? { return .none } func ret_class_nested_optional_rev() -> A { return self } - func ret_subclass_nested_optional() -> A?? { return .none } // expected-note{{potential overridden instance method 'ret_subclass_nested_optional()'}} + func ret_subclass_nested_optional() -> A?? { return .none } func ret_subclass_nested_optional_rev() -> B { return B() } func param_sametype(_ x : Int) {} @@ -42,11 +42,11 @@ class A { func param_subclass_uoptional_rev(_ x : A!) {} func param_subclass_optional_uoptional(_ x : B!) {} func param_subclass_optional_uoptional_rev(_ x : A?) {} - func param_nonclass_nested_optional(_ x : Int) {} // expected-note{{potential overridden instance method 'param_nonclass_nested_optional'}} + func param_nonclass_nested_optional(_ x : Int) {} func param_nonclass_nested_optional_rev(_ x : Int??) {} - func param_class_nested_optional(_ x : B) {} // expected-note{{potential overridden instance method 'param_class_nested_optional'}} + func param_class_nested_optional(_ x : B) {} func param_class_nested_optional_rev(_ x : B??) {} - func param_subclass_nested_optional(_ x : B) {} // expected-note{{potential overridden instance method 'param_subclass_nested_optional'}} + func param_subclass_nested_optional(_ x : B) {} func param_subclass_nested_optional_rev(_ x : A??) {} } @@ -68,11 +68,11 @@ class B : A { func ret_subclass_uoptional_rev() -> A! { return self } override func ret_subclass_optional_uoptional() -> B! { return self } func ret_subclass_optional_uoptional_rev() -> A? { return self } - override func ret_nonclass_nested_optional() -> Int { return 0 } // expected-error{{method does not override any method from its superclass}} + override func ret_nonclass_nested_optional() -> Int { return 0 } func ret_nonclass_nested_optional_rev() -> Int? { return 0 } - override func ret_class_nested_optional() -> B { return self } // expected-error{{method does not override any method from its superclass}} + override func ret_class_nested_optional() -> B { return self } func ret_class_nested_optional_rev() -> A? { return self } - override func ret_subclass_nested_optional() -> B { return self } // expected-error{{method does not override any method from its superclass}} + override func ret_subclass_nested_optional() -> B { return self } func ret_subclass_nested_optional_rev() -> A? { return self } override func param_sametype(_ x : Int) {} @@ -92,11 +92,11 @@ class B : A { func param_subclass_uoptional_rev(_ x : B) {} override func param_subclass_optional_uoptional(_ x : A?) {} func param_subclass_optional_uoptional_rev(_ x : B!) {} - override func param_nonclass_nested_optional(_ x : Int??) {} // expected-error{{method does not override any method from its superclass}} + override func param_nonclass_nested_optional(_ x : Int??) {} func param_nonclass_nested_optional_rev(_ x : Int) {} - override func param_class_nested_optional(_ x : B??) {} // expected-error{{method does not override any method from its superclass}} + override func param_class_nested_optional(_ x : B??) {} func param_class_nested_optional_rev(_ x : B) {} - override func param_subclass_nested_optional(_ x : A??) {} // expected-error{{method does not override any method from its superclass}} + override func param_subclass_nested_optional(_ x : A??) {} func param_subclass_nested_optional_rev(_ x : B) {} }