-
Notifications
You must be signed in to change notification settings - Fork 236
Document constructor ranges #7227
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
base: main
Are you sure you want to change the base?
Conversation
95b6ee7 to
d521063
Compare
d521063 to
6123a1d
Compare
| /// Construct a date from a [`RataDie`] and some calendar representation | ||
| /// The lowest [`RataDie`] that will round-trip through [`Date::from_rata_die`] | ||
| /// and [`Date::to_rata_die`]. | ||
| pub const LOWEST_RATA_DIE: RataDie = *VALID_RD_RANGE.start(); |
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.
note: we should make sure this new public API is where we want it
I think it is.
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.
Alternative:
Date::new_max().to_rata_die()new_max returns Date<Iso>
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 to_rata_die() can't be called in const
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 want to stop treating ISO as a special calendar, RD is the calendar-neutral date representation. Also I don't want to expose this as the max date, only as the max input for the from_rata_die function.
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 that's reasonable.
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.
hmm it's not ideal, because Date is generic and callers have to pick a calendar to access the const, even though it's calendar-agnostic
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.
If from_rata_die saturates, people can get the max via
Date::from_rata_die(RataDie::MAX_VALUE).to_rata_die()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.
RataDie::MAX_VALUE does not exist though
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.
And we probably shouldn't add one since this is an icu_calendar constraint, not a calendrical_calculations constraint.
I'm not overly bothered by this value requiring you to specify a calendar. I don't expect this to be used a lot.
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 had intended to observe that if we were to add RataDie::MAX_VALUE returning i64::MAX in calendrical_calculations, icu_calendar still results in it being constrained.
| /// Construct a new Buddhist [`Date`]. | ||
| /// | ||
| /// Years are specified as BE years. | ||
| /// Years are arithmetic, meaning there is a year 0 preceded by negative years, with a |
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.
Nit: This sentence doesn't read correctly for me. The word "arithmetic" is a noun by default, so "years are arithmetic" doesn't make sense. If using "arithmetic" as an adjective, please don't use it in a position in the sentence where it could be interpreted as a noun.
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 didn't write this
icu4x/components/calendar/src/cal/julian.rs
Line 275 in b6b00b9
| /// Years are arithmetic, meaning there is a year 0. Zero and negative years are in BC, with year 0 = 1 BC |
| (Some(era), Some(era_year)) => { | ||
| let era_year_as_year_info = calendar | ||
| .year_info_from_era(era, range_check(era_year, "year", VALID_YEAR_RANGE)?)?; | ||
| let year = calendar.year_info_from_era(era, era_year)?; |
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.
Issue: The era_year shouldn't get plumbed into the calendar impl until we've checked that it is in some reasonable range, maybe +/- 1e7, to allow calendars like simplified chinese to make assumptions that years aren't too big.
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 don't think this is fixed. It looks like you fixed it for calendar-specific constructors, but not for from-codes or from-fields.
| /// Construct a date from a [`RataDie`] and some calendar representation | ||
| /// The lowest [`RataDie`] that will round-trip through [`Date::from_rata_die`] | ||
| /// and [`Date::to_rata_die`]. | ||
| pub const LOWEST_RATA_DIE: RataDie = *VALID_RD_RANGE.start(); |
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.
Alternative:
Date::new_max().to_rata_die()new_max returns Date<Iso>
components/calendar/src/types.rs
Outdated
| /// [`Date::try_from_fields`](crate::Date::try_from_fields) accepts years that correspond to | ||
| /// `extended_year`s in the range `-1,000,000..=1,000,000`. |
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.
Suggestion/Issue: I think this should range-check the era year to +/- 1e6.
The range check should either be on the input or on the output. If it is on the input, it should check the era year. If it is on the output, it should check the rata die. It doesn't make sense to range check the extended year, since it is the output of a calculation, which is valid so long as the Date is in range of its invariant.
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.
as explained in the PR description, that doesn't work because anyone can add a Japanese era that starts in the year 2e6.
|
Can we special case Japanese so that it checks in eraYear range and then also checks RD ranges? |
|
My concern is that someone could give |
|
I'm okay constraining both era year and extended year. The behavior would be, like,
|
|
Yeah, that's my concern too, and that's the blocking part of my comment there. |
|
Hmm, doing a double check everywhere is fine, I guess. I was hoping we could just check on the inputted But this is fine. |
sffc
left a comment
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.
Would really love to see tests for the limits across the constructors.
| (Some(era), Some(era_year)) => { | ||
| let era_year_as_year_info = calendar | ||
| .year_info_from_era(era, range_check(era_year, "year", VALID_YEAR_RANGE)?)?; | ||
| let year = calendar.year_info_from_era(era, era_year)?; |
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 don't think this is fixed. It looks like you fixed it for calendar-specific constructors, but not for from-codes or from-fields.
Manishearth
left a comment
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 this seems about right!
If you would like you can remove the guards in the fuzz tests but don't worry about it, I can do that myself later.
|
(I do consider tests to be a requirement for shipping this new "feature", but they can be in a follow-up if necessary) |
Changed the range from applying to era years to applying to extended years. We cannot apply it to era years, as Japanese has data-driven eras higher than any era from any calendar, so a new Japanese era would need a bigger RD range.
#7076