mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Remove diag::type_of_expression_is_ambiguous
This is a diagnostic that is only really emitted as a fallback when the constraint system isn't able to better diagnose the expression. It's not particulary helpful for the user, and can be often be misleading since the underlying issue might not actually be an ambiguity, and the user may well already have a type annotation. Let's instead just emit the fallback diagnostic that we emit in all other cases, asking the user to file a bug.
This commit is contained in:
@@ -4749,15 +4749,10 @@ ERROR(could_not_infer_pack_element,none,
|
||||
NOTE(note_in_opening_pack_element,none,
|
||||
"in inferring pack element #%0 of '%1'", (unsigned,StringRef))
|
||||
|
||||
|
||||
ERROR(type_of_expression_is_ambiguous,none,
|
||||
"type of expression is ambiguous without a type annotation", ())
|
||||
|
||||
ERROR(failed_to_produce_diagnostic,none,
|
||||
"failed to produce diagnostic for expression; "
|
||||
SWIFT_BUG_REPORT_MESSAGE, ())
|
||||
|
||||
|
||||
ERROR(missing_protocol,none,
|
||||
"missing protocol %0", (Identifier))
|
||||
ERROR(nil_literal_broken_proto,none,
|
||||
|
||||
@@ -4768,6 +4768,21 @@ void ConstraintSystem::diagnoseFailureFor(SyntacticElementTarget target) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto *wrappedVar = target.getAsUninitializedWrappedVar()) {
|
||||
auto *outerWrapper = wrappedVar->getOutermostAttachedPropertyWrapper();
|
||||
Type propertyType = wrappedVar->getInterfaceType();
|
||||
Type wrapperType = outerWrapper->getType();
|
||||
|
||||
// Emit the property wrapper fallback diagnostic
|
||||
wrappedVar->diagnose(diag::property_wrapper_incompatible_property,
|
||||
propertyType, wrapperType);
|
||||
if (auto nominal = wrapperType->getAnyNominal()) {
|
||||
nominal->diagnose(diag::property_wrapper_declared_here,
|
||||
nominal->getName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto expr = target.getAsExpr()) {
|
||||
if (auto *assignment = dyn_cast<AssignExpr>(expr)) {
|
||||
if (isa<DiscardAssignmentExpr>(assignment->getDest()))
|
||||
@@ -4785,33 +4800,12 @@ void ConstraintSystem::diagnoseFailureFor(SyntacticElementTarget target) {
|
||||
.highlight(closure->getSourceRange());
|
||||
return;
|
||||
}
|
||||
|
||||
// If no one could find a problem with this expression or constraint system,
|
||||
// then it must be well-formed... but is ambiguous. Handle this by
|
||||
// diagnostic various cases that come up.
|
||||
DE.diagnose(expr->getLoc(), diag::type_of_expression_is_ambiguous)
|
||||
.highlight(expr->getSourceRange());
|
||||
} else if (auto *wrappedVar = target.getAsUninitializedWrappedVar()) {
|
||||
auto *outerWrapper = wrappedVar->getOutermostAttachedPropertyWrapper();
|
||||
Type propertyType = wrappedVar->getInterfaceType();
|
||||
Type wrapperType = outerWrapper->getType();
|
||||
|
||||
// Emit the property wrapper fallback diagnostic
|
||||
wrappedVar->diagnose(diag::property_wrapper_incompatible_property,
|
||||
propertyType, wrapperType);
|
||||
if (auto nominal = wrapperType->getAnyNominal()) {
|
||||
nominal->diagnose(diag::property_wrapper_declared_here,
|
||||
nominal->getName());
|
||||
}
|
||||
} else if (target.getAsUninitializedVar()) {
|
||||
DE.diagnose(target.getLoc(), diag::failed_to_produce_diagnostic);
|
||||
} else if (target.isForEachPreamble()) {
|
||||
DE.diagnose(target.getLoc(), diag::failed_to_produce_diagnostic);
|
||||
} else {
|
||||
// Emit a poor fallback message.
|
||||
DE.diagnose(target.getAsFunction()->getLoc(),
|
||||
diag::failed_to_produce_diagnostic);
|
||||
}
|
||||
|
||||
// Emit a poor fallback message.
|
||||
auto diag = DE.diagnose(target.getLoc(), diag::failed_to_produce_diagnostic);
|
||||
if (auto *expr = target.getAsExpr())
|
||||
diag.highlight(expr->getSourceRange());
|
||||
}
|
||||
|
||||
bool ConstraintSystem::isDeclUnavailable(const Decl *D,
|
||||
|
||||
@@ -224,7 +224,7 @@ do {
|
||||
|
||||
// TODO(rdar://125948508): This shouldn't be ambiguous (@Sendable version should be preferred)
|
||||
func test() -> KeyPath<String, Int> {
|
||||
true ? kp() : kp() // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
true ? kp() : kp() // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
func forward<T>(_ v: T) -> T { v }
|
||||
@@ -249,7 +249,7 @@ do {
|
||||
|
||||
// TODO(rdar://125948508): This shouldn't be ambiguous (@Sendable version should be preferred)
|
||||
func fnRet(cond: Bool) -> () -> Void {
|
||||
cond ? Test.fn : Test.otherFn // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
cond ? Test.fn : Test.otherFn // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
func forward<T>(_: T) -> T {
|
||||
|
||||
@@ -290,7 +290,7 @@ func test_invalid_argument_to_keypath_subscript() {
|
||||
// The diagnostic should point out that `ambiguous` is indeed ambiguous and that `5` is not a valid argument
|
||||
// for a key path subscript.
|
||||
ambiguous {
|
||||
// expected-error@-1 {{type of expression is ambiguous without a type annotation}}
|
||||
// expected-error@-1 {{failed to produce diagnostic for expression}}
|
||||
$0[keyPath: 5]
|
||||
}
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ func rdar60727310() {
|
||||
// FIXME: Bad diagnostic.
|
||||
func f_54877(_ e: Error) {
|
||||
func foo<T>(_ a: T, _ op: ((T, T) -> Bool)) {}
|
||||
foo(e, ==) // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
foo(e, ==) // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
// rdar://problem/62054241 - Swift compiler crashes when passing < as the sort function in sorted(by:) and the type of the array is not comparable
|
||||
|
||||
@@ -8,7 +8,7 @@ protocol P<A> {
|
||||
|
||||
func f1(x: any P) -> any P<Int> {
|
||||
// FIXME: Bad diagnostic
|
||||
return x // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
return x // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
func f2(x: any P<Int>) -> any P {
|
||||
@@ -52,4 +52,4 @@ func h3(x: (any P<Int>)?) -> (any P<String>)? {
|
||||
|
||||
func generic1<T>(x: any P<T>) -> T {
|
||||
return x.f()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,5 +29,5 @@ extension S4 where T == (outer: Int, y: Int) {
|
||||
|
||||
public func rdar85263844_2(_ x: [Int]) -> S4<(outer: Int, y: Int)> {
|
||||
// FIXME: Bad error message.
|
||||
S4(x.map { (inner: $0, y: $0) }) // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
S4(x.map { (inner: $0, y: $0) }) // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ takesAnyObject()
|
||||
takesAnyObject(C(), C(), C())
|
||||
|
||||
// FIXME: Bad diagnostic
|
||||
takesAnyObject(C(), S(), C()) // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
takesAnyObject(C(), S(), C()) // expected-error {{failed to produce diagnostic for expression}}
|
||||
|
||||
// Same-type requirements
|
||||
|
||||
|
||||
@@ -22,5 +22,5 @@ import Test;
|
||||
public func test(_ _: AnyObject) {}
|
||||
|
||||
// TODO: make this a better error.
|
||||
test(Empty.create()) // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
test(Empty.create()) // expected-error {{failed to produce diagnostic for expression}}
|
||||
test([Empty.create()][0]) // expected-error {{argument type 'Any' expected to be an instance of a class or class-constrained type}}
|
||||
|
||||
@@ -21,4 +21,4 @@ func takesDeepNestedStruct(_ s: MyNS.MyDeepNS.DeepNestedStruct) {
|
||||
}
|
||||
|
||||
MyNS.method() // expected-error {{type 'MyNS' has no member 'method'}}
|
||||
MyNS.nestedMethod() // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
MyNS.nestedMethod() // expected-error {{failed to produce diagnostic for expression}}
|
||||
|
||||
@@ -22,5 +22,5 @@ import namespaces;
|
||||
|
||||
// Swift's typechecker currently doesn't allow calling a function from inline namespace when it's referenced through the parent namespace.
|
||||
func test() {
|
||||
Parent.functionInInlineChild() // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
Parent.functionInInlineChild() // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ struct File: ~Copyable {
|
||||
discard (self) // expected-error {{cannot convert value of type 'File' to expected argument type 'Int'}}
|
||||
|
||||
// FIXME: we should get an error about it being illegal to discard in a closure.
|
||||
let _ = { // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
let _ = { // expected-error {{failed to produce diagnostic for expression}}
|
||||
discard self
|
||||
return 0
|
||||
}()
|
||||
|
||||
@@ -4,6 +4,6 @@ typealias Alias<T> = Int
|
||||
|
||||
func invalidSpecializeExpr(_ x: Alias<Int>.Type) {
|
||||
let y = x<Int>.self
|
||||
// expected-error@-1 {{type of expression is ambiguous without a type annotation}}
|
||||
// expected-error@-1 {{failed to produce diagnostic for expression}}
|
||||
// FIXME: Bad diagnostic
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ do {
|
||||
// FIXME: Should GenericSignature::getConcreteType return the null type instead
|
||||
// of the error type here for Self.A, despite the broken conformance?
|
||||
let exist: any CompositionBrokenClassConformance_b & BadConformanceClass
|
||||
exist.method(false) // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
exist.method(false) // expected-error {{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
// https://github.com/swiftlang/swift/issues/65533
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
// RUN: %target-swift-frontend -typecheck %s -verify -verify-ignore-unknown
|
||||
|
||||
// FIXME: This should produce a diagnostic with a proper
|
||||
// source location. Right now, we just get three useless errors:
|
||||
// source location. Right now, we just get these errors:
|
||||
|
||||
// <unknown>:0: error: type of expression is ambiguous without a type annotation
|
||||
// <unknown>:0: error: type of expression is ambiguous without a type annotation
|
||||
// <unknown>:0: error: type of expression is ambiguous without a type annotation
|
||||
// <unknown>:0: error: cannot infer key path type from context; consider explicitly specifying a root type
|
||||
// <unknown>:0: error: cannot infer key path type from context; consider explicitly specifying a root type
|
||||
// <unknown>:0: error: cannot infer key path type from context; consider explicitly specifying a root type
|
||||
// <unknown>:0: error: cannot infer key path type from context; consider explicitly specifying a root type
|
||||
// <unknown>:0: error: cannot infer key path type from context; consider explicitly specifying a root type
|
||||
// <unknown>:0: error: cannot infer key path type from context; consider explicitly specifying a root type
|
||||
|
||||
// The actual problem is the type of the subscript declaration is wrong.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class Aaron {
|
||||
func foo() {
|
||||
// Make sure we recover and assume 'self.init'.
|
||||
// expected-error@+2 {{initializer expression requires explicit access; did you mean to prepend it with 'self.'?}} {{11-11=self.}}
|
||||
// expected-error@+1 {{type of expression is ambiguous without a type annotation}}
|
||||
// expected-error@+1 {{failed to produce diagnostic for expression}}
|
||||
_ = init
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ class Theodosia: Aaron {
|
||||
|
||||
// Make sure we recover and assume 'self.init'.
|
||||
// expected-error@+2 {{initializer expression requires explicit access; did you mean to prepend it with 'self.'?}} {{22-22=self.}}
|
||||
// expected-error@+1 {{type of expression is ambiguous without a type annotation}}
|
||||
// expected-error@+1 {{failed to produce diagnostic for expression}}
|
||||
func foo() { _ = init }
|
||||
}
|
||||
|
||||
|
||||
@@ -510,7 +510,7 @@ do {
|
||||
|
||||
// FIXME: The type error is likely due to not solving the conjunction before attempting default type var bindings.
|
||||
let _ = (if .random() { Int?.none } else { 1 as Int? })?.bitWidth
|
||||
// expected-error@-1 {{type of expression is ambiguous without a type annotation}}
|
||||
// expected-error@-1 {{failed to produce diagnostic for expression}}
|
||||
// expected-error@-2 {{'if' may only be used as expression in return, throw, or as the source of an assignment}}
|
||||
}
|
||||
do {
|
||||
|
||||
@@ -865,7 +865,7 @@ func test_keypath_with_method_refs() {
|
||||
let _: KeyPath<S, (Int, Int) -> Int> = \.add()
|
||||
// expected-error@-1 {{cannot assign value of type 'KeyPath<S, Int>' to type 'KeyPath<S, (Int, Int) -> Int>'}}
|
||||
// expected-note@-2 {{arguments to generic parameter 'Value' ('Int' and '(Int, Int) -> Int') are expected to be equal}}
|
||||
let _: KeyPath<S, Int> = \.add() // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
let _: KeyPath<S, Int> = \.add() // expected-error {{failed to produce diagnostic for expression}}
|
||||
let _: KeyPath<S, (Int) -> Int> = \.add(this:)
|
||||
let _: KeyPath<S, Int> = \.add(that: 1)
|
||||
let _: KeyPath<S, (Int) -> Int> = \.subtract // expected-error {{static member 'subtract' cannot be used on instance of type 'S'}}
|
||||
@@ -924,10 +924,10 @@ func test_keypath_with_method_refs() {
|
||||
subscript(index: Int) -> Int { return index }
|
||||
}
|
||||
|
||||
let _: KeyPath<A, Int> = \.foo.bar // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
let _: KeyPath<A, Int> = \.foo.bar // expected-error {{failed to produce diagnostic for expression}}
|
||||
let _: KeyPath<A, Int> = \.faz.bar // expected-error {{static member 'faz()' cannot be used on instance of type 'A'}}
|
||||
let _ = \A.foo.bar // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
let _ = \A.Type.faz.bar // expected-error {{type of expression is ambiguous without a type annotation}}
|
||||
let _ = \A.foo.bar // expected-error {{failed to produce diagnostic for expression}}
|
||||
let _ = \A.Type.faz.bar // expected-error {{failed to produce diagnostic for expression}}
|
||||
let _: KeyPath<A, Int> = \.foo().bar
|
||||
let _: KeyPath<A.Type, Int> = \.faz().bar
|
||||
let _ = \A.foo().bar
|
||||
|
||||
@@ -670,7 +670,7 @@ do {
|
||||
|
||||
// FIXME: The type error is likely due to not solving the conjunction before attempting default type var bindings.
|
||||
let _ = (switch Bool.random() { case true: Int?.none case false: 1 })?.bitWidth
|
||||
// expected-error@-1 {{type of expression is ambiguous without a type annotation}}
|
||||
// expected-error@-1 {{failed to produce diagnostic for expression}}
|
||||
// expected-error@-2 {{'switch' may only be used as expression in return, throw, or as the source of an assignment}}
|
||||
}
|
||||
do {
|
||||
|
||||
@@ -86,5 +86,5 @@ func testPrimaries(
|
||||
takePrimaryCollections(setOfStrings, setOfInts)
|
||||
takePrimaryCollections(setOfStrings, arrayOfInts)
|
||||
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfInts)
|
||||
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without a type annotation}}
|
||||
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func testPrimaries(
|
||||
takePrimaryCollections(setOfStrings, setOfInts)
|
||||
takePrimaryCollections(setOfStrings, arrayOfInts)
|
||||
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfInts)
|
||||
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without a type annotation}}
|
||||
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{failed to produce diagnostic for expression}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user