nrc / derive-new

derive simple constructor functions for Rust structs
MIT License
525 stars 35 forks source link

#[new(value)} errors should not use Span::call_site() #45

Closed SOF3 closed 5 years ago

SOF3 commented 5 years ago

Recursively set the span of the parsed token stream to the span of the LitStr in the attribute that defined the code.

SOF3 commented 5 years ago

I'm not sure about how to write tests for this change, but I did a toy crate locally and it appears to work.

0 | sofe-ThinkPad-T480S @ ~/test/derive-new-test  # cat src/lib.rs 
#[derive(derive_new::new)]
pub struct A {
    #[new(value = "32")]
    bar: String,
}

0 | sofe-ThinkPad-T480S @ ~/test/derive-new-test  # cargo build
   Compiling derive-new-test v0.1.0 (/home/sofe/test/derive-new-test)
error[E0308]: mismatched types
 --> src/lib.rs:3:19
  |
3 |     #[new(value = "32")]
  |                   ^^^^
  |                   |
  |                   expected struct `std::string::String`, found integer
  |                   help: try using a conversion method: `"32".to_string()`
  |
  = note: expected type `std::string::String`
             found type `{integer}`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `derive-new-test`.

To learn more, run the command again with --verbose.

Without this change:

0 | sofe-ThinkPad-T480S @ ~/test/derive-new-test  # cargo build
   Compiling derive-new-test v0.1.0 (/home/sofe/test/derive-new-test)
error[E0308]: mismatched types
   --> src/lib.rs:1:10
    |
1   |   #[derive(derive_new::new)]
    |            ^^^^^^^^^^^^^^^
    |            |
    |            expected struct `std::string::String`, found integer
    |            help: try using a conversion method: `derive_new::new.to_string()`
    |            in this macro invocation
    | 
   ::: /home/sofe/.cargo/registry/src/github.com-1ecc6299db9ec823/derive-new-0.5.8/src/lib.rs:129:1
    |
129 | / pub fn derive(input: TokenStream) -> TokenStream {
130 | |     let ast: syn::DeriveInput = syn::parse(input).expect("Couldn't parse item");
131 | |     let result = match ast.data {
132 | |         syn::Data::Enum(ref e) => new_for_enum(&ast, e),
...   |
136 | |     result.into()
137 | | }
    | |_- in this expansion of `#[derive(derive_new::new)]`
    |
    = note: expected type `std::string::String`
               found type `{integer}`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `derive-new-test`.

To learn more, run the command again with --verbose.
nrc commented 5 years ago

Looks like you need to update the new-invalid-value.rs test though

SOF3 commented 5 years ago

I don't know how to use the compile-fail things.

nrc commented 5 years ago

I think you just need to move line 6 to underneath line 8 (since the error occurs there now) and remove one of the ^s (because the error is one line up, not two).

SOF3 commented 5 years ago

Fixed

nrc commented 5 years ago

Awesome, thanks!