Skip to content

Register trait improvements #463

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

Closed
wants to merge 14 commits into from

Conversation

couchand
Copy link
Contributor

@couchand couchand commented Aug 6, 2020

Shuffling around type and trait definitions with the goal of improving the generated API & documentation. Some highlights:

  • Moves relevant trait impls from register type alias to register spec ZST, which fixes Awkward to write code generic over registers #459 and improves documentation output.
  • Removes internal use of register type alias in favor of transparent usage of Reg<..>. While the type alias is convenient, it hides critical implementation details.
  • Wraps register reader/writer and field readers in newtype wrappers, which significantly improves the documentation output.

My testing so far has been admittedly much too limited given the scope of the changes. However, for the binaries I've checked, the assembly output is identical before and after these changes, suggesting that they are all indeed only type-level cleanup. I've also not run into any examples of user code breakage, despite the public API changes (though I would not be suprised to find some). Spot checking with scd2rust-regress has found no issues so far.

Some notable design decisions worth discussing:

  • The register spec ZST becomes much more important, so I've renamed it to remove the leading underscore. To avoid conflicting with the register type alias, I've moved it into the register module. Should the name have a suffix? Should it be located in the parent module alongside the (now less-important) type alias?
  • I've removed internal use (notably on generated RegisterBlocks) of the register type alias, as I think it adds a speed bump to understanding how the generated code works. Should the alias continue to be used there instead?
  • If breaking changes were on the table, I'd suggest changing the API of Reg::write. Requiring the closure to return the input doesn't seem like the right thing to do. It sows doubt about how exactly the changes propagate, and it makes one-liners slightly shorter at the expense of making multi-line closures an extra line.

Some documentation highlights:

  • Boolean readers now show accessor options directly.
    svd2rust-bool-field

  • Field readers and writers show bits accessors.
    svd2rust-reg-reader
    svd2rust-reg-writer-2

  • Generic R type doesn't show every specific type's impls.
    svd2rust-generic-r-impls

@couchand couchand requested a review from a team as a code owner August 6, 2020 19:50
@rust-highfive
Copy link

r? @reitermarkus

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-tools labels Aug 6, 2020
@couchand couchand force-pushed the 202008/register-traits branch from ed5e817 to 6afe71a Compare August 6, 2020 19:54
@couchand
Copy link
Contributor Author

couchand commented Aug 6, 2020

@therealprof tagging you since you commented on #459.

@burrbull tagging you because I was inspired by a number of your ideas in https://github.com/rust-embedded/svd2rust/blob/pa-traits/pa/src/lib.rs

@couchand
Copy link
Contributor Author

couchand commented Aug 6, 2020

Well I'll be. Some architectures have registers named R. That sure throws a wrench in my naming scheme. I'm open to any suggestions.

@burrbull
Copy link
Member

burrbull commented Aug 6, 2020

I see 3 big changes in your PR. Can you split them in different PRs, please? If it is possible. I will try to review tomorrow.

@couchand
Copy link
Contributor Author

couchand commented Aug 7, 2020

Closing in favor of #464, #465, and #466.

@couchand couchand closed this Aug 7, 2020
bors bot added a commit that referenced this pull request Aug 7, 2020
464: Register spec & traits r=therealprof a=couchand

Part 1 of #463.

- Publishes the register spec zero-sized type and moves all relevant register traits to that struct, which fixes #459 and improves generated documentation.
- Removes the extra type parameter on `Reg`, making the register spec the sole authority on the shape of the register (but not its address).

One thing that's changed since the previous PR, this renames the spec struct so that it won't cause a conflict on NXP, Freescale, and possibly other architectures.  I've gone with `register::REGISTER_SPEC` since that seems reasonably clear and I can't think of how it would cause a conflict (but I'm ready to be proven wrong since I've tried several ideas only to be stymied by various architectures' oddball register naming patterns).

I'd prefer the spec to be in the parent module, but I can't come up with a way to do that which guarantees that the generated code will be free from naming conflicts.  This seems good enough, plus it maintains the rule that when we make up a name it belongs in the child mod (except for `RegisterBlock`).

There is potential for breaking changes here, though the impact seems pretty minimal.  Specifically:
- If users referred to the traits in `mod generic`, their usage would break.  Writing code referring to those traits was previously pretty awkward (see #463), and this PR makes such usage much more ergonomic, so it would seem to be a net benefit.
- If users named the full reader/writer incantation the reference would break.  It doesn't seem users are likely to name the readers/writers at all, but if they do it seems very likely they would use the type alias.
- If users named the previously `#[docs(hidden)] ` spec struct the reference would break.  I don't see why they would have done so.
- If users patched something in to the generated module with the same name as our new register spec, it would break.  That case seems highly unlikely.

r? @burrbull 

Co-authored-by: Andrew Dona-Couch <[email protected]>
bors bot added a commit that referenced this pull request Aug 7, 2020
466: Avoid register type aliases r=therealprof a=couchand

Part 3 of #463, builds on #465.

- Removes generated use of the register type aliases in favor of directly referencing `Reg<REGISTER_SPEC>`.  I think this helps clarify how the generated and generic types work together.

No breaking change concerns on this change set.

r? @burrbull 

Co-authored-by: Andrew Dona-Couch <[email protected]>
bors bot added a commit that referenced this pull request Aug 8, 2020
465: Accessor newtypes r=therealprof a=couchand

Part 2 of #463, builds on #464.

- Wraps register reader/writer and field readers in newtype wrappers, which significantly improves the documentation output.

Again there's some minor potential for breaking changes:

- If users named the complete type of the previous type alias, it would break.  It seems more likely that they would use the alias, which will silently upgrade to a reference to the newtype.

r? @burrbull 

Co-authored-by: Andrew Dona-Couch <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-tools
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Awkward to write code generic over registers
4 participants