xso-proc: improve error message on type mismatch for extracted fields
The case this affects is a field like:
```
struct Foo {
#[xml(extract(fields(text(type_ = String)), namespace = .., name = ..))]
foo: ServiceType,
}
```
Before, we get this:
```
error[E0631]: type mismatch in closure arguments
--> muchopper/libmuchopper/src/xmpp/sjn_api.rs:188:10
|
188 | #[derive(AsXml)]
| ^^^^^
| |
| expected due to this
| found signature defined here
|
= note: expected closure signature `fn(&ServiceType) -> _`
found closure signature `fn(&'xso_proc_as_xml_iter_lifetime std::string::String) -> _`
note: required by a bound in `std::option::Option::<T>::map`
--> /home/jssfr/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1102:12
|
1100 | pub fn map<U, F>(self, f: F) -> Option<U>
| --- required by a bound in this associated function
1101 | where
1102 | F: FnOnce(T) -> U,
| ^^^^^^^^^^^^^^ required by this bound in `Option::<T>::map`
= note: this error originates in the derive macro `AsXml` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Afterwards, this:
```
error[E0308]: mismatched types
--> muchopper/libmuchopper/src/xmpp/sjn_api.rs:207:20
|
206 | #[xml(extract(namespace = ECS, name = "service-type", fields(text(type_ = String))))]
| ------ expected due to this
207 | pub service_type: ServiceType,
| ^^^^^^^^^^^ expected `Option<&String>`, found `Option<&ServiceType>`
|
= note: expected enum `std::option::Option<&'xso_proc_as_xml_iter_lifetime std::string::String>`
found enum `std::option::Option<&ServiceType>`
```
skip-changelog, because this affects a feature which already has an
"Added" line in the changelog.
This commit is contained in:
parent
727e57b756
commit
95773505e4
1 changed files with 10 additions and 2 deletions
|
|
@ -460,14 +460,22 @@ impl ExtractDef {
|
|||
// about that in [`make_from_xml_builder_parts`] implementation
|
||||
// corresponding to this code above, and we will not repeat it
|
||||
// here.
|
||||
|
||||
// These sections with quote_spanned are used to improve error
|
||||
// messages on type mismatches. Without these, the rustc errors
|
||||
// will point at `#[derive(AsXml)]` only, instead of directly
|
||||
// pointing at the sources of those types.
|
||||
let cast = quote_spanned! { input_ty.span()=>
|
||||
::core::option::Option::from(#bound_name)
|
||||
};
|
||||
let type_assert = quote_spanned! { inner_ty.span()=>
|
||||
::core::option::Option<#inner_ty>
|
||||
};
|
||||
(
|
||||
quote! {
|
||||
::xso::asxml::OptionAsXml::new(#cast.map(|#bound_name: #inner_ty| {
|
||||
::xso::asxml::OptionAsXml::new({ let x: #type_assert = #cast; x.map(|#bound_name: #inner_ty| {
|
||||
#item_iter_ty_ident::new((#repack))
|
||||
}).transpose()?)
|
||||
})}.transpose()?)
|
||||
},
|
||||
option_as_xml_ty(item_iter_ty),
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue