fn resolve_requirements()

in src/resolver.rs [890:954]


fn resolve_requirements(
    graph: &DepGraph<'_>,
    policy: &Policy,
    criteria_mapper: &CriteriaMapper,
) -> Vec<CriteriaSet> {
    let _resolve_requirements = trace_span!("resolve_requirements").entered();

    let mut requirements = vec![criteria_mapper.no_criteria(); graph.nodes.len()];

    // For any packages which have dev-dependencies, apply policy-specified
    // dependency-criteria or dev-criteria to those dependencies.
    for package in &graph.nodes {
        if package.dev_deps.is_empty() {
            continue;
        }

        let policy = policy.get(package.name, &package.version);
        let dev_criteria = if let Some(c) = policy.and_then(|p| p.dev_criteria.as_ref()) {
            criteria_mapper.criteria_from_list(c)
        } else {
            criteria_mapper.criteria_from_list([format::DEFAULT_POLICY_DEV_CRITERIA])
        };

        for &depidx in &package.dev_deps {
            let dep_package = &graph.nodes[depidx];
            let dependency_criteria = policy
                .and_then(|policy| policy.dependency_criteria.get(dep_package.name))
                .map(|criteria| criteria_mapper.criteria_from_list(criteria));
            requirements[depidx]
                .unioned_with(dependency_criteria.as_ref().unwrap_or(&dev_criteria));
        }
    }

    // Walk the topo graph in reverse, so that we visit each package before any
    // dependencies.
    for &pkgidx in graph.topo_index.iter().rev() {
        let package = &graph.nodes[pkgidx];
        let policy = policy.get(package.name, &package.version);

        if let Some(c) = policy.and_then(|p| p.criteria.as_ref()) {
            // If we specify a policy on ourselves, override any requirements we've
            // had placed on us by reverse-dependencies.
            requirements[pkgidx] = criteria_mapper.criteria_from_list(c);
        } else if package.is_root {
            // If this is a root crate, it will require at least
            // `DEFAULT_POLICY_CRITERIA` by default, unless overridden.
            requirements[pkgidx].unioned_with(
                &criteria_mapper.criteria_from_list([format::DEFAULT_POLICY_CRITERIA]),
            );
        }
        let normal_criteria = requirements[pkgidx].clone();

        // For each dependency, elaborate the dependency criteria from the configured policy and add it to the dependency requirements.
        for &depidx in &package.normal_and_build_deps {
            let dep_package = &graph.nodes[depidx];
            let dependency_criteria = policy
                .and_then(|policy| policy.dependency_criteria.get(dep_package.name))
                .map(|criteria| criteria_mapper.criteria_from_list(criteria));
            requirements[depidx]
                .unioned_with(dependency_criteria.as_ref().unwrap_or(&normal_criteria));
        }
    }

    requirements
}