Introduce #[diagnostic::on_type_error(message)]#155200
Conversation
|
Some changes occurred in compiler/rustc_passes/src/check_attr.rs cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_attr_parsing cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_hir/src/attrs |
|
r? @davidtwco rustbot has assigned @davidtwco. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
r? estebank |
|
Before you sink more time and effort into this you should explain what you want One expectation I have is that it can specialize for different types. For example if you put this attribute on struct A but the typeerror finds a B or C instead you'll want to emit different messages for them, similar to how the filtering in I'm not convinced this attribute can be implemented in a satisfying way at this time. I'm open to being convinced otherwise though, and am happy to hear your thoughts. |
|
@mejrs two things: I agree that we want filtering in the same way as #[diagnostic::on_type_error(
note = "text",
)]
struct S<T>(T);with an eye for something along the lines of #[diagnostic::on_type_error(
on(expected="Self", found="crate::K", T = "i32", note = "a"),
on(expected="crate::K", found="Self", note = "b"),
note = "c",
)]
struct S<T>(T);some time later. I believe that having the minimal functionality at least lets crate authors include the "filtering information" in the text itself ("if this is the found type, then..." or "if type parameter T is blah, ..."), and that there are already several cases in the std of unconditional addition of notes during error reporting for given types, so I think the minimal functionality is already adding value. For the filtering I would like to share the same parser between on_type_error and on_unimplemented, as it is effectively the same functionality. |
|
Did you two have a discussion about this beforehand? I'd like to read it.
I presume you are talking about this? rust/compiler/rustc_hir_typeck/src/method/suggest.rs Lines 3156 to 3345 in e8e4541 The bit about unwrapping Option/Result is actually really impactful for learners and the way you propose the attribute it should be able to do that sort of thing (minus the inline code suggestions, obviously). So 💯 from me. Let's go for a minimal version for now, like estebank said: #[diagnostic::on_type_error(
note = "text",
)]
struct S<T>(T);I'm a bit worried about this thing being too powerful and showing up in places where authors didn't quite expect or intend. There are after all quite a few ways and places to get type errors. I think the following semantics would be reasonably useful but also restrictive enough to not spook me or the lang people.
Then in the future, when we evolve the attribute forwards, we can specify something like "if you dont supply any filter then this wrapper kind of thing is all it can do". |
There was a discussion initally, it was through video meet though, but, nothing much more than whatever is here actually.
Agreed. |
c6cbaa7 to
5b090d2
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
6366fc0 to
924b894
Compare
This comment has been minimized.
This comment has been minimized.
924b894 to
2392d19
Compare
This comment has been minimized.
This comment has been minimized.
2392d19 to
54106f8
Compare
This comment has been minimized.
This comment has been minimized.
54106f8 to
b5b3b9e
Compare
There was a problem hiding this comment.
General feedback regarding the approach:
- Please do not use the generics machinery for
FoundandExpected. Take a look at how rustc_on_unimplemented'sThisworks; it can be parsed similarly (grep forsym::This), and you can supply it by making new field(s) in theFormatArgsstruct. - I'm on the fence on allowing
{Self}. It feels like one of those things where you think you know what it does but you might be wrong. That's what I like aboutFoundandExpectedas well; it forces you to consider what you actually want. If it's useful we can also enableThisto refer unambiguously to the annotated item, like for rustc_on_unimplemented. Thoughts? - In your tests you have a lot of strings like
note = "expected {Expected}, found {Found}", but at a glance it's really hard to tell if this is emitted by the compiler somewhere or if it's from this attribute. Please change these to something that unambiguously looks "testy". - We talked about implementing this for method calls as well. It's up to you if you implement that here (can be a follow up PR), but either way please add some tests now to document the current behavior.
- More testing in general:
-
- cross crate use
-
- lifetime and const generics.
-
- check that Expected and Found is rejected for other diagnostic attributes
-
- duplicate uses of the attribute on the same item (these should coalesce).
So far I haven't looked too deep at how this hooks into the existing diagnostics machinery as I'm not familiar with it. That's more @estebank's area of expertise anyway. Maybe I'll have more review about that later.
|
Reminder, once the PR becomes ready for a review, use |
Maybe we should just disallow
Noted.
Noted.
Noted. Thanks for the review. |
|
I didn't notice until now, but not all your tests have explicit |
This comment has been minimized.
This comment has been minimized.
|
@estebank, @weiznich and I discussed this at the All Hands. We decided that we'd like to go ahead with @estebank's proposed semantics, so the diagnostic is displayed "both ways". Our general thoughts are along these lines:
|
b5b3b9e to
0dbe989
Compare
|
Some changes occurred to diagnostic attributes. cc @mejrs |
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
49e9fd5 to
e26cc59
Compare
There was a problem hiding this comment.
Thanks for getting back to this. I'm quite looking forward to it.
I have some comments on the attribute part of this. I've asked @estebank to do a review of how it hooks into the error reporting, so he should get back to you for the rest.
| (Mode::DiagnosticOnTypeError, sym::message) | ||
| | (Mode::DiagnosticOnTypeError, sym::label) => { | ||
| malformed!() | ||
| } |
There was a problem hiding this comment.
you can delete this arm, they should just fallthrough to the _other arm at the bottom
| @@ -0,0 +1,18 @@ | |||
| #![feature(diagnostic_on_type_error)] | |||
|
|
|||
| #[diagnostic::on_type_error(note = "custom on_type_error note: test coelesce")] | |||
There was a problem hiding this comment.
| #[diagnostic::on_type_error(note = "custom on_type_error note: test coelesce")] | |
| #[diagnostic::on_type_error(note = "custom on_type_error note: test coalesce")] |
Same for the rest of this file. Also these messages get de duplicated, so you can't tell whether they coalesced and were de duplicated, or whether one got through and the other got ignored. You'd have to make the messages different to test that.
| if !cx.features().diagnostic_on_type_error() { | ||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
You have to target check here, otherwise you can't warn if someone uses this on a macro invocation. Like this:
rust/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs
Lines 30 to 32 in f3ef3bd
The generic param check has to stay in check_attr, it can't be done here.
Suggested-by: Esteban Küber <[email protected]> Signed-off-by: Usman Akinyemi <[email protected]>
e26cc59 to
fba1fbe
Compare
|
@mejrs, thanks for the review. I got it made the changes. |
View all comments