[rustmojo] Add skeleton for Mojom bindings user interface [chromium/src : main]

0 views
Skip to first unread message

Devon Loehr (Gerrit)

unread,
Dec 19, 2025, 5:37:17 PM (7 days ago) Dec 19
to Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
Attention needed from Daniel Cheng and Łukasz Anforowicz

New activity on the change

Open in Gerrit

Related details

Attention is currently required from:
  • Daniel Cheng
  • Łukasz Anforowicz
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
Gerrit-Change-Number: 7279160
Gerrit-PatchSet: 4
Gerrit-Owner: Devon Loehr <dlo...@google.com>
Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
Gerrit-CC: Julia Hansbrough <flowe...@google.com>
Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
Gerrit-Comment-Date: Fri, 19 Dec 2025 22:37:11 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Łukasz Anforowicz (Gerrit)

unread,
Dec 19, 2025, 6:57:15 PM (7 days ago) Dec 19
to Devon Loehr, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
Attention needed from Daniel Cheng and Devon Loehr

Łukasz Anforowicz added 14 comments

Patchset-level comments
File-level comment, Patchset 4 (Latest):
Łukasz Anforowicz . resolved

Very nice - thanks!

File mojo/public/rust/bindings/interface.rs
Line 29, Patchset 4 (Latest)://! fn Div(&mut self, dividend: i32, divisor: i32, response_callback: FnOnce(i32, i32));
Łukasz Anforowicz . unresolved

nit: `impl FnOnce(...)`, right? Or maybe `Box<dyn FnOnce(...)>`?

Can `response_callback` be called after `self` goes away? If not, then I wonder if the type of `response_callback` should refer to the lifetime of `self` (e.g. `FnOnce(...) + `a`).

Can `response_callback` be passed to another thread and then invoked from that other thread? If so, then maybe we should say `+ Send`?

Line 111, Patchset 4 (Latest)://! impl MathService for MathServiceImpl { ... }
Łukasz Anforowicz . unresolved

`SaturatingMathService`, right?

Line 125, Patchset 4 (Latest)://! // Undbing the receiver, getting the state object out
Łukasz Anforowicz . unresolved

Unbind?

Line 126, Patchset 4 (Latest)://! let (p_rec, final_count) = counting_receiver.unbind();
Łukasz Anforowicz . unresolved

Side-note: If this didn't return a **pair**, then I would suggest naming this `into_inner()`. But I think `unbind` is okay and better if we need to return both the inner impl + the strongly-typed pipe/pending-receiver.

Question: would it make sense to say `count_state` rather than `final_count` to signify that this is the same object that was created earlier on line 120?

Line 142, Patchset 4 (Latest):// rules and lack of support for multiple blanket implementations of a trait.
Łukasz Anforowicz . unresolved

Disclaimer: I think that a macro is a reasonable, clean solution to all of this (and it gives us a centralized point of control where we can potentially tweak things in the future if needed). But for completeness, let me try to see if there are other solutions to the problems listed here.

IIUC the `.mojom` => `.rs` generator will generate `trait MathService`. Is it allowed / would it work to have a blanket impl **there**?:

```
impl<T> MojoService for T where T: MojoService {}
```

Line 149, Patchset 4 (Latest):// `dyn SomeInterface` as the parameter to our objects, there's no way to specify
Łukasz Anforowicz . unresolved

Ack. I can't think of anything smart here. I wondered about using `T: !Sized` bound for `Remote`/`Received` (which any `dyn ...` would satisfy), but negative bounds are not supported. Maybe there are some hacks to make this work, but I think we should flush out this approach before (optionally) coming back to this later.

Line 160, Patchset 4 (Latest):// macro like they're supposed to), this ensures that the only valid parameters
Łukasz Anforowicz . unresolved

I wonder if we can:

* Define `trait UsedTheMacro` (name TBD) that is:
- internal (`mod internal`) and undocumented (doc hidden)
- Marked with [`diagnostic::on_unimplemented`](https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute) attribute so that when a user doesn't implement this hidden trait, then our error message wags a finger and says "please use the macro!".
* And then have our macro "automatically" impl this trait
Line 163, Patchset 4 (Latest):// FOR_RELEASE: This is a very clever solution, and possibly too clever. With
// good API design, we can probably make it impossible to construct a remote/
// receiver of the wrong type. But it's still not checked by the compiler, so
// that solution requires all future API designers to maintain the invariant.
Łukasz Anforowicz . unresolved

Meh... if it works, it works. But... we probably **should** try to solicit a review by people who are more familiar with Rust type system tricks. @manishearth may be a good start I think + is a Chromium committer.

Line 188, Patchset 4 (Latest): payload: Vec<u8>,
Łukasz Anforowicz . unresolved

`Rc<[u8]>` to indicate immutability. I forgot how to construct values of this type - I think there is a helper somewhere...

Line 212, Patchset 4 (Latest): fn dispatch_response(message: Message, response_callback: Self::CallbackTy);
Łukasz Anforowicz . unresolved

I don't understand the `response_callback` parameter. The map of response_id-to-resonse_callback will be maintained by a `Remote`, right? If so, then should this take `&mut self` as the first parameter instead of taking `response_callback`? But maybe I just need to wait for an implementation...

Line 248, Patchset 4 (Latest):pub trait SameTypeAs<T: ?Sized> {}
Łukasz Anforowicz . unresolved

A thought: can we compare `TypeId::of<T>()` as an alternative approach for checking type equality at compile time?

Line 296, Patchset 4 (Latest): pending_responses: std::collections::HashMap<u32, T::CallbackTy>,
Łukasz Anforowicz . unresolved

Would it simplify things if `pending_responses`:

  • Was a field of the `mojom`-generated struct instead?
  • Was split into multiple maps - one per method / per response callback type?

?

Line 366, Patchset 4 (Latest): fn new_with_runner(endpoint: MessageEndpoint, runner: SequencedTaskRunnerHandle) -> Self {
Łukasz Anforowicz . unresolved

I wonder if C++ checks that interface methods are called on the right sequence. And if so, then how we could duplicate this behavior.

Open in Gerrit

Related details

Attention is currently required from:
  • Daniel Cheng
  • Devon Loehr
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 4
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Devon Loehr <dlo...@google.com>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Fri, 19 Dec 2025 23:57:03 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Devon Loehr (Gerrit)

    unread,
    Dec 19, 2025, 7:39:09 PM (7 days ago) Dec 19
    to Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng and Łukasz Anforowicz

    Devon Loehr voted and added 12 comments

    Votes added by Devon Loehr

    Commit-Queue+1

    12 comments

    File mojo/public/rust/bindings/interface.rs
    Line 29, Patchset 4://! fn Div(&mut self, dividend: i32, divisor: i32, response_callback: FnOnce(i32, i32));
    Łukasz Anforowicz . resolved

    nit: `impl FnOnce(...)`, right? Or maybe `Box<dyn FnOnce(...)>`?

    Can `response_callback` be called after `self` goes away? If not, then I wonder if the type of `response_callback` should refer to the lifetime of `self` (e.g. `FnOnce(...) + `a`).

    Can `response_callback` be passed to another thread and then invoked from that other thread? If so, then maybe we should say `+ Send`?

    Devon Loehr

    I don't think it's related to `self` at all; adding `Send` makes sense, though.

    Line 111, Patchset 4://! impl MathService for MathServiceImpl { ... }
    Łukasz Anforowicz . resolved

    `SaturatingMathService`, right?

    Devon Loehr

    Done

    Line 125, Patchset 4://! // Undbing the receiver, getting the state object out
    Łukasz Anforowicz . resolved

    Unbind?

    Devon Loehr

    Done

    Line 126, Patchset 4://! let (p_rec, final_count) = counting_receiver.unbind();
    Łukasz Anforowicz . resolved

    Side-note: If this didn't return a **pair**, then I would suggest naming this `into_inner()`. But I think `unbind` is okay and better if we need to return both the inner impl + the strongly-typed pipe/pending-receiver.

    Question: would it make sense to say `count_state` rather than `final_count` to signify that this is the same object that was created earlier on line 120?

    Devon Loehr

    Yeah, I think the `bind`/`unbind` names are meaningful (they're not just data conversions) so I think we should consistently used them throughout.

    Changed the `final_count` name as suggested.

    Line 142, Patchset 4:// rules and lack of support for multiple blanket implementations of a trait.
    Łukasz Anforowicz . unresolved

    Disclaimer: I think that a macro is a reasonable, clean solution to all of this (and it gives us a centralized point of control where we can potentially tweak things in the future if needed). But for completeness, let me try to see if there are other solutions to the problems listed here.

    IIUC the `.mojom` => `.rs` generator will generate `trait MathService`. Is it allowed / would it work to have a blanket impl **there**?:

    ```
    impl<T> MojoService for T where T: MojoService {}
    ```

    Devon Loehr

    No; the problem is that we need to write
    ```
    impl<T> MojomInterface for T where T: MathService {}
    ```

    So the trait we're `impl`ing is `MojomInterface`, which we didn't define. And of course, `T` is arbitrary, so we don't control that either.

    Line 149, Patchset 4:// `dyn SomeInterface` as the parameter to our objects, there's no way to specify
    Łukasz Anforowicz . resolved

    Ack. I can't think of anything smart here. I wondered about using `T: !Sized` bound for `Remote`/`Received` (which any `dyn ...` would satisfy), but negative bounds are not supported. Maybe there are some hacks to make this work, but I think we should flush out this approach before (optionally) coming back to this later.

    Devon Loehr

    Even the `!Sized` bound wouldn't be enough because it might let you use the wrong `dyn`. I think the comment below about the "possibly-too-clever" solution is where this is really addressed.

    Line 160, Patchset 4:// macro like they're supposed to), this ensures that the only valid parameters
    Łukasz Anforowicz . resolved

    I wonder if we can:

    * Define `trait UsedTheMacro` (name TBD) that is:
    - internal (`mod internal`) and undocumented (doc hidden)
    - Marked with [`diagnostic::on_unimplemented`](https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute) attribute so that when a user doesn't implement this hidden trait, then our error message wags a finger and says "please use the macro!".
    * And then have our macro "automatically" impl this trait
    Devon Loehr

    Ah, I actually considered this exact thing, but I didn't know about that attribute. I thought that a trait named `YouNeedToUseTheMacro` was a little overkill, but if we can give a custom error message then that's a good idea. I'll look into it for a later CL.

    Line 188, Patchset 4: payload: Vec<u8>,
    Łukasz Anforowicz . resolved

    `Rc<[u8]>` to indicate immutability. I forgot how to construct values of this type - I think there is a helper somewhere...

    Devon Loehr

    I'm going to leave it for now because this is just a dummy type so I can write the rest of the interface; we can come back to this when we've got an actual message type in front of us.

    Line 212, Patchset 4: fn dispatch_response(message: Message, response_callback: Self::CallbackTy);
    Łukasz Anforowicz . unresolved

    I don't understand the `response_callback` parameter. The map of response_id-to-resonse_callback will be maintained by a `Remote`, right? If so, then should this take `&mut self` as the first parameter instead of taking `response_callback`? But maybe I just need to wait for an implementation...

    Devon Loehr
    Hopefully this will be clearer with the code (I only just realized we needed this myself). My intention is that the bindings will generate something like
    ```
    CallbackTy = enum {
    AddCallback(Box<dyn FnOnce(i32)>),
    DivCallback(Box<dyn FnOnce(i32, i32)>),
    }
    fn dispatch_response(message, callback) {
    match (message_ID, callback) {
    (ADD_ID, AddCallback(fun)) => fun(parse_add(message));
    (DIV_ID, DivCallback(fun)) => fun(parse_div(message));
    _ => panic!("Mismatched callback and message")
    }
    }
    ```

    The remote will just look up the stashed callback in its map, and pass it along. It can't actually deconstruct the callback type because this generic implementation doesn't know how many methods the associated interface will have.

    Line 248, Patchset 4:pub trait SameTypeAs<T: ?Sized> {}
    Łukasz Anforowicz . unresolved

    A thought: can we compare `TypeId::of<T>()` as an alternative approach for checking type equality at compile time?

    Devon Loehr

    Hmmm, maybe? I'm not sure if we can do that in "trait position" without doing something like this that uses a const generic instead of a type parameter.

    Line 296, Patchset 4: pending_responses: std::collections::HashMap<u32, T::CallbackTy>,
    Łukasz Anforowicz . unresolved

    Would it simplify things if `pending_responses`:

    • Was a field of the `mojom`-generated struct instead?
    • Was split into multiple maps - one per method / per response callback type?

    ?

    Devon Loehr

    I'm not sure what `mojom`-generated struct you're talking about -- I think that for `Remote` we don't end up generating any structs (but we'll do some `impls` for `dyn Whatever`).

    We could split it into multiple maps, but we'd have to do so dynamically, because `Remote<T>` doesn't know how many methods the associated interface has as long as `T` is generic.

    Line 366, Patchset 4: fn new_with_runner(endpoint: MessageEndpoint, runner: SequencedTaskRunnerHandle) -> Self {
    Łukasz Anforowicz . resolved

    I wonder if C++ checks that interface methods are called on the right sequence. And if so, then how we could duplicate this behavior.

    Devon Loehr

    I know C++ has a `DCHECK_CALLED_ON_VALID_SEQUENCE`, which seems to be the way they check this. I just filed b/470438844 which is related to this, so let's continue the discussion there.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Łukasz Anforowicz
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 5
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Sat, 20 Dec 2025 00:39:04 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Łukasz Anforowicz <luk...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Devon Loehr (Gerrit)

    unread,
    Dec 19, 2025, 7:40:05 PM (7 days ago) Dec 19
    to Manish Goregaokar, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng, Manish Goregaokar and Łukasz Anforowicz

    Devon Loehr added 1 comment

    File mojo/public/rust/bindings/interface.rs
    Line 163, Patchset 4:// FOR_RELEASE: This is a very clever solution, and possibly too clever. With

    // good API design, we can probably make it impossible to construct a remote/
    // receiver of the wrong type. But it's still not checked by the compiler, so
    // that solution requires all future API designers to maintain the invariant.
    Łukasz Anforowicz . unresolved

    Meh... if it works, it works. But... we probably **should** try to solicit a review by people who are more familiar with Rust type system tricks. @manishearth may be a good start I think + is a Chromium committer.

    Devon Loehr

    Sounds good - @manishearth, could you take a look at this trick to see if it makes sense/there's not a better way?

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Manish Goregaokar
    • Łukasz Anforowicz
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 6
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Manish Goregaokar <manis...@google.com>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Sat, 20 Dec 2025 00:39:58 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Łukasz Anforowicz <luk...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Manish Goregaokar (Gerrit)

    unread,
    Dec 19, 2025, 7:55:45 PM (7 days ago) Dec 19
    to Devon Loehr, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng, Devon Loehr and Łukasz Anforowicz

    Manish Goregaokar added 3 comments

    File mojo/public/rust/bindings/interface.rs
    Line 163, Patchset 4:// FOR_RELEASE: This is a very clever solution, and possibly too clever. With
    // good API design, we can probably make it impossible to construct a remote/
    // receiver of the wrong type. But it's still not checked by the compiler, so
    // that solution requires all future API designers to maintain the invariant.
    Łukasz Anforowicz . unresolved

    Meh... if it works, it works. But... we probably **should** try to solicit a review by people who are more familiar with Rust type system tricks. @manishearth may be a good start I think + is a Chromium committer.

    Devon Loehr

    Sounds good - @manishearth, could you take a look at this trick to see if it makes sense/there's not a better way?

    Manish Goregaokar

    I'm not really sure I understand this setup. Is this designed the way it is so that people can only write `Receiver<dyn Interface>` and not `Receiver<ConcreteType>`?

    You could potentially achieve that via a trait DynMojomInterface that is only implemented on `dyn Interface`. I think that might be cleaner? It would be better for docs, too, because you can have `T: DynMojomInterface` vs `T: MojomInterface` and they are both useful bounds meaning different things.

    Line 204, Patchset 6 (Latest): type DynTy: MojomInterface + ?Sized + SameTypeAs<Self::DynTy>;
    Manish Goregaokar . unresolved

    question: why is this SameTypeAs necessary? It feels like this will trivially always be true?

    Or is this to help other bounds assume it?

    Line 248, Patchset 4:pub trait SameTypeAs<T: ?Sized> {}
    Łukasz Anforowicz . unresolved

    A thought: can we compare `TypeId::of<T>()` as an alternative approach for checking type equality at compile time?

    Devon Loehr

    Hmmm, maybe? I'm not sure if we can do that in "trait position" without doing something like this that uses a const generic instead of a type parameter.

    Manish Goregaokar

    You can't, SameTypeAs is a useful trick, though most of the time you can avoid it in my experience.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Devon Loehr
    • Łukasz Anforowicz
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 6
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Devon Loehr <dlo...@google.com>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Sat, 20 Dec 2025 00:55:35 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Devon Loehr <dlo...@google.com>
    Comment-In-Reply-To: Łukasz Anforowicz <luk...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Devon Loehr (Gerrit)

    unread,
    Dec 19, 2025, 8:46:34 PM (7 days ago) Dec 19
    to Manish Goregaokar, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng, Manish Goregaokar and Łukasz Anforowicz

    Devon Loehr added 3 comments

    File mojo/public/rust/bindings/interface.rs
    Line 163, Patchset 4:// FOR_RELEASE: This is a very clever solution, and possibly too clever. With
    // good API design, we can probably make it impossible to construct a remote/
    // receiver of the wrong type. But it's still not checked by the compiler, so
    // that solution requires all future API designers to maintain the invariant.
    Łukasz Anforowicz . unresolved

    Meh... if it works, it works. But... we probably **should** try to solicit a review by people who are more familiar with Rust type system tricks. @manishearth may be a good start I think + is a Chromium committer.

    Devon Loehr

    Sounds good - @manishearth, could you take a look at this trick to see if it makes sense/there's not a better way?

    Manish Goregaokar

    I'm not really sure I understand this setup. Is this designed the way it is so that people can only write `Receiver<dyn Interface>` and not `Receiver<ConcreteType>`?

    You could potentially achieve that via a trait DynMojomInterface that is only implemented on `dyn Interface`. I think that might be cleaner? It would be better for docs, too, because you can have `T: DynMojomInterface` vs `T: MojomInterface` and they are both useful bounds meaning different things.

    Devon Loehr

    There are two reasons: first, we want to ensure that people only write `Remote<dyn SomeInterface>`, but we also want to make sure that they can't confuse `Remote<dyn SomeInterface>` and `Remote<dyn SomeOtherInterface>`. Implementing a marker trait only for `dyn Interface` would achieve the first, but it would (in theory) leave the door open for the second.

    In essence, what we really want to say is to parameterize on a trait, like `Remote<SomeInterface>`, for readability, consistency with C++, and to ensure that each `Remote/Receiver` pair is using the same interface. But since that's not allowed, we're using `dyn SomeInterface` instead of `Interface`, and this trickery is just to try to prevent people from writing other things in that position.

    Line 204, Patchset 6 (Latest): type DynTy: MojomInterface + ?Sized + SameTypeAs<Self::DynTy>;
    Manish Goregaokar . resolved

    question: why is this SameTypeAs necessary? It feels like this will trivially always be true?

    Or is this to help other bounds assume it?

    Devon Loehr

    Yes, it was to help later bounds assume it. That said, I don't think I ended up keeping any of the code that took advantage of it, so we can remove it.

    Line 248, Patchset 4:pub trait SameTypeAs<T: ?Sized> {}
    Łukasz Anforowicz . resolved

    A thought: can we compare `TypeId::of<T>()` as an alternative approach for checking type equality at compile time?

    Devon Loehr

    Hmmm, maybe? I'm not sure if we can do that in "trait position" without doing something like this that uses a const generic instead of a type parameter.

    Manish Goregaokar

    You can't, SameTypeAs is a useful trick, though most of the time you can avoid it in my experience.

    Devon Loehr

    Good to know, thanks!

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Manish Goregaokar
    • Łukasz Anforowicz
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 6
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Manish Goregaokar <manis...@google.com>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Sat, 20 Dec 2025 01:46:28 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Manish Goregaokar <manis...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Devon Loehr (Gerrit)

    unread,
    Dec 22, 2025, 1:16:59 PM (4 days ago) Dec 22
    to Manish Goregaokar, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng and Manish Goregaokar

    Devon Loehr added 1 comment

    File mojo/public/rust/bindings/interface.rs
    Line 160, Patchset 4:// macro like they're supposed to), this ensures that the only valid parameters
    Łukasz Anforowicz . resolved

    I wonder if we can:

    * Define `trait UsedTheMacro` (name TBD) that is:
    - internal (`mod internal`) and undocumented (doc hidden)
    - Marked with [`diagnostic::on_unimplemented`](https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute) attribute so that when a user doesn't implement this hidden trait, then our error message wags a finger and says "please use the macro!".
    * And then have our macro "automatically" impl this trait
    Devon Loehr

    Ah, I actually considered this exact thing, but I didn't know about that attribute. I thought that a trait named `YouNeedToUseTheMacro` was a little overkill, but if we can give a custom error message then that's a good idea. I'll look into it for a later CL.

    Devon Loehr

    Ah, unfortunately I think this doesn't quite work because we can't `impl UsedTheMacro for Remote<dyn MathInterface>` in the generated code, since it didn't define either `UsedTheMacro` or `Remote`. It's very close to working, so maybe I'll come up with a variant, but for now it doesn't seem possible.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Manish Goregaokar
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 8
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Manish Goregaokar <manis...@google.com>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Mon, 22 Dec 2025 18:16:53 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Devon Loehr (Gerrit)

    unread,
    Dec 22, 2025, 2:55:30 PM (4 days ago) Dec 22
    to Manish Goregaokar, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng and Manish Goregaokar

    Devon Loehr added 1 comment

    File mojo/public/rust/bindings/interface.rs
    Line 160, Patchset 4:// macro like they're supposed to), this ensures that the only valid parameters
    Łukasz Anforowicz . resolved

    I wonder if we can:

    * Define `trait UsedTheMacro` (name TBD) that is:
    - internal (`mod internal`) and undocumented (doc hidden)
    - Marked with [`diagnostic::on_unimplemented`](https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute) attribute so that when a user doesn't implement this hidden trait, then our error message wags a finger and says "please use the macro!".
    * And then have our macro "automatically" impl this trait
    Devon Loehr

    Ah, I actually considered this exact thing, but I didn't know about that attribute. I thought that a trait named `YouNeedToUseTheMacro` was a little overkill, but if we can give a custom error message then that's a good idea. I'll look into it for a later CL.

    Devon Loehr

    Ah, unfortunately I think this doesn't quite work because we can't `impl UsedTheMacro for Remote<dyn MathInterface>` in the generated code, since it didn't define either `UsedTheMacro` or `Remote`. It's very close to working, so maybe I'll come up with a variant, but for now it doesn't seem possible.

    Devon Loehr

    Ah ah, nevermind, I got this to work by using blanket `impl<T> for Remote<T>`, which is fine because users aren't implementing anything for `Remote`s, only for state objects.

    Gerrit-Comment-Date: Mon, 22 Dec 2025 19:55:24 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Manish Goregaokar (Gerrit)

    unread,
    Dec 22, 2025, 6:28:30 PM (4 days ago) Dec 22
    to Devon Loehr, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng and Devon Loehr

    Manish Goregaokar added 1 comment

    File mojo/public/rust/bindings/interface.rs
    Line 163, Patchset 4:// FOR_RELEASE: This is a very clever solution, and possibly too clever. With
    // good API design, we can probably make it impossible to construct a remote/
    // receiver of the wrong type. But it's still not checked by the compiler, so
    // that solution requires all future API designers to maintain the invariant.
    Łukasz Anforowicz . unresolved

    Meh... if it works, it works. But... we probably **should** try to solicit a review by people who are more familiar with Rust type system tricks. @manishearth may be a good start I think + is a Chromium committer.

    Devon Loehr

    Sounds good - @manishearth, could you take a look at this trick to see if it makes sense/there's not a better way?

    Manish Goregaokar

    I'm not really sure I understand this setup. Is this designed the way it is so that people can only write `Receiver<dyn Interface>` and not `Receiver<ConcreteType>`?

    You could potentially achieve that via a trait DynMojomInterface that is only implemented on `dyn Interface`. I think that might be cleaner? It would be better for docs, too, because you can have `T: DynMojomInterface` vs `T: MojomInterface` and they are both useful bounds meaning different things.

    Devon Loehr

    There are two reasons: first, we want to ensure that people only write `Remote<dyn SomeInterface>`, but we also want to make sure that they can't confuse `Remote<dyn SomeInterface>` and `Remote<dyn SomeOtherInterface>`. Implementing a marker trait only for `dyn Interface` would achieve the first, but it would (in theory) leave the door open for the second.

    In essence, what we really want to say is to parameterize on a trait, like `Remote<SomeInterface>`, for readability, consistency with C++, and to ensure that each `Remote/Receiver` pair is using the same interface. But since that's not allowed, we're using `dyn SomeInterface` instead of `Interface`, and this trickery is just to try to prevent people from writing other things in that position.

    Manish Goregaokar

    Hmmmm. Still not convinced you should ever need SameTypeAs, then.

    I think what you probably want is T: MojomInterface and T: DynMojomInterface, with MojomInterface having `type Dyn: DynMojomInterface` (and autogenerated with the macro). I think that would anyway be a more easier to understand refactor, docs wise.

    Then Remote<T> can have most methods be T: DynMojomInterace, and where you need to ensure the types are the same with Receiver, just use Receiver<T>.

    It's a bit hard for me to be sure without looking at something end-to-end, but I think `T: MojomInterface + SameTypeAs<T::DynTy>` is much more conveniently represented as DynMojomInterface

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Devon Loehr
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 9
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-Attention: Devon Loehr <dlo...@google.com>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Mon, 22 Dec 2025 23:28:20 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Manish Goregaokar <manis...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Devon Loehr (Gerrit)

    unread,
    Dec 23, 2025, 9:38:16 AM (4 days ago) Dec 23
    to Manish Goregaokar, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng, Manish Goregaokar and Łukasz Anforowicz

    Devon Loehr added 1 comment

    File mojo/public/rust/bindings/interface.rs
    Line 163, Patchset 4:// FOR_RELEASE: This is a very clever solution, and possibly too clever. With
    // good API design, we can probably make it impossible to construct a remote/
    // receiver of the wrong type. But it's still not checked by the compiler, so
    // that solution requires all future API designers to maintain the invariant.
    Łukasz Anforowicz . resolved

    Meh... if it works, it works. But... we probably **should** try to solicit a review by people who are more familiar with Rust type system tricks. @manishearth may be a good start I think + is a Chromium committer.

    Devon Loehr

    Sounds good - @manishearth, could you take a look at this trick to see if it makes sense/there's not a better way?

    Manish Goregaokar

    I'm not really sure I understand this setup. Is this designed the way it is so that people can only write `Receiver<dyn Interface>` and not `Receiver<ConcreteType>`?

    You could potentially achieve that via a trait DynMojomInterface that is only implemented on `dyn Interface`. I think that might be cleaner? It would be better for docs, too, because you can have `T: DynMojomInterface` vs `T: MojomInterface` and they are both useful bounds meaning different things.

    Devon Loehr

    There are two reasons: first, we want to ensure that people only write `Remote<dyn SomeInterface>`, but we also want to make sure that they can't confuse `Remote<dyn SomeInterface>` and `Remote<dyn SomeOtherInterface>`. Implementing a marker trait only for `dyn Interface` would achieve the first, but it would (in theory) leave the door open for the second.

    In essence, what we really want to say is to parameterize on a trait, like `Remote<SomeInterface>`, for readability, consistency with C++, and to ensure that each `Remote/Receiver` pair is using the same interface. But since that's not allowed, we're using `dyn SomeInterface` instead of `Interface`, and this trickery is just to try to prevent people from writing other things in that position.

    Manish Goregaokar

    Hmmmm. Still not convinced you should ever need SameTypeAs, then.

    I think what you probably want is T: MojomInterface and T: DynMojomInterface, with MojomInterface having `type Dyn: DynMojomInterface` (and autogenerated with the macro). I think that would anyway be a more easier to understand refactor, docs wise.

    Then Remote<T> can have most methods be T: DynMojomInterace, and where you need to ensure the types are the same with Receiver, just use Receiver<T>.

    It's a bit hard for me to be sure without looking at something end-to-end, but I think `T: MojomInterface + SameTypeAs<T::DynTy>` is much more conveniently represented as DynMojomInterface

    Devon Loehr

    You're right, I think the trick was realizing that you normally can't compare traits for equality (hence the `SameTypeAs` trick), but you _can_ do that for associated items. So we can write the comparison as `StateTy: MojomInterface<DynTy = T::DynTy>` and avoid all the boilerplate that comes from the new trait. Thanks!

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Manish Goregaokar
    • Łukasz Anforowicz
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
    Gerrit-Change-Number: 7279160
    Gerrit-PatchSet: 9
    Gerrit-Owner: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
    Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Julia Hansbrough <flowe...@google.com>
    Gerrit-CC: Manish Goregaokar <manis...@google.com>
    Gerrit-Attention: Manish Goregaokar <manis...@google.com>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
    Gerrit-Comment-Date: Tue, 23 Dec 2025 14:38:09 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Manish Goregaokar (Gerrit)

    unread,
    Dec 23, 2025, 11:48:17 AM (3 days ago) Dec 23
    to Devon Loehr, Łukasz Anforowicz, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
    Attention needed from Daniel Cheng, Devon Loehr and Łukasz Anforowicz

    Manish Goregaokar voted and added 1 comment

    Votes added by Manish Goregaokar

    Code-Review+1

    1 comment

    Patchset-level comments
    File-level comment, Patchset 10 (Latest):
    Manish Goregaokar . resolved

    This looks much easier to understand.

    I don't know enough about this setup to verify where we should be doing T: MojomInterface vs T: DynMojomInterface, someone should check that. But the model is much cleaner.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Cheng
    • Devon Loehr
    • Łukasz Anforowicz
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
      Gerrit-Change-Number: 7279160
      Gerrit-PatchSet: 10
      Gerrit-Owner: Devon Loehr <dlo...@google.com>
      Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
      Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
      Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
      Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
      Gerrit-CC: Julia Hansbrough <flowe...@google.com>
      Gerrit-Attention: Devon Loehr <dlo...@google.com>
      Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
      Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
      Gerrit-Comment-Date: Tue, 23 Dec 2025 16:48:04 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Łukasz Anforowicz (Gerrit)

      unread,
      Dec 23, 2025, 12:16:10 PM (3 days ago) Dec 23
      to Devon Loehr, Manish Goregaokar, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
      Attention needed from Daniel Cheng and Devon Loehr

      Łukasz Anforowicz voted and added 4 comments

      Votes added by Łukasz Anforowicz

      Code-Review+1

      4 comments

      File mojo/public/rust/bindings/interface.rs
      Line 142, Patchset 4:// rules and lack of support for multiple blanket implementations of a trait.
      Łukasz Anforowicz . resolved

      Disclaimer: I think that a macro is a reasonable, clean solution to all of this (and it gives us a centralized point of control where we can potentially tweak things in the future if needed). But for completeness, let me try to see if there are other solutions to the problems listed here.

      IIUC the `.mojom` => `.rs` generator will generate `trait MathService`. Is it allowed / would it work to have a blanket impl **there**?:

      ```
      impl<T> MojoService for T where T: MojoService {}
      ```

      Devon Loehr

      No; the problem is that we need to write
      ```
      impl<T> MojomInterface for T where T: MathService {}
      ```

      So the trait we're `impl`ing is `MojomInterface`, which we didn't define. And of course, `T` is arbitrary, so we don't control that either.

      Łukasz Anforowicz

      Acknowledged

      Line 212, Patchset 4: fn dispatch_response(message: Message, response_callback: Self::CallbackTy);
      Łukasz Anforowicz . resolved

      I don't understand the `response_callback` parameter. The map of response_id-to-resonse_callback will be maintained by a `Remote`, right? If so, then should this take `&mut self` as the first parameter instead of taking `response_callback`? But maybe I just need to wait for an implementation...

      Devon Loehr
      Hopefully this will be clearer with the code (I only just realized we needed this myself). My intention is that the bindings will generate something like
      ```
      CallbackTy = enum {
      AddCallback(Box<dyn FnOnce(i32)>),
      DivCallback(Box<dyn FnOnce(i32, i32)>),
      }
      fn dispatch_response(message, callback) {
      match (message_ID, callback) {
      (ADD_ID, AddCallback(fun)) => fun(parse_add(message));
      (DIV_ID, DivCallback(fun)) => fun(parse_div(message));
      _ => panic!("Mismatched callback and message")
      }
      }
      ```

      The remote will just look up the stashed callback in its map, and pass it along. It can't actually deconstruct the callback type because this generic implementation doesn't know how many methods the associated interface will have.

      Łukasz Anforowicz

      Acknowledged

      Line 296, Patchset 4: pending_responses: std::collections::HashMap<u32, T::CallbackTy>,
      Łukasz Anforowicz . resolved

      Would it simplify things if `pending_responses`:

      • Was a field of the `mojom`-generated struct instead?
      • Was split into multiple maps - one per method / per response callback type?

      ?

      Devon Loehr

      I'm not sure what `mojom`-generated struct you're talking about -- I think that for `Remote` we don't end up generating any structs (but we'll do some `impls` for `dyn Whatever`).

      We could split it into multiple maps, but we'd have to do so dynamically, because `Remote<T>` doesn't know how many methods the associated interface has as long as `T` is generic.

      Łukasz Anforowicz

      Acknowledged

      Line 422, Patchset 10 (Latest): // alias for `bind` and `unbind`, but I think it's better that binding is
      // explicit, since it's a stateful operation (not just converting data)
      Łukasz Anforowicz . resolved

      I agree that `bind` and `unbind` sound better.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Daniel Cheng
      • Devon Loehr
      Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement satisfiedCode-Owners
        • requirement satisfiedCode-Review
        • requirement satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
        Gerrit-Change-Number: 7279160
        Gerrit-PatchSet: 10
        Gerrit-Owner: Devon Loehr <dlo...@google.com>
        Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
        Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
        Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
        Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
        Gerrit-CC: Julia Hansbrough <flowe...@google.com>
        Gerrit-Attention: Devon Loehr <dlo...@google.com>
        Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
        Gerrit-Comment-Date: Tue, 23 Dec 2025 17:15:58 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes
        satisfied_requirement
        open
        diffy

        Daniel Cheng (Gerrit)

        unread,
        Dec 24, 2025, 8:35:42 PM (2 days ago) Dec 24
        to Devon Loehr, Łukasz Anforowicz, Manish Goregaokar, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
        Attention needed from Devon Loehr

        Daniel Cheng added 8 comments

        File mojo/public/rust/bindings/interface.rs
        Line 59, Patchset 10 (Latest)://! function on the remote object, and pass a callback specifying how to handle
        //! the response.
        Daniel Cheng . unresolved

        Technically this is optional. Not sure if that's important to mention here though.

        Line 102, Patchset 10 (Latest)://! declare_mojom_state_object!(CountingMathService, MathService);
        Daniel Cheng . unresolved

        I don't love this name.

        Line 130, Patchset 10 (Latest)://! Note that receivers can get receive messages while they are pending, but those
        Daniel Cheng . unresolved

        Nit: Remove "get" or "receive" here

        Line 145, Patchset 10 (Latest):// `MojomInterface` appropriately, and require uses to call it so the code is in
        Daniel Cheng . unresolved

        users?

        Line 204, Patchset 10 (Latest): type ResponseCallbackTy;
        Daniel Cheng . resolved

        In practice, this is a union of all callback types accepted by messages defined on this interface right?

        Line 319, Patchset 10 (Latest): /// This type represents one end of a Mojo pipe associated with a particular
        Daniel Cheng . unresolved

        I think we want to be careful about using the word "associated" in these docs. I noticed a few other instances. Unfortunately "associated" already has a meaning in mojo.

        I've seen the word "entangled" used for the two endpoints of a Mojo message pipe; the relationship between "message pipe" and "interface" is a bit murkier, since multiple interfaces can be multiplexed on the same message pipe (via the magic of associated interfaces); in the context of 'associated interfaces', I think the original one is the 'primary interface'.

        Line 422, Patchset 10 (Latest): // alias for `bind` and `unbind`, but I think it's better that binding is
        // explicit, since it's a stateful operation (not just converting data)
        Łukasz Anforowicz . resolved

        I agree that `bind` and `unbind` sound better.

        Daniel Cheng

        +1

        Line 543, Patchset 10 (Latest): pub fn unbind(self) -> (PendingReceiver<StateTy::DynTy>, StateTy) {
        Daniel Cheng . unresolved

        Honestly it's a bit of a dangerous method. I wonder if we should just avoid adding this for now; it's not very commonly used I think.

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Devon Loehr
        Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement satisfiedCode-Owners
          • requirement satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement satisfiedReview-Enforcement
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: chromium/src
          Gerrit-Branch: main
          Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
          Gerrit-Change-Number: 7279160
          Gerrit-PatchSet: 10
          Gerrit-Owner: Devon Loehr <dlo...@google.com>
          Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
          Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
          Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
          Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
          Gerrit-CC: Julia Hansbrough <flowe...@google.com>
          Gerrit-Attention: Devon Loehr <dlo...@google.com>
          Gerrit-Comment-Date: Thu, 25 Dec 2025 01:35:28 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          Comment-In-Reply-To: Łukasz Anforowicz <luk...@chromium.org>
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Devon Loehr (Gerrit)

          unread,
          10:02 AM (13 hours ago) 10:02 AM
          to Łukasz Anforowicz, Manish Goregaokar, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
          Attention needed from Daniel Cheng

          Devon Loehr added 7 comments

          Patchset-level comments
          Devon Loehr . unresolved

          @dcheng: Thanks for taking a look, please also note the naming scheme of Remotes/Receivers, where every type except `Receiver` takes a `dyn` type and `Receiver` takes a concrete type.

          I'm still on the fence about whether it's cleaner for `Receiver` to take an (additional, useless) `dyn` type for consistency and searchability. I worry that it's obnoxious and will lead to people immediately aliasing the type to something even less searchable, which is probably what I'd do in that situation. I implemented it without the extra type, but it's not hard to add it if you still feel strongly that we should.

          File mojo/public/rust/bindings/interface.rs
          Line 59, Patchset 10 (Latest)://! function on the remote object, and pass a callback specifying how to handle
          //! the response.
          Daniel Cheng . resolved

          Technically this is optional. Not sure if that's important to mention here though.

          Devon Loehr

          Acknowledged

          Line 102, Patchset 10 (Latest)://! declare_mojom_state_object!(CountingMathService, MathService);
          Daniel Cheng . unresolved

          I don't love this name.

          Devon Loehr

          Me neither; I've changed it several times. Tried once more, let me know what you think.

          Line 130, Patchset 10 (Latest)://! Note that receivers can get receive messages while they are pending, but those
          Daniel Cheng . resolved

          Nit: Remove "get" or "receive" here

          Devon Loehr

          Done

          Line 145, Patchset 10 (Latest):// `MojomInterface` appropriately, and require uses to call it so the code is in
          Daniel Cheng . resolved

          users?

          Devon Loehr

          Done

          Line 319, Patchset 10 (Latest): /// This type represents one end of a Mojo pipe associated with a particular
          Daniel Cheng . resolved

          I think we want to be careful about using the word "associated" in these docs. I noticed a few other instances. Unfortunately "associated" already has a meaning in mojo.

          I've seen the word "entangled" used for the two endpoints of a Mojo message pipe; the relationship between "message pipe" and "interface" is a bit murkier, since multiple interfaces can be multiplexed on the same message pipe (via the magic of associated interfaces); in the context of 'associated interfaces', I think the original one is the 'primary interface'.

          Devon Loehr

          Fair enough, I went through and reworded things (mostly replacing with `engtangled with` or `corresponding to`)

          Line 543, Patchset 10 (Latest): pub fn unbind(self) -> (PendingReceiver<StateTy::DynTy>, StateTy) {
          Daniel Cheng . resolved

          Honestly it's a bit of a dangerous method. I wonder if we should just avoid adding this for now; it's not very commonly used I think.

          Devon Loehr

          I want to have it here demonstrate its type signature, so I just made it private and left a note.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Daniel Cheng
          Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement satisfiedCode-Owners
          • requirement satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement satisfiedReview-Enforcement
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: chromium/src
          Gerrit-Branch: main
          Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
          Gerrit-Change-Number: 7279160
          Gerrit-PatchSet: 10
          Gerrit-Owner: Devon Loehr <dlo...@google.com>
          Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
          Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
          Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
          Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
          Gerrit-CC: Julia Hansbrough <flowe...@google.com>
          Gerrit-Attention: Daniel Cheng <dch...@chromium.org>
          Gerrit-Comment-Date: Fri, 26 Dec 2025 15:01:38 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          Comment-In-Reply-To: Daniel Cheng <dch...@chromium.org>
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Daniel Cheng (Gerrit)

          unread,
          8:34 PM (3 hours ago) 8:34 PM
          to Devon Loehr, Łukasz Anforowicz, Manish Goregaokar, Daniel Cheng, Julia Hansbrough, Chromium LUCI CQ, chromium...@chromium.org
          Attention needed from Devon Loehr

          Daniel Cheng added 2 comments

          Patchset-level comments
          Devon Loehr . unresolved

          @dcheng: Thanks for taking a look, please also note the naming scheme of Remotes/Receivers, where every type except `Receiver` takes a `dyn` type and `Receiver` takes a concrete type.

          I'm still on the fence about whether it's cleaner for `Receiver` to take an (additional, useless) `dyn` type for consistency and searchability. I worry that it's obnoxious and will lead to people immediately aliasing the type to something even less searchable, which is probably what I'd do in that situation. I implemented it without the extra type, but it's not hard to add it if you still feel strongly that we should.

          Daniel Cheng

          1. How will people answer the question for "who listens to messages for this interface"?
          2. I think we should explain the technical reason for this limitation in comments if we absolutely can't work around it.

          Daniel Cheng . resolved

          Looks like the latest patchset might not be uploaded yet?

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Devon Loehr
          Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement satisfiedCode-Owners
          • requirement satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement satisfiedReview-Enforcement
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: chromium/src
          Gerrit-Branch: main
          Gerrit-Change-Id: I5285c9b018a5ac71fc534ed91754c2647a6485f8
          Gerrit-Change-Number: 7279160
          Gerrit-PatchSet: 10
          Gerrit-Owner: Devon Loehr <dlo...@google.com>
          Gerrit-Reviewer: Daniel Cheng <dch...@chromium.org>
          Gerrit-Reviewer: Devon Loehr <dlo...@google.com>
          Gerrit-Reviewer: Manish Goregaokar <manis...@google.com>
          Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
          Gerrit-CC: Julia Hansbrough <flowe...@google.com>
          Gerrit-Attention: Devon Loehr <dlo...@google.com>
          Gerrit-Comment-Date: Sat, 27 Dec 2025 01:34:12 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          Comment-In-Reply-To: Devon Loehr <dlo...@google.com>
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy
          Reply all
          Reply to author
          Forward
          0 new messages