mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Sema] Fix issue 65330 Unhelpful error when missing contextually required as bridging conversion to AnyObject in structural position. Minor formatting change in previous test case
This commit is contained in:
@@ -2577,7 +2577,6 @@ bool ContextualFailure::diagnoseAsError() {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case ConstraintLocator::UnresolvedMemberChainResult: {
|
||||
auto &solution = getSolution();
|
||||
|
||||
@@ -3528,6 +3527,66 @@ ContextualFailure::getDiagnosticFor(ContextualTypePurpose context,
|
||||
return None;
|
||||
}
|
||||
|
||||
bool NonClassTypeToAnyObjectConversionFailure::diagnoseAsError() {
|
||||
auto locator = getLocator();
|
||||
if (locator->isForContextualType()) {
|
||||
return ContextualFailure::diagnoseAsError();
|
||||
}
|
||||
|
||||
auto fromType = getFromType();
|
||||
auto toType = getToType();
|
||||
assert(fromType);
|
||||
assert(toType);
|
||||
if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
|
||||
ArgumentMismatchFailure failure(getSolution(), fromType, toType, locator);
|
||||
return failure.diagnoseAsError();
|
||||
}
|
||||
|
||||
Optional<Diag<Type, Type>> diagnostic;
|
||||
|
||||
bool forProtocol = toType->isConstraintType();
|
||||
auto rawAnchor = getRawAnchor();
|
||||
|
||||
if (isExpr<ArrayExpr>(rawAnchor)) {
|
||||
diagnostic = forProtocol ? diag::cannot_convert_array_element_protocol
|
||||
: diag::cannot_convert_array_element;
|
||||
} else if (isExpr<DictionaryExpr>(rawAnchor)) {
|
||||
auto lastElem = locator->getLastElementAs<LocatorPathElt::TupleElement>();
|
||||
if (lastElem && lastElem->getIndex() == 0) {
|
||||
diagnostic = forProtocol ? diag::cannot_convert_dict_key_protocol
|
||||
: diag::cannot_convert_dict_key;
|
||||
} else {
|
||||
diagnostic = forProtocol ? diag::cannot_convert_dict_value_protocol
|
||||
: diag::cannot_convert_dict_value;
|
||||
}
|
||||
} else if (toType->isAnyObject()) {
|
||||
diagnostic = diag::cannot_convert_initializer_value_anyobject;
|
||||
}
|
||||
|
||||
if (diagnostic.hasValue()) {
|
||||
emitDiagnostic(*diagnostic, fromType, toType);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NonClassTypeToAnyObjectConversionFailure::diagnoseAsNote() {
|
||||
auto *locator = getLocator();
|
||||
|
||||
if (locator->isForContextualType()) {
|
||||
return ContextualFailure::diagnoseAsNote();
|
||||
}
|
||||
|
||||
if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
|
||||
ArgumentMismatchFailure failure(getSolution(), getFromType(), getToType(),
|
||||
getLocator());
|
||||
return failure.diagnoseAsNote();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TupleContextualFailure::diagnoseAsError() {
|
||||
Diag<Type, Type> diagnostic;
|
||||
auto purpose = getContextualTypePurpose();
|
||||
|
||||
@@ -804,6 +804,19 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class NonClassTypeToAnyObjectConversionFailure final
|
||||
: public ContextualFailure {
|
||||
|
||||
public:
|
||||
NonClassTypeToAnyObjectConversionFailure(const Solution &solution, Type lhs,
|
||||
Type rhs, ConstraintLocator *locator)
|
||||
: ContextualFailure(solution, lhs, rhs, locator, FixBehavior::Error) {}
|
||||
|
||||
bool diagnoseAsError() override;
|
||||
|
||||
bool diagnoseAsNote() override;
|
||||
};
|
||||
|
||||
/// Diagnose errors related to using an array literal where a
|
||||
/// dictionary is expected.
|
||||
class ArrayLiteralToDictionaryConversionFailure final : public ContextualFailure {
|
||||
|
||||
@@ -1934,18 +1934,10 @@ bool AllowNonClassTypeToConvertToAnyObject::diagnose(const Solution &solution,
|
||||
bool asNote) const {
|
||||
auto *locator = getLocator();
|
||||
|
||||
if (locator->isForContextualType()) {
|
||||
ContextualFailure failure(solution, getFromType(), getToType(), locator);
|
||||
return failure.diagnose(asNote);
|
||||
}
|
||||
NonClassTypeToAnyObjectConversionFailure failure(solution, getFromType(),
|
||||
getToType(), locator);
|
||||
|
||||
if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
|
||||
ArgumentMismatchFailure failure(solution, getFromType(), getToType(),
|
||||
locator);
|
||||
return failure.diagnose(asNote);
|
||||
}
|
||||
|
||||
return false;
|
||||
return failure.diagnose(asNote);
|
||||
}
|
||||
|
||||
AllowNonClassTypeToConvertToAnyObject *
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
let _: AnyObject = "a" // expected-error {{value of type 'String' expected to be instance of class or class-constrained type}}
|
||||
|
||||
let _: [AnyObject] = ["a"] // expected-error {{cannot convert value of type 'String' to expected element type 'AnyObject'}}
|
||||
let _: [String: AnyObject] = ["a": "a"] // expected-error {{cannot convert value of type 'String' to expected dictionary value type 'AnyObject'}}
|
||||
let _: [AnyObject: String] = ["a": "a"] // expected-error {{type 'AnyObject' does not conform to protocol 'Hashable'}}
|
||||
// expected-error@-1 {{cannot convert value of type 'String' to expected dictionary key type 'AnyObject'}}
|
||||
let _: (AnyObject, Void) = ("a", ()) // expected-error {{value of type 'String' expected to be instance of class or class-constrained type}}
|
||||
@@ -1,16 +1,13 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol P {
|
||||
subscript<Value>(x: Value) -> Int // expected-note {{protocol requires subscript with type '<Value> (Value) -> Int'; do you want to add a stub?}}
|
||||
{
|
||||
subscript<Value>(x: Value) -> Int { // expected-note {{protocol requires subscript with type '<Value> (Value) -> Int'; do you want to add a stub?}}
|
||||
get
|
||||
}
|
||||
}
|
||||
|
||||
struct S: P // expected-error {{type 'S' does not conform to protocol 'P'}}
|
||||
{
|
||||
subscript<Value>(x: Int) -> Value // expected-note {{candidate has non-matching type '<Value> (Int) -> Value'}}
|
||||
{
|
||||
struct S : P { // expected-error {{type 'S' does not conform to protocol 'P'}}
|
||||
subscript<Value>(x: Int) -> Value { // expected-note {{candidate has non-matching type '<Value> (Int) -> Value'}}
|
||||
} // expected-error {{missing return in subscript expected to return 'Value'}}
|
||||
}
|
||||
|
||||
@@ -21,8 +18,7 @@ struct S2: P {
|
||||
}
|
||||
|
||||
protocol P2 {
|
||||
subscript(x: Int) -> Int
|
||||
{
|
||||
subscript(x: Int) -> Int {
|
||||
get
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user