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

Fix Option<&str> == Option<&String> build error when using rust_decimal/rkyv feature #11205

Merged
merged 1 commit into from
Dec 2, 2023

Conversation

dtolnay
Copy link
Contributor

@dtolnay dtolnay commented Dec 2, 2023

Without this change, projects which depend on both nu-command and rust_decimal's "rkyv" feature cause nu-command to fail to compile.

[dependencies]
nu-command = { path = "../nushell/crates/nu-command" }
rust_decimal = { version = "1", features = ["rkyv"] }
error[E0277]: can't compare `std::option::Option<&str>` with `std::option::Option<&std::string::String>`
   --> nushell/crates/nu-command/src/filters/join.rs:367:35
    |
367 |         let k_shared = shared_key == Some(k);
    |                                   ^^ no implementation for `std::option::Option<&str> == std::option::Option<&std::string::String>`
    |
    = help: the trait `PartialEq<std::option::Option<&std::string::String>>` is not implemented for `std::option::Option<&str>`
    = help: the following other types implement trait `PartialEq<Rhs>`:
              <std::option::Option<Box<U>> as PartialEq<rkyv::niche::option_box::ArchivedOptionBox<T>>>
              <std::option::Option<T> as PartialEq>
              <std::option::Option<U> as PartialEq<rkyv::option::ArchivedOption<T>>>

For more information about this error, try `rustc --explain E0277`.
warning: `nu-command` (lib) generated 1 warning
error: could not compile `nu-command` (lib) due to previous error; 1 warning emitted

Copy link
Contributor

@AucaCoyan AucaCoyan left a comment

Choose a reason for hiding this comment

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

This looks all good, thanks!

@sholderbach
Copy link
Member

The change making this explicitly symmetrical sounds good.

Surprised that this is the only place in the code base where this PartialEq type coercion problem pops up.

= help: the trait `PartialEq<std::option::Option<&std::string::String>>` is not implemented for `std::option::Option<&str>`
    = help: the following other types implement trait `PartialEq<Rhs>`:
              <std::option::Option<Box<U>> as PartialEq<rkyv::niche::option_box::ArchivedOptionBox<T>>>
              <std::option::Option<T> as PartialEq>
              <std::option::Option<U> as PartialEq<rkyv::option::ArchivedOption<T>>>

Do I read that message correctly that if those other types are not visible (we don't use them) the T in impl PartialEq<Option<T>> for Option<T> takes impl PartialEq<String> for str.

@sholderbach sholderbach merged commit 5d28375 into nushell:main Dec 2, 2023
19 checks passed
@dtolnay dtolnay deleted the rkyv branch December 2, 2023 18:09
@dtolnay
Copy link
Contributor Author

dtolnay commented Dec 2, 2023

The standard PartialEq impl for Option only applies to Option<T> == Option<T>. There is never a situation in which impl PartialEq<String> for str would come into play.

@sholderbach
Copy link
Member

sholderbach commented Dec 2, 2023

I am even more confused how this compiled fine before but not with rkyv. But my understanding of Deref coercion outside fns with specified target types is not really principled and more a gut feeling.

There is never a situation in which impl PartialEq<String> for str would come into play.

Right, T in a generic may be opaque but always a single concrete type.

@dtolnay
Copy link
Contributor Author

dtolnay commented Dec 2, 2023

shared_key's type is Option<&str>. If the 2 non-standard-library PartialEq impls shown in the error message (PartialEq<ArchivedOption<T>>, PartialEq<ArchivedOptionBox<T>> are not part of the program, then the unique impl which could apply in shared_key == ?? is PartialEq<Option<&str>>. So shared_key == Some(k) coerces k (which is &String) to &str using Deref coercion.

When there are other possible PartialEq impls that could apply, the coercion won't happen.

@dtolnay
Copy link
Contributor Author

dtolnay commented Dec 2, 2023

FYI @djkoloski. I am not familiar with rkyv so I don't know what impact on the API this would have, but I would recommend looking into removing the PartialEq impls linked above if possible. See also serde-rs/json#380 — we have found that PartialEq in this direction (standard_type == my_type) causes more problems than they are worth.

hardfau1t pushed a commit to hardfau1t/nushell that referenced this pull request Dec 14, 2023
…ell#11205)

Without this change, projects which depend on both nu-command and
rust_decimal's "rkyv" feature cause nu-command to fail to compile.

```toml
[dependencies]
nu-command = { path = "../nushell/crates/nu-command" }
rust_decimal = { version = "1", features = ["rkyv"] }
```

```console
error[E0277]: can't compare `std::option::Option<&str>` with `std::option::Option<&std::string::String>`
   --> nushell/crates/nu-command/src/filters/join.rs:367:35
    |
367 |         let k_shared = shared_key == Some(k);
    |                                   ^^ no implementation for `std::option::Option<&str> == std::option::Option<&std::string::String>`
    |
    = help: the trait `PartialEq<std::option::Option<&std::string::String>>` is not implemented for `std::option::Option<&str>`
    = help: the following other types implement trait `PartialEq<Rhs>`:
              <std::option::Option<Box<U>> as PartialEq<rkyv::niche::option_box::ArchivedOptionBox<T>>>
              <std::option::Option<T> as PartialEq>
              <std::option::Option<U> as PartialEq<rkyv::option::ArchivedOption<T>>>

For more information about this error, try `rustc --explain E0277`.
warning: `nu-command` (lib) generated 1 warning
error: could not compile `nu-command` (lib) due to previous error; 1 warning emitted
```
dmatos2012 pushed a commit to dmatos2012/nushell that referenced this pull request Feb 20, 2024
…ell#11205)

Without this change, projects which depend on both nu-command and
rust_decimal's "rkyv" feature cause nu-command to fail to compile.

```toml
[dependencies]
nu-command = { path = "../nushell/crates/nu-command" }
rust_decimal = { version = "1", features = ["rkyv"] }
```

```console
error[E0277]: can't compare `std::option::Option<&str>` with `std::option::Option<&std::string::String>`
   --> nushell/crates/nu-command/src/filters/join.rs:367:35
    |
367 |         let k_shared = shared_key == Some(k);
    |                                   ^^ no implementation for `std::option::Option<&str> == std::option::Option<&std::string::String>`
    |
    = help: the trait `PartialEq<std::option::Option<&std::string::String>>` is not implemented for `std::option::Option<&str>`
    = help: the following other types implement trait `PartialEq<Rhs>`:
              <std::option::Option<Box<U>> as PartialEq<rkyv::niche::option_box::ArchivedOptionBox<T>>>
              <std::option::Option<T> as PartialEq>
              <std::option::Option<U> as PartialEq<rkyv::option::ArchivedOption<T>>>

For more information about this error, try `rustc --explain E0277`.
warning: `nu-command` (lib) generated 1 warning
error: could not compile `nu-command` (lib) due to previous error; 1 warning emitted
```
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.

None yet

3 participants