I have what seems to be a simple struct where I implement the Default trait:
#[derive(Debug, PartialEq)]
pub enum AuthenticationType {
Trust,
AuthenticationCleartextPassword,
AuthenticationMD5Password,
AuthenticationSASL,
}
#[derive(Debug)]
pub struct Configuration {
user: String,
password: Option<String>,
dbname: Option<String>,
hostaddr: SocketAddr,
authentication_type: AuthenticationType,
}
impl Configuration {
pub fn new(user: String, password: Option<String>, dbname: Option<String>, hostaddr: SocketAddr, authentication_type: AuthenticationType) -> Self {
Configuration {
user,
password,
dbname,
hostaddr,
authentication_type,
}
}
}
impl Default for Configuration {
fn default() -> Self {
Configuration {
hostaddr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5432),
authentication_type: AuthenticationType::Trust,
..Default::default()
}
}
}
and a test for the default method that causes a stack overflow:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_configuration() {
let configuration = Configuration::default();
//assert_eq!(configuration.authentication_type, AuthenticationType::Trust);
}
}
Using VSCode to step into the default method I get an EXC_BAD_ACCESS
when ..Default::default()
is called.
I'm sure I'm missing something obvious but can't figure out what it is?
impl Default for Configuration {
fn default() -> Self {
Configuration {
hostaddr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5432),
authentication_type: AuthenticationType::Trust,
..Default::default()
}
}
}
In the above code Default::default()
has an inferred return type of Configuration, because the ..
syntax indicates that you want to use the field values specified and the field values from a value of type Configuration
.
Since Default::default()
has an inferred return type of Configuration
, it calls the default
implementation for Configuration
, which results in infinite recursion.
The infinite recursion results in a stackoverflow which manifests as accessing invalid memory off the end of the stack, resulting in EXC_BAD_ACCESS
.