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

Use Pattern more directly #5531

Merged
merged 15 commits into from
Sep 19, 2024
Merged

Conversation

robertbastian
Copy link
Member

@robertbastian robertbastian commented Sep 11, 2024

  • Removed the Store generic from Pattern. It now always uses the unsized PatternBackend::Store. Instead of using Pattern<B, String> for the owned version, it's now Box<Pattern<B>>

  • Implemented ToOwned for Pattern so that we can use Cow<Pattern<B>>. The owned type is Box<Pattern<B>>

  • Replaced the FromStr implementation by try_from_str, which returns Box<Self>

    • Together these changes completely remove the need of downstream users to fuss around with the store.
  • Removed the PluralPatterns type, this now uses PluralElementsPackedCow<Pattern<B>> directly

  • Changed pattern JSON serialization to use actual pattern string, instead of vecs of items

  • Changed CLDR parsing to use patterns directly in CLDR JSON structs

Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

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

Praise: I'm in favor of this change and the work you did looks quite good. I have some suggestions/nits/issues about some corners.

///
/// To parse a pattern string, use [`FromStr::from_str`].
///
/// # Examples
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Bring back the example, please

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a moot examples because users don't have to do store-juggling anymore.

Copy link
Member

Choose a reason for hiding this comment

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

Stores are still public, yes?

Copy link
Member Author

Choose a reason for hiding this comment

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

No

utils/pattern/src/frontend/mod.rs Show resolved Hide resolved
utils/pattern/src/frontend/mod.rs Show resolved Hide resolved
utils/pattern/src/frontend/mod.rs Show resolved Hide resolved
utils/pattern/src/frontend/mod.rs Show resolved Hide resolved
Comment on lines 40 to 41
#[allow(clippy::unwrap_used)] // todo does this work?
Self(Pattern::try_from_boxed_store(Default::default()).unwrap())
Copy link
Member

Choose a reason for hiding this comment

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

Why do you need to impl Default?

Copy link
Member Author

Choose a reason for hiding this comment

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

To use this in CLDR JSON.

utils/pattern/src/common.rs Outdated Show resolved Hide resolved
utils/pattern/src/common.rs Outdated Show resolved Hide resolved
utils/pattern/src/frontend/mod.rs Outdated Show resolved Hide resolved
@sffc
Copy link
Member

sffc commented Sep 12, 2024

@robertbastian I want to add custom baked constructors in order to fix #5230, but it would directly conflict with this PR. Are you planning to finish/merge this soon?

Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

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

(almost done reviewing)

provider/source/src/tests/make_testdata.rs Outdated Show resolved Hide resolved
sffc
sffc previously approved these changes Sep 16, 2024
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

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

Good work; nothing blocks landing this PR, which I prefer to do in order to prevent bitrot, but there are a few small things I'd like to see fixed in a follow-up

deserialize_with = "icu_pattern::deserialize_option_borrowed_cow"
)
)]
pub standard_pattern: Option<Cow<'data, DoublePlaceholderPattern>>,
Copy link
Member

Choose a reason for hiding this comment

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

Thought: I think we should do as you suggested in the other issue. We can export a ZeroCow type from zerovec that has the correct Serde impls and reduces one layer of struct construction in the Bake impl. (Not in this PR)

utils/pattern/src/frontend/serde.rs Outdated Show resolved Hide resolved
D: serde::Deserializer<'de>,
{
Ok(Self(
Pattern::<B>::try_from_str(&<Cow<str>>::deserialize(deserializer)?, Default::default())
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I think <Cow<str>>::deserialize always deserializes to a String. serde_derive has special-case code that essentially adds a deserialize_with if Syn sees a Cow<str>. It doesn't actually specialize Cow<str> to borrow when possible.

utils/pattern/src/frontend/serde.rs Show resolved Hide resolved
unsafe impl VarULE for Pattern<SinglePlaceholder, str> {
unsafe impl<B> VarULE for Pattern<B>
where
B: PatternBackend<Store = str>,
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: does this work with B::Store: VarULE?

@robertbastian
Copy link
Member Author

Cool this triggers an ICE

@sffc
Copy link
Member

sffc commented Sep 16, 2024

error: internal compiler error: compiler/rustc_traits/src/codegen.rs:44:13: Encountered error SignatureMismatch(SignatureMismatchData { found_trait_ref: <fn(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned) -> alloc::borrow::Cow<'_, frontend::Pattern<B>> {alloc::borrow::Cow::<'_, frontend::Pattern<B>>::Owned} as core::ops::FnOnce<(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned,)>>, expected_trait_ref: <fn(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned) -> alloc::borrow::Cow<'_, frontend::Pattern<B>> {alloc::borrow::Cow::<'_, frontend::Pattern<B>>::Owned} as core::ops::FnOnce<(alloc::boxed::Box<frontend::Pattern<B>>,)>>, terr: Sorts(ExpectedFound { expected: alloc::boxed::Box<frontend::Pattern<B/#2>, alloc::alloc::Global>, found: Alias(Projection, AliasTy { args: [frontend::Pattern<B/#2>], def_id: DefId(4:790 ~ alloc[a325]::borrow::ToOwned::Owned) }) }) }) selecting <fn(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned) -> alloc::borrow::Cow<'_, frontend::Pattern<B>> {alloc::borrow::Cow::<'_, frontend::Pattern<B>>::Owned} as core::ops::FnOnce<(alloc::boxed::Box<frontend::Pattern<B>>,)>> during codegen

thread 'rustc' panicked at compiler/rustc_traits/src/codegen.rs:44:13:
Box

sffc
sffc previously approved these changes Sep 17, 2024
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

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

LGTM up to this point

@sffc
Copy link
Member

sffc commented Sep 17, 2024

The ICE says:

found_trait_ref:

<fn(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned) -> alloc::borrow::Cow<'_, frontend::Pattern<B>> {alloc::borrow::Cow::<'_, frontend::Pattern<B>>::Owned} as core::ops::FnOnce<(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned,)>>

expected_trait_ref:

<fn(<frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned) -> alloc::borrow::Cow<'_, frontend::Pattern<B>> {alloc::borrow::Cow::<'_, frontend::Pattern<B>>::Owned} as core::ops::FnOnce<(alloc::boxed::Box<frontend::Pattern<B>>,)>>

So something about <frontend::Pattern<B> as alloc::borrow::ToOwned>::Owned not matching with alloc::boxed::Box<frontend::Pattern<B>> (even though they are the same type)

I see some HRTBs in this PR which probably doesn't help.

Also, this only happens in test-c and test-dart, which suggests a no_std-related issue (although for some reason it passes in other no_std tests).

Initial guess: what happens if you change the Pattern::from_ref_store_unchecked(B::empty()).to_owned() in impl Default to construct the box directly instead of trying to re-use impl ToOwned?

@sffc
Copy link
Member

sffc commented Sep 18, 2024

Oh I just noticed this in the error output, too

query stack during panic:
#0 [codegen_select_candidate] computing candidate for `<alloc::borrow::Cow<'_, frontend::Pattern<B>>::Owned as core::ops::function::FnOnce<(alloc::boxed::Box<frontend::Pattern<B>>,)>>`
#1 [resolve_instance] resolving instance `<alloc::borrow::Cow<'_, frontend::Pattern<B>>::Owned as core::ops::function::FnOnce<(alloc::boxed::Box<frontend::Pattern<B>>,)>>::call_once`
#2 [mir_callgraph_reachable] computing if `frontend::serde::deserialize_borrowed_cow::<'_, B, __D>` (transitively) calls `frontend::serde::deserialize_option_borrowed_cow::_::<impl at utils/pattern/src/frontend/serde.rs:20:14: 20:25>::deserialize`
#3 [optimized_mir] optimizing MIR for `frontend::serde::deserialize_option_borrowed_cow::_::<impl at utils/pattern/src/frontend/serde.rs:20:14: 20:25>::deserialize`
end of query stack

So it's in Serde deserialize_option_borrowed_cow. Maybe those two failing jobs are the only no_std + serde jobs.

sffc
sffc previously approved these changes Sep 18, 2024
@sffc
Copy link
Member

sffc commented Sep 18, 2024

@robertbastian ICE fixed. Ready to land?

@robertbastian
Copy link
Member Author

it's not pretty that you have to add the generics when using deserialize_option_borrowed_cow, but for now we can merge

@sffc
Copy link
Member

sffc commented Sep 18, 2024

it's not pretty that you have to add the generics when using deserialize_option_borrowed_cow, but for now we can merge

We switched from exercising one compiler bug to another. Adding the generics is required due to rust-lang/rust#130180 (see #5510 (comment))

@sffc
Copy link
Member

sffc commented Sep 18, 2024

The way to actually fix this, I think, is to introduce a new type such as ZeroCow that has all the correct impls, and then we won't need deserialize_with.

@robertbastian robertbastian merged commit 30d488e into unicode-org:main Sep 19, 2024
28 checks passed
@robertbastian robertbastian deleted the genericplurals branch September 19, 2024 08:15
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.

2 participants