Skip to content
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

Give a better error message when a query isn't supported for a local / external crate #101666

Closed
jyn514 opened this issue Sep 10, 2022 · 10 comments · Fixed by #104675
Closed

Give a better error message when a query isn't supported for a local / external crate #101666

jyn514 opened this issue Sep 10, 2022 · 10 comments · Fixed by #104675
Labels
A-contributor-roadblock Area: Makes things more difficult for new contributors to rust itself A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) E-help-wanted Call for participation: Help is requested to fix this issue. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate.

Comments

@jyn514
Copy link
Member

jyn514 commented Sep 10, 2022

@richkadel made a great start on this in #83367, but it would be nice to explain the local/external distinction in the panic message; "unsupported by crate" is unhelpful. This is an ICE targeted at compiler developers so IMO it can be pretty much as long as we want.

Currently the error looks like this:

error: internal compiler error: compiler\rustc_middle\src\ty\query.rs:335:1: tcx.module_children(DefId(0:4 ~ similar_paths_reexported[71d7]::module::S)) unsupported by its crate; perhaps the module_children query was never assigned a provider function

I wrote up this description while helping someone debug on discord, which may be a good start:

There are two types of queries. Queries local to the crate, and queries for external crates. This error means that you try to use it for the one that's not supported - usually that's the local crate
But you can tell by looking at CrateId of the DefId

If possible, we should say "tcx.module_children unsupported by local crate" (or external as appropriate, selected at runtime), but if not, we should at least explain what's going wrong better. The link below has a lot of details about the code structure that may be helpful.

Originally posted by @richkadel in #83122 (comment)

@jyn514 jyn514 added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue. A-contributor-roadblock Area: Makes things more difficult for new contributors to rust itself A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) labels Sep 10, 2022
@hanar3
Copy link
Contributor

hanar3 commented Sep 13, 2022

Claiming this. If @jyn514 someone could bring some color on whether key is always a valid rustc_query_impl::keys::Key in this context as per the discussion on #83122 (comment) would be very helpful as this is the first issue I'm taking on.

If key is guaranteed to be a valid key, we could call key.query_crate_is_local as per the docs to figure if it's a local or external crate?

@hanar3
Copy link
Contributor

hanar3 commented Sep 13, 2022

@rustbot claim

@jyn514
Copy link
Member Author

jyn514 commented Sep 14, 2022

@hanar3 yes, all keys must implement Key or they can't be used as the argument to a query in the first place. query_key_is_local is already used in that macro :) https://github.com/rust-lang/rust/blob/8d113ae658eec2feb3a5be0a782eabbfacfb0f2b/compiler/rustc_query_impl/src/plumbing.rs#L250

@hanar3
Copy link
Contributor

hanar3 commented Sep 14, 2022

Awesome, thanks for the reply! This is what I have in place so far.

        impl Default for Providers {
            fn default() -> Self {
                Providers {
                    $($name: |_, key| bug!(
                        "`tcx.{}({:?})` unsupported for {} crate; \
                         perhaps the `{}` query was never assigned a provider function. Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.", 
                        stringify!($name),
                        key,
                        if key.query_crate_is_local() { "local" } else { "external" } ,
                        stringify!($name),
                    ),)*
                }
            }
        }

The compiler, however, is not happy with me calling key.query_crate_is_local()

175  | /  macro_rules! define_callbacks {
176  | |      (
177  | |       $($(#[$attr:meta])*
178  | |          [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
...    |
282  | |                          if key.query_crate_is_local() { "local" } else { "external" } ,
     | |                                 ^^^^^^^^^^^^^^^^^^^^ method not found in `(ty::Ty<'_>, Option<Binder<'_, ExistentialTraitRef<'_>>>)`
...    |
321  | |      };
322  | |  }
     | |__- in this expansion of `define_callbacks!` (#2)

This is the macro definition, I noticed it usestt for every argument of fn.

[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {

Is it right to assume that the method not found in (ty::Ty<'_>, Option<Binder<'_, ExistentialTraitRef<'_>>>) is due to the macro using tt to define the function arguments rather than :expr as per your example? If so, could we use use/define a macro similar to the one you referenced on your comment above? Something like:

[$($modifiers:tt)*] fn $name:ident($($K:expr)*) -> $V:ty,)*)

EDIT: If key is always a valid key at runtime, this wouldn't cause harm I believe?

Thanks in advance!

@jyn514
Copy link
Member Author

jyn514 commented Sep 14, 2022

@hanar3 hmm, I think I was wrong before - the problem is that the key only needs to implement the Key trait if the macro has the separate_provide_extern modifier. Maybe you can add a new get_default_provider macro; that will give a better error anyway since it can distinguish "you added a local provider but not an extern provider" from "you never added a provider at all".

tt vs expr isn't relevant, they expand to the same thing at expansion time.

@hanar3
Copy link
Contributor

hanar3 commented Sep 15, 2022

Hi @jyn514, if I understood correctly, the key is not guaranteed to implement the Key trait on the code snippet I provided, so we can't reliably call query_crate_is_local() due to that, which is fine.

To your point on the new get_default_provider macro, I tried a few takes, since I'm not very knowledgeable on the macros, and haven't found many docs around them, I tried a few takes basing myself off of the get_provider macro you referenced above, and seperate_provide_extern_default to come up with an implementation for the new get_default_provider macro. Since both macros I used as example have the separate_provide_extern, I thought this would help me figure out the new macro.

I got to a point where I tried a few solutions (I can share them here, if you want to reference), but still end up with very similar compiler issues for all of them.

key.query_crate_is_local(),
     | |                   ^^^^^^^^^^^^^^^^^^^^ method not found in `InstanceDef<'_>`

and

186  | |               key.query_crate_is_local(),
     | |                   ^^^^^^^^^^^^^^^^^^^^ method not found in `(rustc_span::def_id::CrateNum, SimplifiedTypeGen<rustc_span::def_id::DefId>)`

This one made me think I might be going to the right direction...I see a DefId here, and we know we can tell the crate by looking at the DefId...

This was my last take on get_default_provider. Again, I'm not very knowledgeable on this, so my solutions were heavily based off of macros that were already present and doing similar things, so I'm afraid this might not be the way to solve it.

macro_rules! get_default_provider {
    ([][$name:ident]) => {
        ()
    };

    ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
        |_, key| bug!(
            "`tcx.{}({:?})` unsupported by {} crate;", // Removed a chunk of the message here just to make this more readable.
            stringify!($name),
            if key.query_crate_is_local() { "local" } else { "extern" },
            stringify!($name),
        )
    };
    ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
        get_default_provider!([$($modifiers)*][$($args)*])
    };
}

If you could point me to the right direction here as it relates to this new macro, that would be super helpful!!

Again, thanks for the great support on this one. Really having fun while trying to push my first contribution! :)

@hanar3
Copy link
Contributor

hanar3 commented Sep 18, 2022

Hi @jyn514,
After some digging, I couldn't find a way to reliably add local / external to the message based on the key - so I ended up just improving the message without it specifying which crate the error is referring to.

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 20, 2022
…e, r=oli-obk

Improve error for when query is unsupported by crate

This is an improvement to the error message mentioned on rust-lang#101666.  It seems like a good idea to also add [this link to the rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html), if explaining the query system in detail is a concern here, but I'm unsure if there is any restrictions on adding links to error messages.
spastorino added a commit to spastorino/rust that referenced this issue Sep 20, 2022
…e, r=oli-obk

Improve error for when query is unsupported by crate

This is an improvement to the error message mentioned on rust-lang#101666.  It seems like a good idea to also add [this link to the rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html), if explaining the query system in detail is a concern here, but I'm unsure if there is any restrictions on adding links to error messages.
notriddle added a commit to notriddle/rust that referenced this issue Sep 20, 2022
…e, r=oli-obk

Improve error for when query is unsupported by crate

This is an improvement to the error message mentioned on rust-lang#101666.  It seems like a good idea to also add [this link to the rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html), if explaining the query system in detail is a concern here, but I'm unsure if there is any restrictions on adding links to error messages.
notriddle added a commit to notriddle/rust that referenced this issue Sep 20, 2022
…e, r=oli-obk

Improve error for when query is unsupported by crate

This is an improvement to the error message mentioned on rust-lang#101666.  It seems like a good idea to also add [this link to the rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html), if explaining the query system in detail is a concern here, but I'm unsure if there is any restrictions on adding links to error messages.
@hanar3 hanar3 removed their assignment Oct 4, 2022
@SarthakSingh31
Copy link
Contributor

SarthakSingh31 commented Oct 25, 2022

Hello @jyn514, I looked into this a little bit and to me it seems that all the keys do implement rustc_query_impl::key::Key. The main problem with calling Key::query_crate_is_local from rustc_middle::ty::query::Providers::default is that rustc_middle cannot depend on rustc_query_impl and therefore cannot use the Key trait.

I am new to contributing to rust. I don't know how feasible this is but maybe we can move compiler/rustc_query_impl/src/keys.rs to rustc_middle? Every dependency used in keys.rs is also available in rustc_middle.

@winxpqq955
Copy link
Contributor

@rustbot claim

@winxpqq955 winxpqq955 removed their assignment Nov 3, 2022
@winxpqq955
Copy link
Contributor

@rustbot release-assignment

@jyn514 jyn514 added E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. and removed E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. labels Nov 12, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 26, 2022
Unsupported query error now specifies if its unsupported for local or external crate

Fixes rust-lang#101666.
I had to move `keys.rs` from `rustc_query_impl` to `rustc_middle`. I don't know if that is problematic. I couldn't think of any other way to get the needed information inside `rustc_middle`.

r? ``@jyn514``
@bors bors closed this as completed in 42010a2 Nov 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-contributor-roadblock Area: Makes things more difficult for new contributors to rust itself A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) E-help-wanted Call for participation: Help is requested to fix this issue. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate.
Projects
None yet
4 participants