-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Cargo fix generates broken code for type names passed to derives #67373
Comments
Moved to rust-lang/rust, as the fix suggestions are generated by It might help to include a minimal reproduction, along with details about what the before and after looks like. Diesel is quite large, and it can be difficult to untangle what is going on from what you linked. |
Thanks, @ehuss! A minimal reproduction would be this:
I suspect the problem here is that we are parsing the given string as a type (since that's the only type that could be used to reference a type in a meta attribute), keeping the span of the original string. It appears as though it's just naively putting
gets the same treatment:
Since the APIs on |
I was thinking of something more along the lines of not using diesel, since there's a lot of machinery there. Something like this: // A proc-macro crate named "pmf".
extern crate proc_macro;
extern crate syn;
extern crate quote;
use proc_macro::TokenStream;
use quote::quote;
#[proc_macro_derive(Foo, attributes(helper))]
pub fn foo(tokens: TokenStream) -> TokenStream {
let s = syn::parse_macro_input!(tokens as syn::DeriveInput);
let helper = s.attrs.iter().filter(|attr| attr.path.is_ident("helper")).next().unwrap();
let name = match helper.parse_meta().unwrap() {
syn::Meta::NameValue(v) => v.lit,
_ => panic!("expected helper=lit"),
};
let name_str = match name {
syn::Lit::Str(s) => s,
_ => panic!("expected string"),
};
let ty: syn::Type = name_str.parse().unwrap(); // KEY POINT HERE
let ts = quote!{
impl Foo for #ty {}
};
TokenStream::from(ts)
} // A 2015-edition crate using the proc-macro "pmf".
#![warn(absolute_paths_not_starting_with_crate)]
extern crate pmf;
pub trait Foo {}
#[derive(pmf::Foo)]
#[helper = "::Bar"]
pub struct S;
pub struct Bar; Results in:
I think the key part here is that diesel is using |
That's certainly an option, but the code will still be broken (because the string |
Sure, but IMO leaving broken code is preferable to generating even more broken code |
I can try to produce a more minimal repro if you'd like -- I opted not to upon reporting because it seems the root cause is pretty clear just from the behavior alone. (Granted it seems like your last comment has it, thank you!) |
Do not provide suggestions when the spans come from expanded code that doesn't point at user code Hide invalid proc-macro suggestions and track spans coming from proc-macros pointing at attribute. Effectively, unless the proc-macro keeps user spans, suggestions will not be produced for the code they produce. r? `@ghost` Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557. Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
Do not provide suggestions when the spans come from expanded code that doesn't point at user code Hide invalid proc-macro suggestions and track spans coming from proc-macros pointing at attribute. Effectively, unless the proc-macro keeps user spans, suggestions will not be produced for the code they produce. r? ``@ghost`` Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557. Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
When a type is given to a proc macro as a string, such as in https://github.com/diesel-rs/diesel/blob/6e2d467d131030dc0bbce4e4801c7bee7bcbf0dd/diesel/src/type_impls/primitives.rs#L20,
cargo fix --edition
will incorrectly generatecrate::"::old_type::Path"
. If there are nested types inside, such as https://github.com/diesel-rs/diesel/blob/6e2d467d131030dc0bbce4e4801c7bee7bcbf0dd/diesel/src/type_impls/primitives.rs#L42, they won't be touched at all.The text was updated successfully, but these errors were encountered: