Why does "default-features=false" not work

I run examples in rustls with default-features=false of rustls dep and enable the feature ring in rustls package. but it seems like the default feature aws_lc_rs of rustls package doesn't disabled.

examples/Cargo.toml

[dependencies]
rustls = { path = "../rustls", default-features = false, features = [
  "ring",
  "logging",
] }

rustls/Cargo.toml

[features]
default = ["aws_lc_rs", "logging", "std", "tls12"]
std = ["webpki/std", "pki-types/std", "once_cell/std"]
logging = ["log"]
aws_lc_rs = ["dep:aws-lc-rs", "webpki/aws_lc_rs"]
aws-lc-rs = ["aws_lc_rs"]                                 # Alias because Cargo features commonly use `-`
brotli = ["dep:brotli", "dep:brotli-decompressor", "std"]
ring = ["dep:ring", "webpki/ring"]
custom-provider = []
tls12 = []
read_buf = ["rustversion", "std"]
fips = ["aws_lc_rs", "aws-lc-rs?/fips"]
zlib = ["dep:zlib-rs"]

How are you determining if the feature gets disabled? All features will show up in the Cargo.lock

1 Like

You can use

cargo tree -e features

to see which dependencies enable what features.

Features are unified across the entire dependency tree. The common cause of problems is other dependencies including the same crate with the default features enabled.

2 Likes

There is function in rustls lib, if ring and aws_lc_rs all are enabled, it will return None

    /// Returns a provider named unambiguously by rustls crate features.
    ///
    /// This function returns `None` if the crate features are ambiguous (ie, specify two
    /// providers), or specify no providers, or the feature `custom-provider` is activated.
    /// In all cases the application should explicitly specify the provider to use
    /// with [`CryptoProvider::install_default`].
    fn from_crate_features() -> Option<Self> {
        #[cfg(all(
            feature = "ring",
            not(feature = "aws_lc_rs"),
            not(feature = "custom-provider")
        ))]
        {
            return Some(ring::default_provider());
        }

        #[cfg(all(
            feature = "aws_lc_rs",
            not(feature = "ring"),
            not(feature = "custom-provider")
        ))]
        {
            return Some(aws_lc_rs::default_provider());
        }

        #[allow(unreachable_code)]
        None
    }

I'm not sure if other dependencies including the same crate with the default features enabled.
But when I remove "aws_lc_rs" in features.default in rustls/Cargo.toml, aws_lc_rs is disabled.