fn new()

in tools/hakari/src/hakari.rs [830:988]


    fn new(builder: &'b HakariBuilder<'g>) -> Self {
        // This was just None or All for a bit under the theory that feature sets are additive only,
        // but unfortunately we cannot exploit this property because it doesn't account for the fact
        // that some dependencies might not be built *at all*, under certain feature combinations.
        //
        // That's also why we simulate builds with and without dev-only dependencies in all cases.
        //
        // For example, for:
        //
        // ```toml
        // [dependencies]
        // dep = { version = "1", optional = true }
        //
        // [dev-dependencies]
        // dep = { version = "1", optional = true, features = ["dev-feature"] }
        //
        // [features]
        // default = ["dep"]
        // extra = ["dep/extra", "dep/dev-feature"]
        // ```
        //
        // | feature set | include dev | dep status         |
        // | ----------- | ----------- | ------------------ |
        // | none        | no          | not built          |
        // | none        | yes         | not built          |
        // | default     | no          | no features        |
        // | default     | yes         | dev-feature        |
        // | all         | no          | extra, dev-feature |
        // | all         | yes         | extra, dev-feature |
        //
        // (And there's further complexity possible with transitive deps as well.)
        let features_include_dev = [
            (StandardFeatures::None, false),
            (StandardFeatures::None, true),
            (StandardFeatures::Default, false),
            (StandardFeatures::Default, true),
            (StandardFeatures::All, false),
            (StandardFeatures::All, true),
        ];

        // Features for the "always" platform spec.
        let always_features = features_include_dev
            .iter()
            .map(|&(features, include_dev)| (None, PlatformSpec::Always, features, include_dev));

        // Features for specified platforms.
        let specified_features =
            features_include_dev
                .iter()
                .flat_map(|&(features, include_dev)| {
                    builder
                        .platforms
                        .iter()
                        .enumerate()
                        .map(move |(idx, platform)| {
                            (
                                Some(idx),
                                PlatformSpec::Platform(platform.clone()),
                                features,
                                include_dev,
                            )
                        })
                });
        let platforms_features: Vec<_> = always_features.chain(specified_features).collect();

        let workspace = builder.graph.workspace();
        let excludes = builder.make_traversal_excludes();
        let features_only = builder.make_features_only();
        let excludes_ref = &excludes;
        let features_only_ref = &features_only;

        let computed_map: ComputedMap<'g> = platforms_features
            .into_par_iter()
            // The cargo_set computation in the inner iterator is the most expensive part of the
            // process, so use flat_map instead of flat_map_iter.
            .flat_map(|(idx, platform_spec, feature_filter, include_dev)| {
                let mut cargo_options = CargoOptions::new();
                cargo_options
                    .set_include_dev(include_dev)
                    .set_resolver(builder.resolver)
                    .set_platform(platform_spec)
                    .add_omitted_packages(excludes.iter());

                workspace.par_iter().map(move |workspace_package| {
                    if excludes_ref.is_excluded(workspace_package.id()) {
                        // Skip this package since it was excluded during traversal.
                        return BTreeMap::new();
                    }

                    let initials = workspace_package
                        .to_package_set()
                        .to_feature_set(feature_filter);
                    let cargo_set =
                        CargoSet::new(initials, features_only_ref.clone(), &cargo_options)
                            .expect("cargo resolution should succeed");

                    let all_features = cargo_set.all_features();

                    let values = all_features.iter().flat_map(|&(build_platform, features)| {
                        features
                            .packages_with_features(DependencyDirection::Forward)
                            .filter_map(move |feature_list| {
                                let dep = feature_list.package();
                                if dep.in_workspace() {
                                    // Only looking at third-party packages for hakari.
                                    return None;
                                }

                                let features: BTreeSet<&'g str> =
                                    feature_list.named_features().collect();
                                Some((
                                    idx,
                                    build_platform,
                                    dep.id(),
                                    features,
                                    workspace_package,
                                    feature_filter,
                                    include_dev,
                                ))
                            })
                    });

                    let mut map = ComputedMap::new();
                    for (
                        platform_idx,
                        build_platform,
                        package_id,
                        features,
                        package,
                        feature_filter,
                        include_dev,
                    ) in values
                    {
                        // Accumulate the features and package for each key.
                        map.entry((platform_idx, package_id)).or_default().insert(
                            build_platform,
                            features,
                            package,
                            feature_filter,
                            include_dev,
                        );
                    }

                    map
                })
            })
            .reduce(ComputedMap::new, |mut acc, map| {
                // Accumulate across all threads.
                for (k, v) in map {
                    acc.entry(k).or_default().merge(v);
                }
                acc
            });

        Self {
            excludes,
            computed_map,
        }
    }