mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
That is, if there's a problem with a witness, and the witness comes from a different extension from the conformance (or the original type, when the conformance is on an extension), put the main diagnostic on the conformance, with a note on the witness. This involves some shuffling and rephrasing of existing diagnostics too. There's a few reasons for this change: - More context. It may not be obvious why a declaration in file A.swift needs to be marked 'public' if you can't see the conformance in B.swift. - Better locations for imported declarations. If you're checking a conformance in a source file but the witness came from an imported module, it's better to put the diagnostic on the part you have control over. (This is especially true in Xcode, which can't display diagnostics on imported declarations in the source editor.) - Plays better with batch mode. Without this change, you can have diagnostics being reported in file A.swift that are tied to a conformance declared in file B.swift. Of course the contents of A.swift also affect the diagnostic, but compiling A.swift on its own wouldn't produce the diagnostic, and so putting it there is problematic. The change does in some cases make for a worse user experience, though; if you just want to apply the changes and move on, the main diagnostic isn't in the "right place". It's the note that has the info and possible fix-it. It's also a slightly more complicated implementation.
147 lines
5.1 KiB
Swift
147 lines
5.1 KiB
Swift
// RUN: %target-typecheck-verify-swift -enable-objc-interop
|
|
|
|
@objc class C1 { }
|
|
@objc class C2 { }
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Parameters of IUO type.
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol ParameterIUO1 {
|
|
@objc optional func f0(_ x: C1!)
|
|
}
|
|
|
|
@objc class ParameterIUO1a : ParameterIUO1 {
|
|
func f0(_ x: C1!) { } // okay: exact match
|
|
}
|
|
|
|
@objc class ParameterIUO1b : ParameterIUO1 {
|
|
func f0(_ x: C1) { } // okay: all is permitted with IUO requirements
|
|
}
|
|
|
|
@objc class ParameterIUO1c : ParameterIUO1 {
|
|
func f0(_ x: C1?) { } // okay: all is permitted with IUO requirements
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Parameters of optional type.
|
|
// ------------------------------------------------------------------------
|
|
|
|
@objc protocol ParameterOpt1 {
|
|
@objc optional func f0(_ x: C1?) // expected-note 2{{declared here}}
|
|
}
|
|
|
|
@objc class ParameterOpt1a : ParameterOpt1 {
|
|
func f0(_ x: C1?) { } // okay: exact match
|
|
}
|
|
|
|
@objc class ParameterOpt1b : ParameterOpt1 {
|
|
func f0(_ x: C1!) { } // expected-warning{{different optionality than expected}}{{18-19=?}}
|
|
}
|
|
|
|
@objc class ParameterOpt1c : ParameterOpt1 {
|
|
func f0(_ x: C1) { } // expected-error{{different optionality than required}}{{18-18=?}}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Parameters of non-optional type.
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol ParameterNonOpt1 {
|
|
@objc optional func f0(_ x: C1) // expected-note 3 {{declared here}}
|
|
}
|
|
|
|
@objc class ParameterNonOpt1a : ParameterNonOpt1 {
|
|
func f0(_ x: C1) { } // okay: exact match
|
|
}
|
|
|
|
@objc class ParameterNonOpt1b : ParameterNonOpt1 {
|
|
func f0(_ x: C1!) { } // expected-warning{{parameter of 'f0' has different optionality than expected by protocol 'ParameterNonOpt1'}}{{18-19=}}
|
|
}
|
|
|
|
@objc class ParameterNonOpt1c : ParameterNonOpt1 {
|
|
func f0(_ x: C1?) { } // expected-warning{{parameter of 'f0' has different optionality than expected by protocol 'ParameterNonOpt1'}}{{18-19=}}
|
|
}
|
|
|
|
@objc class ParameterNonOpt1d {
|
|
func f0(_ x: C1?) { } // expected-note {{'f0' declared here}} {{none}}
|
|
}
|
|
extension ParameterNonOpt1d : ParameterNonOpt1 {} // expected-warning{{parameter of 'f0' has different optionality than expected by protocol 'ParameterNonOpt1'}} {{none}}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Result of IUO type.
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol ResultIUO1 {
|
|
@objc optional func f0() -> C1!
|
|
}
|
|
|
|
@objc class ResultIUO1a : ResultIUO1 {
|
|
func f0() -> C1! { return nil } // okay: exact match
|
|
}
|
|
|
|
@objc class ResultIUO1b : ResultIUO1 {
|
|
func f0() -> C1 { } // okay: all is permitted with IUO requirements
|
|
}
|
|
|
|
@objc class ResultIUO1c : ResultIUO1 {
|
|
func f0() -> C1? { } // okay: all is permitted with IUO requirements
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Result of optional type.
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol ResultOpt1 {
|
|
@objc optional func f0() -> C1? // expected-note 2{{declared here}}
|
|
}
|
|
|
|
@objc class ResultOpt1a : ResultOpt1 {
|
|
func f0() -> C1? { return nil } // okay: exact match
|
|
}
|
|
|
|
@objc class ResultOpt1b : ResultOpt1 {
|
|
func f0() -> C1 { } // expected-warning{{different optionality}}{{18-18=?}}
|
|
}
|
|
|
|
@objc class ResultOpt1c : ResultOpt1 {
|
|
func f0() -> C1! { } // expected-warning{{different optionality}}{{18-19=?}}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Result of non-optional type.
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol ResultNonOpt1 {
|
|
@objc optional func f0() -> C1 // expected-note 2 {{declared here}}
|
|
}
|
|
|
|
@objc class ResultNonOpt1a : ResultNonOpt1 {
|
|
func f0() -> C1 { } // okay: exact match
|
|
}
|
|
|
|
@objc class ResultNonOpt1b : ResultNonOpt1 {
|
|
func f0() -> C1? { } // expected-error{{different optionality than required}}{{18-19=}}
|
|
}
|
|
|
|
@objc class ResultNonOpt1c : ResultNonOpt1 {
|
|
func f0() -> C1! { } // expected-warning{{different optionality}}{{18-19=}}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Multiple parameter mismatches
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol MultiParamsOpt1 {
|
|
@objc optional func f0(_ x: C1?, y: C1) // expected-note{{here}}
|
|
}
|
|
|
|
@objc class MultiParamsOpt1a : MultiParamsOpt1 {
|
|
func f0(_ x: C1!, y: C1!) { } // expected-warning{{parameters of 'f0(_:y:)' have different optionality than expected}}{{18-19=?}}{{26-27=}}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Parameter and result type mismatches
|
|
// ------------------------------------------------------------------------
|
|
@objc protocol ParamAndResult1 {
|
|
@objc optional func f0(_ x: C1?) -> C1 // expected-note{{here}}
|
|
}
|
|
|
|
@objc class ParamAndResult1a : ParamAndResult1 {
|
|
func f0(_ x: C1!) -> C1! { } // expected-warning{{result and parameters of 'f0' have different optionality than expected}}{{18-19=?}}{{26-27=}}
|
|
}
|