jonhoo / fantoccini

A high-level API for programmatically interacting with web pages through WebDriver.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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?

@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 !