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

[r2r] safe number type casting #1517

Merged
merged 6 commits into from
Nov 15, 2022
Merged

Conversation

onur-ozkan
Copy link
Member

@onur-ozkan onur-ozkan commented Oct 30, 2022

I think we should replace all the possible overflow cases with this implementation. Should we cover that in this PR? @artemii235

Atm it only covers this line because @sergeyboyko0791 specifically asked for it here.

Opened from: #1515 (comment)
Resolves: #1500

Signed-off-by: ozkanonur <work@onurozkan.dev>
Signed-off-by: ozkanonur <work@onurozkan.dev>
Signed-off-by: ozkanonur <work@onurozkan.dev>
Copy link

@sergeyboyko0791 sergeyboyko0791 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the great improvement!
Please consider my suggestions.

mm2src/common/number_type_casting.rs Show resolved Hide resolved
impl_safe_number_type_cast!(u128, u8);

// I128
impl_safe_number_type_cast!(i128, i64);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is impl_safe_number_type_cast!(i128, isize); missing?

mm2src/common/number_type_casting.rs Outdated Show resolved Hide resolved
mm2src/common/number_type_casting.rs Show resolved Hide resolved
Signed-off-by: Onur Özkan <work@onurozkan.dev>
Copy link
Member

@artemii235 artemii235 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question.

($from: ident, $to: ident) => {
impl SafeTypeCastingNumbers<$to> for $from {
fn into_or(self, or: $to) -> $to { std::convert::TryFrom::try_from(self).unwrap_or(or) }
fn into_or_max(self) -> $to { std::convert::TryFrom::try_from(self).unwrap_or(std::$to::MAX) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find into_or_max a bit confusing for signed -> unsigned cast like impl_safe_number_type_cast!(i128, u64);. IMHO, it won't have a realistic use case. For example, if we get a negative value for a number supposed to represent an amount of money (e.g. BTC satoshis), we would likely prefer to return an error in such case instead of using max possible value. In general, should we maybe consider using TryFrom/TryInto directly and use unwrap_or where applicable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find into_or_max a bit confusing for signed -> unsigned cast like

impl_safe_number_type_cast!(i128, u64); so we will be able to use into_or_zero or into_or, there we should not use into_or_max.

For example, if we get a negative value for a number supposed to represent an amount of money (e.g. BTC satoshis), we would likely prefer to return an error in such case instead of using max possible value.

Then if we use this implementation, we should also add function that takes closure as an argument and uses it if try_from fails.

In general, should we maybe consider using TryFrom/TryInto directly and use unwrap_or where applicable?

For me it's also fine. Anything that replaces wrong x as y castings is fine enough :)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my point of view, so I agree with Artem about this. It's better to handle negative values manually.

I find into_or_max a bit confusing for signed -> unsigned cast like impl_safe_number_type_cast!(i128, u64);.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my point of view, so I agree with Artem about this. It's better to handle negative values manually.

I guess we should close the PR then?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we still need to cast unsigned to signed in my opinion

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@artemii235 any comments? If you aggree with Sergey, I can do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree - let's keep unsigned -> signed cast and handle negative values manually.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about unsigned -> unsigned casting(like u64 to u16 might cause overflow and produce random value) ? @artemii235 @sergeyboyko0791

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'll be helpful!

What about unsigned -> unsigned casting

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, having e.g. into_or_max seems reasonable for such cases.

Signed-off-by: ozkanonur <work@onurozkan.dev>
@onur-ozkan
Copy link
Member Author

Please review again @artemii235 @sergeyboyko0791

Btw, I think target_pointer_width is not really needed since values are handled by max or custom value. So it's better to provide this trait for all memory types.

Copy link

@sergeyboyko0791 sergeyboyko0791 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the conversation and for the fixes! Next review iteration.

mm2src/common/number_type_casting.rs Show resolved Hide resolved
mm2src/common/number_type_casting.rs Show resolved Hide resolved
mm2src/common/number_type_casting.rs Show resolved Hide resolved
Signed-off-by: ozkanonur <work@onurozkan.dev>
@artemii235
Copy link
Member

@sergeyboyko0791 Could you take one more look at this PR, please?

Copy link

@sergeyboyko0791 sergeyboyko0791 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@sergeyboyko0791 sergeyboyko0791 merged commit 535d6cb into dev Nov 15, 2022
@sergeyboyko0791 sergeyboyko0791 deleted the safe-number-type-casting branch November 15, 2022 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants