Skip to content

E0507 could perhaps suggest fixing subsequent uses if it changes T to &T #106882

@matthiaskrgr

Description

@matthiaskrgr

Code

use std::any::TypeId;
use std::collections::HashMap;
use std::hash::Hash;

trait State {
    type EventType;
    fn get_type_id_of_state(&self) -> TypeId;
}

struct StateMachine<EventType: Hash + Eq> {
    current_state: Box<dyn State<EventType = EventType>>,
    transition_table:
        HashMap<TypeId, HashMap<EventType, fn() -> Box<dyn State<EventType = EventType>>>>,
}

impl<EventType: Hash + Eq> StateMachine<EventType> {
    fn inner_process_event(&mut self, event: EventType) -> Result<(), i8> {
        let new_state_creation_function = self
            .transition_table
            .iter()
            .find(|(&event_typeid, _)| event_typeid == self.current_state.get_type_id_of_state())
            .ok_or(1)?
            .1
            .iter()
            .find(|(&event_type, _)| event == event_type)
            //~^ ERROR cannot move out of a shared reference
            .ok_or(2)?
            .1;

        self.current_state = new_state_creation_function();
        Ok(())
    }
}

fn main() {}

Current output

error[E0507]: cannot move out of a shared reference
  --> src/lib.rs:25:20
   |
25 |             .find(|(&event_type, _)| event == event_type)
   |                    ^^----------^^^^
   |                      |
   |                      data moved here
   |                      move occurs because `event_type` has type `EventType`, which does not implement the `Copy` trait
   |
help: consider borrowing the pattern binding
   |
25 |             .find(|(&ref event_type, _)| event == event_type)
   |                      +++

For more information about this error, try `rustc --explain E0507`.

Desired output

help: consider borrowing the pattern binding
   |
25 |             .find(|(&ref event_type, _)| event == *event_type)
   |                      +++                          +

Rationale and extra context

Applying the suggestion will cause type mismatch in event == event_type, so perhaps rust could suggest borrowing/dereferencing automatically to fix that?

error[E0308]: mismatched types
  --> src/lib.rs:25:51
   |
16 | impl<EventType: Hash + Eq> StateMachine<EventType> {
   |      --------- this type parameter
...
25 |             .find(|(&ref event_type, _)| event == event_type)
   |                                          -----    ^^^^^^^^^^ expected type parameter `EventType`, found `&EventType`
   |                                          |
   |                                          expected because this is `EventType`
   |
   = note: expected type parameter `EventType`
                   found reference `&EventType`

For more information about this error, try `rustc --explain E0308`.

Other cases

No response

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions