Skip to content

error[E0506] when using rustc but passes with cargo #61855

Closed
@AbdouSeck

Description

@AbdouSeck

I am sorry if this turns out to be a duplicate, or an issue directly related with some other issue. I am relatively new to the language.

The following (also linked here) will compile just fine with cargo run or cargo build. However, when compiled with rustc, I get a compile error:

Code:

// A Person struct with name, age and health status
#[derive(Debug)]
struct Person {
    /// Name of the person
    name: String,
    /// Age of the person
    age: u32,
    /// The health status of the person
    status: Status,
}

// Create a constructor for the Person struct
impl Person {
    fn new(n: String, a: u32, s: Status) -> Self {
        Person {
            name: n,
            age: a,
            status: s,
        }
    }
}

// A Disease struct with symptoms, curability and medication information
#[derive(Debug)]
struct Disease {
    /// Whether or not the disease is curable
    curable: bool,
    /// A list of symptoms
    symptoms: Vec<String>,
    /// The recommended medication
    medication: String,
}

// Make a constructor for the Disease struct
impl Disease {
    fn new(curable: bool, symptoms: Vec<String>, medication: String) -> Self {
        Disease {
            curable,
            symptoms,
            medication,
        }
    }
}

// Enum with 2 variants: Healthy and Sick
#[derive(Debug)]
enum Status {
    /// Variant indicating that the person is healthy
    Healthy,
    /// Variant indicating that the person is sick
    Sick(Vec<Disease>),
}

// Trait for the current status of a person's health
trait Sick {
    /// Return the diseases someone has, if any.
    /// A None is returned if someone is not sick
    fn sickness(&self) -> Option<&Vec<Disease>>;
    /// Check whether or not someone is sick
    fn is_sick(&self) -> bool;
    /// Make someone sick by adding the provided
    /// disease to their list of diseases
    fn sicken(&mut self, d: Disease);
}

// Implement the Sick trait for Person
impl Sick for Person {
    fn sickness(&self) -> Option<&Vec<Disease>> {
        match &self.status {
            Status::Healthy => None,
            Status::Sick(d) => Some(d),
        }
    }
    fn is_sick(&self) -> bool {
        self.sickness().is_some()
    }
    fn sicken(&mut self, d: Disease) {
        match &mut self.status {
            Status::Healthy => {
                self.status = Status::Sick(vec![d])
            },
            Status::Sick(diseases) => {
                diseases.push(d);
            }
        }
    }
}

// Bring everything together
fn main() {
    // Let there be healthy Mireille
    let mut p = Person::new(String::from("Mireille"), 45, Status::Healthy);
    println!("{:#?}", p.sickness());
    println!("{}", p.is_sick());
    // Make up some disease
    let d = Disease::new(
        true,
        vec![String::from("Sore throat")],
        String::from("Sleep"),
    );
    // Infect Mireille with it
    p.sicken(d);
    // Make another one
    let d = Disease::new(
        true,
        vec![String::from("Headache")],
        String::from("Aspirin"),
    );
    // Sicken her even more
    p.sicken(d);
    // Check for diseases
    println!("{:#?}", p.sickness().unwrap());
}

Error with rustc:

error[E0506]: cannot assign to `self.status` because it is borrowed
  --> sicklies.rs:80:17
   |
78 |         match &mut self.status {
   |                    ----------- borrow of `self.status` occurs here
79 |             Status::Healthy => {
80 |                 self.status = Status::Sick(vec![d])
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.status` occurs here

I have, quite frankly, come to terms with the fact that the borrow checker is right about the error here. self.status is mutably borrowed at match &mut self.status; so reassigning it with the line self.status = Status::Sick(vec![d]) should trigger an error. Hence, I see that error by directly invoking rustc. Not seeing the same error with cargo has me confused.

Summary:

  • Doesn't compile in:
rustc 1.34.2 (6c2484dc3 2019-05-13)
binary: rustc
commit-hash: 6c2484dc3c532c052f159264e970278d8b77cdc9
commit-date: 2019-05-13
host: x86_64-apple-darwin
release: 1.34.2
LLVM version: 8.0

or

rustc 1.34.1 (fc50f328b 2019-04-24)
binary: rustc
commit-hash: fc50f328b0353b285421b8ff5d4100966387a997
commit-date: 2019-04-24
host: x86_64-unknown-linux-gnu
release: 1.34.1
LLVM version: 8.0

or

rustc 1.33.0 (2aa4c46cf 2019-02-28)
binary: rustc
commit-hash: 2aa4c46cfdd726e97360c2734835aa3515e8c858
commit-date: 2019-02-28
host: x86_64-unknown-linux-gnu
release: 1.33.0
LLVM version: 8.0
  • But compiles with:
cargo 1.33.0 (f099fe94b 2019-02-12)
release: 1.33.0
commit-hash: f099fe94b66f0a2f80370be8f2d3db2a55b97050
commit-date: 2019-02-12

and

cargo 1.34.0 (6789d8a0a 2019-04-01)
release: 1.34.0
commit-hash: 6789d8a0a54a96d95365c4e1fb01d47a5eed9937
commit-date: 2019-04-01

Questions:
Is this a bug or am I missing something?

Thank you,

Abdou

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions