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

Fix ambiguous associated item for TryFrom, TryInto and FromStr #410

Merged
merged 4 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
([#399](https://github.com/JelteF/derive_more/pull/399))
- `unreachable_code` warnings on generated code when `!` (never type) is used.
([#404](https://github.com/JelteF/derive_more/pull/404))
- Fix ambiguous associated item error when deriving `TryFrom`, `TryInto` or `FromStr` with an associated item called `Error` or `Err` respectively.


## 1.0.0 - 2024-08-07
Expand Down
6 changes: 3 additions & 3 deletions impl/doc/from_str.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Code like this will be generated:
# struct MyInt(i32);
impl derive_more::FromStr for MyInt {
type Err = <i32 as derive_more::FromStr>::Err;
fn from_str(src: &str) -> Result<Self, Self::Err> {
fn from_str(src: &str) -> Result<Self, <i32 as derive_more::FromStr>::Err> {
return Ok(MyInt(i32::from_str(src)?));
}
}
Expand Down Expand Up @@ -76,7 +76,7 @@ Code like this will be generated:
# }
impl derive_more::FromStr for Point1D {
type Err = <i32 as derive_more::FromStr>::Err;
fn from_str(src: &str) -> Result<Self, Self::Err> {
fn from_str(src: &str) -> Result<Self, <i32 as derive_more::FromStr>::Err> {
return Ok(Point1D {
x: i32::from_str(src)?,
});
Expand Down Expand Up @@ -123,7 +123,7 @@ Code like this will be generated:
#
impl derive_more::FromStr for EnumNoFields {
type Err = derive_more::FromStrError;
fn from_str(src: &str) -> Result<Self, Self::Err> {
fn from_str(src: &str) -> Result<Self, derive_more::FromStrError> {
Ok(match src.to_lowercase().as_str() {
"foo" => EnumNoFields::Foo,
"bar" => EnumNoFields::Bar,
Expand Down
14 changes: 7 additions & 7 deletions impl/doc/try_into.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Code like this will be generated:
# }
impl derive_more::TryFrom<MixedInts> for (i32) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
fn try_from(value: MixedInts) -> Result<Self, &'static str> {
match value {
MixedInts::SmallInt(__0) => Ok(__0),
_ => Err("Only SmallInt can be converted to i32"),
Expand All @@ -106,7 +106,7 @@ impl derive_more::TryFrom<MixedInts> for (i32) {
}
impl derive_more::TryFrom<MixedInts> for (i64) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
fn try_from(value: MixedInts) -> Result<Self, &'static str> {
match value {
MixedInts::BigInt(__0) => Ok(__0),
_ => Err("Only BigInt can be converted to i64"),
Expand All @@ -115,7 +115,7 @@ impl derive_more::TryFrom<MixedInts> for (i64) {
}
impl derive_more::TryFrom<MixedInts> for (i32, i32) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
fn try_from(value: MixedInts) -> Result<Self, &'static str> {
match value {
MixedInts::TwoSmallInts(__0, __1) => Ok((__0, __1)),
_ => Err("Only TwoSmallInts can be converted to (i32, i32)"),
Expand All @@ -124,7 +124,7 @@ impl derive_more::TryFrom<MixedInts> for (i32, i32) {
}
impl derive_more::TryFrom<MixedInts> for (i64, i64) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
fn try_from(value: MixedInts) -> Result<Self, &'static str> {
match value {
MixedInts::NamedSmallInts { x: __0, y: __1 } => Ok((__0, __1)),
_ => Err("Only NamedSmallInts can be converted to (i64, i64)"),
Expand All @@ -133,7 +133,7 @@ impl derive_more::TryFrom<MixedInts> for (i64, i64) {
}
impl derive_more::TryFrom<MixedInts> for (u32) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
fn try_from(value: MixedInts) -> Result<Self, &'static str> {
match value {
MixedInts::UnsignedOne(__0) | MixedInts::UnsignedTwo(__0) => Ok(__0),
_ => Err("Only UnsignedOne, UnsignedTwo can be converted to u32"),
Expand Down Expand Up @@ -163,7 +163,7 @@ Code like this will be generated:
# }
impl derive_more::TryFrom<EnumWithUnit> for (i32) {
type Error = &'static str;
fn try_from(value: EnumWithUnit) -> Result<Self, Self::Error> {
fn try_from(value: EnumWithUnit) -> Result<Self, &'static str> {
match value {
EnumWithUnit::SmallInt(__0) => Ok(__0),
_ => Err("Only SmallInt can be converted to i32"),
Expand All @@ -172,7 +172,7 @@ impl derive_more::TryFrom<EnumWithUnit> for (i32) {
}
impl derive_more::TryFrom<EnumWithUnit> for () {
type Error = &'static str;
fn try_from(value: EnumWithUnit) -> Result<Self, Self::Error> {
fn try_from(value: EnumWithUnit) -> Result<Self, &'static str> {
match value {
EnumWithUnit::Unit => Ok(()),
_ => Err("Only Unit can be converted to ()"),
Expand Down
7 changes: 4 additions & 3 deletions impl/src/from_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ pub fn struct_from(state: &State, trait_name: &'static str) -> TokenStream {

let initializers = [quote! { #casted_trait::from_str(src)? }];
let body = single_field_data.initializer(&initializers);
let error = quote! { <#field_type as #trait_path>::Err };

quote! {
#[automatically_derived]
impl #impl_generics #trait_path for #input_type #ty_generics #where_clause {
type Err = <#field_type as #trait_path>::Err;
type Err = #error;

#[inline]
fn from_str(src: &str) -> derive_more::core::result::Result<Self, Self::Err> {
fn from_str(src: &str) -> derive_more::core::result::Result<Self, #error> {
derive_more::core::result::Result::Ok(#body)
}
}
Expand Down Expand Up @@ -97,7 +98,7 @@ fn enum_from(
type Err = derive_more::FromStrError;

#[inline]
fn from_str(src: &str) -> derive_more::core::result::Result<Self, Self::Err> {
fn from_str(src: &str) -> derive_more::core::result::Result<Self, derive_more::FromStrError> {
Ok(match src.to_lowercase().as_str() {
#(#cases)*
_ => return Err(derive_more::FromStrError::new(#input_type_name)),
Expand Down
6 changes: 4 additions & 2 deletions impl/src/try_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,16 @@ impl ToTokens for Expansion {
)
.unzip();

let error = quote! { derive_more::TryFromReprError<#repr_ty> };

quote! {
#[automatically_derived]
impl #impl_generics derive_more::TryFrom<#repr_ty #ty_generics> for #ident #where_clause {
type Error = derive_more::TryFromReprError<#repr_ty>;
type Error = #error;

#[allow(non_upper_case_globals)]
#[inline]
fn try_from(val: #repr_ty) -> derive_more::core::result::Result<Self, Self::Error> {
fn try_from(val: #repr_ty) -> derive_more::core::result::Result<Self, #error> {
#( const #consts: #repr_ty = #discriminants; )*
match val {
#(#consts => derive_more::core::result::Result::Ok(#ident::#variants),)*
Expand Down
8 changes: 6 additions & 2 deletions impl/src/try_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,21 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
input.generics.split_for_impl()
};

let error = quote! {
derive_more::TryIntoError<#reference_with_lifetime #input_type #ty_generics>
};

let try_from = quote! {
#[automatically_derived]
impl #impl_generics derive_more::core::convert::TryFrom<
#reference_with_lifetime #input_type #ty_generics
> for (#(#reference_with_lifetime #original_types),*) #where_clause {
type Error = derive_more::TryIntoError<#reference_with_lifetime #input_type #ty_generics>;
type Error = #error;

#[inline]
fn try_from(
value: #reference_with_lifetime #input_type #ty_generics,
) -> derive_more::core::result::Result<Self, Self::Error> {
) -> derive_more::core::result::Result<Self, #error> {
match value {
#(#matchers)|* => derive_more::core::result::Result::Ok(#vars),
_ => derive_more::core::result::Result::Err(
Expand Down
Loading