Skip to content

Order of operands to equality expression matters when inferring a AsRef implementation #23762

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

Open
shepmaster opened this issue Mar 26, 2015 · 4 comments
Labels
A-inference Area: Type inference A-type-system Area: Type system C-bug Category: This is a bug. I-needs-decision Issue: In need of a decision. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@shepmaster
Copy link
Member

This may be related to or the same as #23673, but I wanted to file it anyway as it seems to have a slightly different flavor.

#![feature(convert)]

struct Container {
    i: u8,
    b: bool,
}

impl AsRef<u8> for Container {
    fn as_ref(&self) -> &u8 {
        &self.i
    }
}

// A second implementation to make the `as_ref` ambiguous without further information
impl AsRef<bool> for Container {
    fn as_ref(&self) -> &bool {
        &self.b
    }
}

fn main() {
    let c = Container { i: 42, b: true };

    // Succeeds
    &42u8 == c.as_ref();

    // Fails
    c.as_ref() == &42u8;
}

Fails with

type annotations required: cannot resolve `Container : core::convert::AsRef<_>` [E0283]

However, if you flip the order of the arguments to the equality operator, then the code compiles and the correct type is inferred. It seems as if both forms should work the same.

Originally from this Stack Overflow question

@steveklabnik steveklabnik added the A-type-system Area: Type system label Mar 27, 2015
@hawkw
Copy link
Contributor

hawkw commented Apr 12, 2015

I've seen what (appears to be) a similar issue when trying to use as_ref() in a pattern guard expression.

@brson
Copy link
Contributor

brson commented Dec 1, 2016

Still repros.

@brson brson added I-needs-decision Issue: In need of a decision. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 1, 2016
@Mark-Simulacrum Mark-Simulacrum added A-inference Area: Type inference C-bug Category: This is a bug. labels Jul 22, 2017
@steveklabnik
Copy link
Member

Triage: still reproduces

error[E0283]: type annotations needed for `Container`
  --> src/main.rs:28:7
   |
22 |     let c = Container { i: 42, b: true };
   |         - consider giving `c` a type
...
28 |     c.as_ref() == &42u8;
   |       ^^^^^^ cannot infer type for struct `Container`
   |
   = note: cannot resolve `Container: std::convert::AsRef<_>`

@fmease fmease added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Dec 21, 2024
@krinistof
Copy link

Although the compiler emits a helpful message, this issue is still reproducible.

error[E0283]: type annotations needed
  --> test.rs:27:7
   |
27 |     c.as_ref() == &42u8;
   |       ^^^^^^
   |
note: multiple `impl`s satisfying `Container: AsRef<_>` found
  --> test.rs:7:1
   |
7  | impl AsRef<u8> for Container {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
14 | impl AsRef<bool> for Container {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: try using a fully qualified path to specify the expected types
   |
27 -     c.as_ref() == &42u8;
27 +     <Container as AsRef<T>>::as_ref(&c) == &42u8;
   |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference A-type-system Area: Type system C-bug Category: This is a bug. I-needs-decision Issue: In need of a decision. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants