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

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

Closed
AbdouSeck opened this issue Jun 14, 2019 · 4 comments
Closed

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

AbdouSeck opened this issue Jun 14, 2019 · 4 comments

Comments

@AbdouSeck
Copy link

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

@ehuss
Copy link
Contributor

ehuss commented Jun 14, 2019

The default edition in rustc is 2015. New cargo projects default to 2018. 2018 now uses non-lexical lifetimes. rustc 1.36 (beta) will also use NLL in the 2015 edition, but the versions you have do not.

If you want to use the rustc command line, pass --edition=2018.

@AbdouSeck
Copy link
Author

AbdouSeck commented Jun 15, 2019

@ehuss Thank you! That's definitely something I missed. I will use the information to see how it applies to my code.

@estebank
Copy link
Contributor

@AbdouSeck filed #61914 for a more holistic approach to these kind of edition discrepancies. This particular problem will go away once we enable NLL in 2015 edition, but the general problem of discrepancies between editions not being explained when encountered are a paper cut that needs fixing.

@AbdouSeck
Copy link
Author

@estebank Thanks for making that clear. Please don't hesitate to ask if I can be of any help; especially with documentation. It may take me a little bit to navigate and fully understand the structure of the project though. So, any guidance will be appreciated.

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

3 participants