pub fn set_features_only<'b>(
        &mut self,
        workspace_names: impl IntoIterator<Item = &'b str>,
        features: StandardFeatures,
    ) -> Result<&mut Self, guppy::Error> {
        let old_workspace = self.old.workspace();
        let mut old_names = vec![];
        let new_names: Vec<_> = workspace_names
            .into_iter()
            .inspect(|&name| {
                if old_workspace.contains_name(name) {
                    old_names.push(name);
                }
            })
            .collect();

        // Missing package name in new workspace => error.
        let new_features_only = self
            .new
            .resolve_workspace_names(new_names)?
            .to_feature_set(features);
        let old_features_only = self
            .old
            .resolve_workspace_names(old_names)
            .expect("old names were checked already")
            .to_feature_set(features);

        self.new_features_only = Some(new_features_only);
        self.old_features_only = Some(old_features_only);
        Ok(self)
    }
Configures features-only packages that are used in build simulations.

The packages and features will be used for feature unification. This is useful for
pseudo-packages or workspace-hack packages, including those generated by tools like
[Hakari](https://docs.rs/hakari).

For more about `features_only`, see the documentation for [`CargoSet::new`](CargoSet::new).

The package names are expected to be present in the new graph, but may not be present in the
old `PackageGraph`.
* If a package name isn't in the *new* graph, this method returns an error.
* If a package name isn't in the *old* graph, it is ignored.
tools/determinator/src/determinator.rs