What's happening here? (fantoccini breaks String + &String)
tomaspecl opened this issue · comments
For some reason when I put fantoccini in my project then every operation like String + &String
will fail to compile. It will break in every file in that project, even if I use fantoccini
only in one file.
I am running cargo 1.65.0 (4bc8f24d3 2022-10-20) on my windows machine.
Here is the minimal code that causes problems:
/* in Cargo.toml:
[package]
name = "fantoccini_test"
version = "0.1.0"
edition = "2021"
[dependencies]
fantoccini = "0.19.3"
*/
//use fantoccini; //uncomment me and it wont compile!
fn main() {
let mut a = String::new();
a += &String::new(); //the trait `AddAssign<&String>` is not implemented for `String`
}
Cargo output with cargo build
:
Compiling fantoccini_test v0.1.0 (C:\Users\PC\Desktop\fantoccini test)
warning: unused import: `fantoccini`
--> src\main.rs:9:5
|
9 | use fantoccini; //uncomment me and it wont compile!
| ^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: cannot add-assign `&String` to `String`
--> src\main.rs:12:7
|
12 | a += &String::new(); //the trait `AddAssign<&String>` is not implemented for `String`
| ^^ no implementation for `String += &String`
|
= help: the trait `AddAssign<&String>` is not implemented for `String`
= help: the following other types implement trait `AddAssign<Rhs>`:
<String as AddAssign<&str>>
<String as AddAssign<Key>>
For more information about this error, try `rustc --explain E0277`.
warning: `fantoccini_test` (bin "fantoccini_test") generated 1 warning
error: could not compile `fantoccini_test` due to previous error; 1 warning emitted
Am I just missing something or is this completely wierd and broken?
I found something relevant here:
https://std-dev-guide.rust-lang.org/code-considerations/breaking-changes/new-trait-impls.html#deref-coercion-breaks-when-a-new-impl-is-introduced
It is caused by your
impl Add<Key> for String {
type Output = String;
fn add(mut self, rhs: Key) -> Self::Output {
self.push(rhs.into());
self
}
}
impl AddAssign<Key> for String {
fn add_assign(&mut self, rhs: Key) {
self.push(rhs.into());
}
}
That's very suspicious, and I think it should be reported upstream. Those docs are specifically for the standard library, not for crate authors, and this is certainly a footgun if it applies to all crates!
cc @stevepryde as this was introduced in #151. We could totally remove these impls as they haven't been made part of a stable release yet, though that would also hurt the ergonomics of Key
a fair amount.
I added a note in rust-lang/rust#51916
Yeah that's unfortunate. I think it's better to take a small drop in ergonomics than potentially break other code just by importing fantoccini.
I'm inclined to agree. Let's remove the impls for now 👍 We could perhaps add a helper method like Key::and
?
Hello I have an idea how to make it work and still be quite ergonomic:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cd64fbcedcdc4e446a64d7f1c8616d43
@jonhoo should I do a pull request or will you (or @stevepryde ) do it?
It's pretty weird to have to add those &
in there, but maybe that's the best we can do for now. We should call it out in the docs for Key
explicitly at least.
Feel free to open a PR, that'll probably be faster!
@jonhoo can this be closed?
Ah, yes, closed by #198 !