Wado

WEP: Default Trait

Context

Many types have a natural "zero value" or "empty value" — 0 for integers, "" for strings, [] for arrays. A Default trait provides a uniform interface for obtaining these values, enabling generic code to construct default instances without knowing the concrete type.

Rust's Default trait has proven valuable for:

Decision

Trait Definition

Default is a trait in core:prelude with a single static method:

#[comp_feature("default")]
pub trait Default {
    fn default() -> Self;
}

The #[comp_feature("default")] attribute allows the compiler to reference this trait internally (e.g., for serde deserialization of optional fields).

No Compiler Synthesis

Unlike Serialize/Deserialize, there is no compiler-synthesized implementation for Default. Users must write impl Default for MyType manually. This keeps the feature simple and explicit — the user always controls what the default value is.

Standard Library Implementations

The following types implement Default in the standard library:

Type default()
i8, i16, i32, i64 0
u8, u16, u32, u64 0
i128, u128 0
f32, f64 0.0
bool false
char '\0'
String ""
List<T> []
Option<T> null
TreeMap<K, V> {}

Result<T, E> does not implement Default because there is no obvious choice between Ok and Err.

Usage

// Direct usage
let n = i32::default();       // 0
let s = String::default();    // ""

// In generic code
fn make_default<T: Default>() -> T {
    return T::default();
}

let x = make_default::<i32>();      // 0
let arr = make_default::<List<String>>();  // []

// User-defined types
struct Config {
    host: String,
    port: i32,
    debug: bool,
}

impl Default for Config {
    fn default() -> Config {
        return Config {
            host: "localhost",
            port: 8080,
            debug: false,
        };
    }
}

let config = Config::default();

Compiler Usage via comp_feature

The #[comp_feature("default")] attribute registers Default in the compiler's TypeTable, allowing internal passes to:

This does not auto-derive Default for any type — it only makes the trait visible to the compiler.

Consequences