Commit graph

7 commits

Author SHA1 Message Date
Martin von Zweigbergk
8ce099470b cargo: explicitly indicate paths to publish
Running `cargo publish` from a non-colocated repo (such as my usual
repo) is currently quite scary because it uploads all non-hidden
files, even if they're ignored by `.gitignore`
(https://github.com/rust-lang/cargo/issues/2063). I noticed this a
while ago and have always run the command from a fresh clone since
then. To avoid the need for that, let's use the workaround mentioned
on the bug, which is to explicitly list patterns we want to publish.
2024-04-15 20:37:00 -07:00
Martin von Zweigbergk
955c9bf27b jj-lib-proc-macros: add missing LICENSE file
We publish this crate on crates.io, so it should have a LICENSE file.
2024-04-15 20:37:00 -07:00
Martin von Zweigbergk
5ce5022ee9 cargo: mark the jj-lib-proc-macros crate for publish
I don't think we can publish a new version of the other crates without
publishing `jj-lib-proc-macros`.
2024-03-06 20:35:38 -08:00
Evan Mesterhazy
79518eafce Output better error messages when deriving ContentHash for an enum fails
Consider this code:
```
struct NoContentHash {}

#[derive(ContentHash)]
enum Hashable {
    NoCanHash(NoContentHash),
    Empty,
}
```

Before this commit, it generates an error like this:
```
error[E0277]: the trait bound `NoContentHash: ContentHash` is not satisfied
   --> lib/src/content_hash.rs:150:10
    |
150 | #[derive(ContentHash)]
    |          ^^^^^^^^^^^ the trait `ContentHash` is not implemented for `NoContentHash`
151 | enum Hashable {
152 |     NoCanHash(NoContentHash),
    |     --------- required by a bound introduced by this call
    |
    = help: the following other types implement trait `ContentHash`:
              bool
              i32
              i64
              u8
              u32
              u64
              std::collections::HashMap<K, V>
              BTreeMap<K, V>
            and 35 others

For more information about this error, try `rustc --explain E0277`.
```

After this commit, it generates a better error message:
```
error[E0277]: the trait bound `NoContentHash: ContentHash` is not satisfied
   --> lib/src/content_hash.rs:152:15
    |
152 |     NoCanHash(NoContentHash),
    |               ^^^^^^^^^^^^^ the trait `ContentHash` is not implemented for `NoContentHash`
    |
    = help: the following other types implement trait `ContentHash`:
              bool
              i32
              i64
              u8
              u32
              u64
              std::collections::HashMap<K, V>
              BTreeMap<K, V>
            and 35 others

For more information about this error, try `rustc --explain E0277`.
error: could not compile `jj-lib` (lib) due to 1 previous error
```

It also works for enum variants with named fields:
```
error[E0277]: the trait bound `NoContentHash: ContentHash` is not satisfied
   --> lib/src/content_hash.rs:152:23
    |
152 |     NoCanHash { named: NoContentHash },
    |                       ^^^^^^^^^^^^^ the trait `ContentHash` is not implemented for `NoContentHash`
    |
    = help: the following other types implement trait `ContentHash`:
              bool
              i32
              i64
              u8
              u32
              u64
              std::collections::HashMap<K, V>
              BTreeMap<K, V>
            and 35 others

For more information about this error, try `rustc --explain E0277`.
```
2024-02-20 16:29:25 -05:00
Evan Mesterhazy
966a5505e2 Add support for deriving ContentHash for Enums
Here's an example of what the derived output looks like for an enum:

```rust
pub enum TreeValue {
    File { id: FileId, executable: bool },
    Symlink(SymlinkId),
    Tree(TreeId),
    GitSubmodule(CommitId),
    Conflict(ConflictId),
}
#[automatically_derived]
impl ::jj_lib::content_hash::ContentHash for TreeValue {
    fn hash(&self, state: &mut impl digest::Update) {
        match self {
            Self::File { id, executable } => {
                state.update(&0u32.to_le_bytes());
                ::jj_lib::content_hash::ContentHash::hash(id, state);
                ::jj_lib::content_hash::ContentHash::hash(executable, state);
            }
            Self::Symlink(field_0) => {
                state.update(&1u32.to_le_bytes());
                ::jj_lib::content_hash::ContentHash::hash(field_0, state);
            }
            Self::Tree(field_0) => {
                state.update(&2u32.to_le_bytes());
                ::jj_lib::content_hash::ContentHash::hash(field_0, state);
            }
            Self::GitSubmodule(field_0) => {
                state.update(&3u32.to_le_bytes());
                ::jj_lib::content_hash::ContentHash::hash(field_0, state);
            }
            Self::Conflict(field_0) => {
                state.update(&4u32.to_le_bytes());
                ::jj_lib::content_hash::ContentHash::hash(field_0, state);
            }
        }
    }
}
```


#3054
2024-02-20 12:59:35 -05:00
Evan Mesterhazy
8e1a6c708f Add support for generics to #[derive(ContentHash)]
#3054
2024-02-20 12:48:25 -05:00
Evan Mesterhazy
965d6ce4e4 Implement a procedural macro to derive the ContentHash trait for structs
This is a no-op in terms of function, but provides a nicer way to derive the
ContentHash trait for structs using the `#[derive(ContentHash)]` syntax used
for other traits such as `Debug`.

This commit only adds the macro. A subsequent commit will replace uses of
`content_hash!{}` with `#[derive(ContentHash)]`.

The new macro generates nice error messages, just like the old macro:

```
error[E0277]: the trait bound `NotImplemented: content_hash::ContentHash` is not satisfied
   --> lib/src/content_hash.rs:265:16
    |
265 |             z: NotImplemented,
    |                ^^^^^^^^^^^^^^ the trait `content_hash::ContentHash` is not implemented for `NotImplemented`
    |
    = help: the following other types implement trait `content_hash::ContentHash`:
              bool
              i32
              i64
              u8
              u32
              u64
              std::collections::HashMap<K, V>
              BTreeMap<K, V>
            and 38 others
```

This commit does two things to make proc macros re-exported by jj_lib useable
by deps:

1. jj_lib needs to be able refer to itself as `jj_lib` which it does
   by adding an `extern crate self as jj_lib` declaration.

2. jj_lib::content_hash needs to re-export the `digest::Update` type so that
   users of jj_lib can use the `#[derive(ContentHash)]` proc macro without
   directly depending on the digest crate. This is done by re-exporting it
   as `DigestUpdate`.


#3054
2024-02-20 11:29:05 -05:00