-
Notifications
You must be signed in to change notification settings - Fork 29
Indicate specific blocking risks in conversions #482
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
Conversation
Right now, conversion failures are somewhat inscrutable. Consider these unsafe conversions: ```cpp seconds(2).as(nano(seconds)); // OVERFLOW_RISK nano(seconds)(2).as(seconds); // TRUNCATION_RISK (giga(hertz) * mag<2>() / mag<3>())(1).as(hertz); // ALL_RISKS ``` I've annotated each one with the risk that prevents the conversion --- but remember that an end user won't know a priori which one this is! And the error messages are no help: <img width="1117" height="829" alt="image" src="https://github.com/user-attachments/assets/8f0315be-dd03-44d8-876d-ba71577633f9" /> This just basically says "some risk is too high". It doesn't say which risk(s), and it doesn't say what to do about it. We can do better by checking the risks individually, and splitting the error message across three mutually exclusive and exhasutive error conditions. First, if a conversion is blocked, then it would either fail the overflow risk check, truncation risk check, or else both (those are the 3 possibilities). Second, if _any_ non-skipped risk check fails, then we want to check _all_ risk checks, _regardless_ of skip status. After all, if a conversion is "double risked", and the user has passed `ignore(OVERFLOW_RISK)`, we don't want to tell them to pass `ignore(TRUNCATION_RISK)`, because that will just re-activate the overflow risk failure! We want to tell them to use `ignore(ALL_RISKS)`. <img width="1117" height="814" alt="image" src="https://github.com/user-attachments/assets/8a9ac4a4-5eeb-4b0b-aac1-7af6e98bac84" /> These error messages are much more clear and actionable. We can bikeshed the wording, but it seems clear that this will be a much better experience for our users. Follow-on to #387.
|
I'm planning to kick off an overnight compile time impact measurement tonight. We can review the PR once we get those results. |
|
The compile time impact is roughly:
0.5.0 already has a moderate slowdown for conversion functions generally. It's higher than I would prefer, but not a showstopper IMO. What this PR seems to do is to make that increased cost about 15% larger. This is also higher than I would prefer, but I think the usability gains are worth more. Even in our canonical "lots of conversions" file, this PR amounts to about 25 ms (cumulative over all those conversions). I think that is a price worth paying to make the error messages significantly more actionable. As for the specific contents of the message:
So I think we can land as-is as a placeholder, with plans to fix up the contents when we do the doc refresh. |
au/quantity.hh
Outdated
| !is_truncation_risk_ok; | ||
| static_assert(!are_both_overflow_and_truncation_unacceptably_risky, | ||
| "Both truncation and overflow risk too high. " | ||
| "Can silence by passing `ignore(ALL_RISKS)` as second argument, " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just had a thought about ALL_RISKS. Would there be a passibility that we'll add additional risk types in the future? Would setting ALL_RISKS today potentially mask those new risks in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's pretty unlikely, but I definitely think this will be safer, and at the very least also more intent-based. I'll update the message accordingly.
Right now, conversion failures are somewhat inscrutable. Consider these
unsafe conversions:
I've annotated each one with the risk that prevents the conversion ---
but remember that an end user won't know a priori which one this is!
And the error messages are no help:
This just basically says "some risk is too high". It doesn't say which
risk(s), and it doesn't say what to do about it.
We can do better by checking the risks individually, and splitting the
error message across three mutually exclusive and exhasutive error
conditions. First, if a conversion is blocked, then it would either
fail the overflow risk check, truncation risk check, or else both (those
are the 3 possibilities). Second, if any non-skipped risk check
fails, then we want to check all risk checks, regardless of skip
status. After all, if a conversion is "double risked", and the user has
passed
ignore(OVERFLOW_RISK), we don't want to tell them to passignore(TRUNCATION_RISK), because that will just re-activate theoverflow risk failure! We want to tell them to use
ignore(ALL_RISKS).These error messages are much more clear and actionable. We can
bikeshed the wording, but it seems clear that this will be a much better
experience for our users.
Follow-on to #387.