-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Diagnostics] Generalize the "protocol type cannot conform" error to work for all types that cannot conform to protocols. #27176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
work for all types that cannot conform to protocols.
non-nominal types.
@swift-ci please smoke test |
validation-test/compiler_crashers_2_fixed/0196-rdar48937223.swift
Outdated
Show resolved
Hide resolved
I like the attempt to improve the diagnostic, but I’m not sure the revised wording is ideal: “Argument type” is helpful here because it helps the reader figure out where the error specifically is that we’re talking about. It may not always be obvious that the type being referenced is that of the argument used, since the argument won’t always be a tuple literal. Consider a use site By contrast, consider the revised wording “tuple type ‘(Int, String)’”: it is clear to anyone with a basic knowledge of Swift that “(Int, String)” is a tuple type, so that wording says the same thing twice. Meanwhile, it is true that the tuple type “does not” conform to the protocol “P”, and it is equally true that it “cannot.” The original diagnostic is phrased in terms of the specifics of why there is an error: the argument to this specific function must be of a type that conforms to “P”—and this in turn implies the only way to call this function correctly: by supplying an argument of a type that does conform to ‘P’. It also implies a currently impossible fix when the argument is a tuple: conforming the type of the argument being used to the protocol. This is what we need to clarify. Put another way, there are three pieces of information that need to be conveyed here to the user:
The current diagnostic only accomplishes (1) and (2). The proposed diagnostic here does not accomplish (1) because it does not phrase itself in terms of the specific argument. In fact, not only does it remove the word “argument,” it also phrases the error as a general rule about the language (“cannot”). It is a legitimate technique to teach users in error messages about what does or does not work in the language. But in this case it is phrased as a general rule with an oddly ambiguous specificity: now, the user is being taught that this specific type cannot (as a rule) conform to protocol “P”. At least two implied fixes that a user might take away are false: another tuple type cannot conform to “P” any more than this one can, and this tuple type cannot conform to any other protocol any more than to “P”. Therefore, the proposed error message here correctly clarifies what it’s trying to say by then restating the general rule in a more accurate way. But then it does so by affirmatively mentioning structs, enums, and classes, none of which are relevant to this error in this place. The end result is that a general rule is stated twice, accomplishing points (2) and (3) above more than once, while abandoning point (1). One wording that might work to teach users all three points is: “Argument type ‘(Int, String)’ does not conform to expected protocol ‘P’; tuple types cannot conform to protocols.” “Argument type ‘P’ does not conform to expected protocol ‘P’; protocols used as types cannot conform to protocols.” |
@xwu Thank you for such a thoughtful comment! I agree that it would be best to get an additional variant of this diagnostic which is tailored for arguments as you suggest. That would actually be as easy as adjusting existing |
@xwu again, thank you for the feedback! I agree that there is a lot of useful information that should be shown to the user, and this is where Swift's one-line diagnostic messages really fall short. FWIW, this is already what we show for existential types (which is arguably the most common form of this error), so we are already missing a lot of information in that case, and I'm attempting to remedy this by adding notes to this diagnostic. In the most recent version of Xcode, the error message for the example in the description actually says As I mentioned, I'm currently adding notes to this diagnostic so that the user does see more of this information (and I'm removing the redundancy of |
How about "type '(Int, String)' cannot satisfy expected protocol constraint because it is not a struct, enum, or class"? Again, I think for some users it can be misleading to say that it "cannot conform to 'P'", since |
to the declaration that requires protocol conformance.
type_cannot_conform diagnostic message.
cc7e95c
to
7687293
Compare
error message and note.
comes from an argument, use the argument expression as the anchor for `diagnoseTypeCannotConform`.
@swift-ci please smoke test |
Add a tailored diagnostic for missing conformance failures for (all) types that cannot conform to protocols. Example:
Previously, we diagnosed
argument type '(Int, String)' does not conform to expected type 'P'
. Now, we diagnosetype '(Int, String)' cannot conform to 'P'; only struct/enum/class types can conform to protocols
. Additionally, this change adds notes pointing to the requirement declaration, which we previously didn't show for existential types.rdar://problem/44204160