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

Possible regression on use of Self in generics ("mismatched types") #69611

Closed
rye opened this issue Mar 1, 2020 · 3 comments
Closed

Possible regression on use of Self in generics ("mismatched types") #69611

rye opened this issue Mar 1, 2020 · 3 comments

Comments

@rye
Copy link
Contributor

rye commented Mar 1, 2020

The following code (also on playground) compiles fine on Stable and Beta rustc, but has started no longer compiling on latest nightly (2020-02-28, 2020-02-29 both have this issue).

pub struct Container<V>(pub V);

impl<T, V> core::ops::Mul<T> for Container<V>
where
    T: From<V> + core::ops::Mul<T, Output = T>,
{
    type Output = Container<T>;

    fn mul(self, scalar: T) -> Self::Output {
        Self(scalar * self.0.into())
    }
}

I would expect this code snippet to compile with no errors as it currently does in stable and beta Rust.

Instead, on recent nightlies (02-28 and 02-29 were tested), an error is produced:

  --> src/lib.rs:10:14
   |
3  | impl<T, V> core::ops::Mul<T> for Container<V>
   |      -  - expected type parameter
   |      |
   |      found type parameter
...
10 |         Self(scalar * self.0.into())
   |              ^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `V`, found type parameter `T`
   |
   = note: expected type parameter `V`
              found type parameter `T`
   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

For what it's worth, the substitution

 pub struct Container<V>(pub V);

 impl<T, V> core::ops::Mul<T> for Container<V>
 where
     T: From<V> + core::ops::Mul<T, Output = T>,
 {
     type Output = Container<T>;
 
     fn mul(self, scalar: T) -> Self::Output {
-        Self(scalar * self.0.into())
+        Container(scalar * self.0.into())
     }
 }

resolves the error.

I believe this is because rustc is erroneously picking Self to be Container<V> (the type for which the impl is being specified) instead of using Container and inferring the (formerly correct) output type of Container<T>.

Meta

rustc --version --verbose:

rustc 1.43.0-nightly (d3c79346a 2020-02-29)
binary: rustc
commit-hash: d3c79346a3e7ddbb5fb417810f226ac5a9209007
commit-date: 2020-02-29
host: x86_64-apple-darwin
release: 1.43.0-nightly
LLVM version: 9.0
@rye rye added the C-bug Category: This is a bug. label Mar 1, 2020
@rye
Copy link
Contributor Author

rye commented Mar 1, 2020

Sure enough, this seems related to #69306, which was marked resolved by PR #69340. I guess I'm one of the lucky people affected by those changes. 😄

@Centril
Copy link
Contributor

Centril commented Mar 1, 2020

Yeah, this was caused by a bug fix to type checking of Self paths, which would previously wrongly introduce inference variables for type parameters in the impl. Using Self should always refer to the Self type, just as using Self {...} would. In other words, your code should never have compiled.

@Centril Centril removed the C-bug Category: This is a bug. label Mar 2, 2020
@Centril
Copy link
Contributor

Centril commented Mar 18, 2020

Closing as expected breakage and "wontfix".

@Centril Centril closed this as completed Mar 18, 2020
rye added a commit to rye/motion-planning that referenced this issue Mar 20, 2020
See rust-lang/rust#69611.

This is necessary because

> Using `Self` should always refer to the `Self` type, just as using
> `Self {...}` would. In other words, your code should never have
> compiled.

This'll fix the recurring build failure on nightly Rusts.

Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com>
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

No branches or pull requests

2 participants