-
Couldn't load subscription status.
- Fork 13.9k
Add shorter and more direct error for dyn AsyncFn #133267
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
|
r? @wesleywiser rustbot has assigned @wesleywiser. Use |
|
HIR ty lowering was modified cc @fmease Some changes occurred in diagnostic error codes |
1e17c14 to
55d16b9
Compare
This comment has been minimized.
This comment has been minimized.
| ) -> Vec<DynCompatibilityViolation> { | ||
| debug_assert!(tcx.generics_of(trait_def_id).has_self); | ||
|
|
||
| // Check for `AsyncFn` traits first to avoid reporting various other |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't necessary, is it? I would suppose removing this doesn't actually affect anything.
| // errors about the details of why these traits aren't object-safe. | ||
| for supertrait in tcx.supertrait_def_ids(trait_def_id) { | ||
| if tcx.trait_is_async_fn(supertrait) { | ||
| let fn_trait = tcx.item_name(supertrait); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defer this call to item_name to the error reporting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, lol, you can't. If you want, you could probably remove the PartialOrd implementation from DynCompatibilityViolation, and change the one(?) sort call in error reporting to stop doing that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I did try that initially! Hence the comments about my annoyance that I couldn't put a DefId in the DynCompatibilityViolation. I don't think I want to extend this PR to removing the PartialOrd impl + sorting, as I anticipate that'll affect a number of other error outputs as well.
| let hir::Node::Ty(ty) = tcx.hir_node(hir_id) else { return }; | ||
| let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind else { return }; | ||
| let mut hir_id = hir_id; | ||
| while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use parent_iter and take_while rather than redoing it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like this?
- let mut hir_id = hir_id;
- while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) {
- hir_id = ty.hir_id;
- }
- if tcx.parent_hir_node(hir_id).fn_sig().is_none() {
+ let parent_ty_hir_id = tcx
+ .parent_iter(hir_id)
+ .take_while(|_id, node| if let hir::Node::Ty(_) = node { true } else { false })
+ .last()
+ .unwrap_or(hir_id);
+ if tcx.parent_hir_node(parent_ty_hir_id).fn_sig().is_none() {IMO that's harder to read. I also don't have access to parent_iter since it's a method on Map, though I'm probably just missing how to access that value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can access Map through tcx.hir().
Also, I'd probably write it a bit shorter like:
if tcx
.hir()
.parent_iter(hir_id)
.take_while(|_, node| matches!(node, hir::Node::Ty(_)))
Or actually, maybe just using skip_while to get the next node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parent_iter should always be preferred over repeated calls of parent_hir_node/parent_hir_id for performance reasons (see also docs of https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.parent_hir_id)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or actually, maybe just using skip_while to get the next node.
nit: I don't quite see how skip_while would work here since the goal is to get the last element that matches a predicate. I think take_while + last seems the most straightforward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, and we're immediately calling parent_hir_node on it. So what we really want is the first node that isn't a Node::Ty. But whatever, not worth fixing here.
compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
Outdated
Show resolved
Hide resolved
|
Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri Some changes occurred to the CTFE machinery cc @rust-lang/wg-const-eval |
This comment has been minimized.
This comment has been minimized.
0718a49 to
b73794d
Compare
This comment has been minimized.
This comment has been minimized.
b73794d to
166484c
Compare
166484c to
306702e
Compare
|
@bors r+ |
|
Sorry, but I actually have some thoughts here after some experimentation on a local branch @bors r- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the churn, but actually, I looked into this a bit further on my own local checkout since I wanted to make a quick follow-up, and I think this still needs some tweaks:
-
You're not actually using the
fn_traititem in theDynCompatibilityViolationanywhere? Not sure if it was intentional, but I also think that's fine -- I don't think it helps with the messaging anyways (and we can always elaborate the trait def id if we want to find it later, rather than storing it into theDynCompatibilityViolation). -
I'm gonna re-raise the question that I asked that didn't get an answer, which is why this needs a separate error code? I think that error code is kinda bespoke and unnecessary when we have a general error code E0038 for dyn compatibility violations, especially b/c we're already noting that "the trait cannot be made into an object because
asyncfunction traits are not yet dyn-compatible". -
Also, if you want to be cool and remove the sorting and
PartialOrd/Ordimplementation fromDynCompatibilityViolation, it's actually totally unnecessary for sorting. If you look at the one callsite in the compiler, it sorts the list and then maps that list then sorts it again 😆. If you don't want to fix that, then that's fine too 👍
| LL | fn takes_async_fn_once_implicit_dyn(_: Box<impl AsyncFnOnce()>) {} | ||
| | ++++ | ||
|
|
||
| error[E0038]: the trait `SubAsyncFn` cannot be made into an object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have an error code for object safety, why add another one? Also, I am a bit unsatisfied with the inconsistency in the error messaging between the error message above and this one. If we want to have a separate error message, it should probably read somewhat parallel to the E0038 error message.
I don't believe users really need an in-depth explanation of the implementation details for why AsyncFn* is not dyn-compatible, and especially b/c it's something that I expect for us to fix in the medium-term future with my introduction of general AFIDT support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't use the language "cannot be made into an object" in the new error message because my understanding was that "object-safety" is the deprecated term, and "dyn-compatibility" is the new one. I also didn't change both to use "dyn-compatibility" because that would have affected significantly more code, though I can send a separate PR for that if it is desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just making this say the same thing as what E0038 says by default is fine, and if you'd like to reword the general error message in a separate PR it should be done separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the net effect of this PR should be to deduplicate the many different dyn compatibility violations, and to add a note explaining that AsyncFn* is not object safe.
Adding a totally different error message and a new error code seem unnecessary on top of that I feel?
| // in the error reporting stage, but sadly this isn't possible because | ||
| // DefIds cannot be stored at this stage. Is there a better way to handle | ||
| // catching the supertrait case than string comparison? | ||
| fn_trait: Symbol, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually use this anywhere?
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
|
Closing this in favor of some more general fixes in #133372 |
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267
…=fmease Refactor dyn-compatibility error and suggestions This CL makes a number of small changes to dyn compatibility errors: - "object safety" has been renamed to "dyn-compatibility" throughout - "Convert to enum" suggestions are no longer generated when there exists a type-generic impl of the trait or an impl for `dyn OtherTrait` - Several error messages are reorganized for user readability Additionally, the dyn compatibility error creation code has been split out into functions. cc rust-lang#132713 cc rust-lang#133267 r? `@compiler-errors`
Fix #132713
cc #62290