Closed
Description
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
Labels
No labels