Skip to content

Add resolver opt-in for new feature resolver. #8129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions crates/cargo-test-support/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,27 @@ impl Package {
}

fn make_archive(&self) {
let dst = self.archive_dst();
t!(fs::create_dir_all(dst.parent().unwrap()));
let f = t!(File::create(&dst));
let mut a = Builder::new(GzEncoder::new(f, Compression::default()));

if !self.files.iter().any(|(name, _)| name == "Cargo.toml") {
self.append_manifest(&mut a);
}
if self.files.is_empty() {
self.append(&mut a, "src/lib.rs", "");
} else {
for &(ref name, ref contents) in self.files.iter() {
self.append(&mut a, name, contents);
}
}
for &(ref name, ref contents) in self.extra_files.iter() {
self.append_extra(&mut a, name, contents);
}
}

fn append_manifest<W: Write>(&self, ar: &mut Builder<W>) {
let mut manifest = format!(
r#"
[package]
Expand Down Expand Up @@ -508,21 +529,7 @@ impl Package {
manifest.push_str("[lib]\nproc-macro = true\n");
}

let dst = self.archive_dst();
t!(fs::create_dir_all(dst.parent().unwrap()));
let f = t!(File::create(&dst));
let mut a = Builder::new(GzEncoder::new(f, Compression::default()));
self.append(&mut a, "Cargo.toml", &manifest);
if self.files.is_empty() {
self.append(&mut a, "src/lib.rs", "");
} else {
for &(ref name, ref contents) in self.files.iter() {
self.append(&mut a, name, contents);
}
}
for &(ref name, ref contents) in self.extra_files.iter() {
self.append_extra(&mut a, name, contents);
}
self.append(ar, "Cargo.toml", &manifest);
}

fn append<W: Write>(&self, ar: &mut Builder<W>, file: &str, contents: &str) {
Expand Down
1 change: 1 addition & 0 deletions src/cargo/core/compiler/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub fn resolve_std<'cfg>(
ws_config,
/*profiles*/ None,
crate::core::Features::default(),
None,
);

let config = ws.config();
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ features! {

// Allow to specify profiles other than 'dev', 'release', 'test', etc.
[unstable] named_profiles: bool,

// Opt-in new-resolver behavior.
[unstable] resolver: bool,
}
}

Expand Down
21 changes: 21 additions & 0 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use serde::Serialize;
use url::Url;

use crate::core::interning::InternedString;
use crate::core::resolver::ResolveBehavior;
use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
use crate::core::{Edition, Feature, Features, WorkspaceConfig};
use crate::util::errors::*;
Expand Down Expand Up @@ -44,6 +45,7 @@ pub struct Manifest {
im_a_teapot: Option<bool>,
default_run: Option<String>,
metabuild: Option<Vec<String>>,
resolve_behavior: Option<ResolveBehavior>,
}

/// When parsing `Cargo.toml`, some warnings should silenced
Expand All @@ -66,6 +68,7 @@ pub struct VirtualManifest {
profiles: Option<TomlProfiles>,
warnings: Warnings,
features: Features,
resolve_behavior: Option<ResolveBehavior>,
}

/// General metadata about a package which is just blindly uploaded to the
Expand Down Expand Up @@ -410,6 +413,7 @@ impl Manifest {
default_run: Option<String>,
original: Rc<TomlManifest>,
metabuild: Option<Vec<String>>,
resolve_behavior: Option<ResolveBehavior>,
) -> Manifest {
Manifest {
summary,
Expand All @@ -432,6 +436,7 @@ impl Manifest {
default_run,
publish_lockfile,
metabuild,
resolve_behavior,
}
}

Expand Down Expand Up @@ -501,6 +506,13 @@ impl Manifest {
&self.features
}

/// The style of resolver behavior to use, declared with the `resolver` field.
///
/// Returns `None` if it is not specified.
pub fn resolve_behavior(&self) -> Option<ResolveBehavior> {
self.resolve_behavior
}

pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Manifest {
Manifest {
summary: self.summary.map_source(to_replace, replace_with),
Expand Down Expand Up @@ -564,6 +576,7 @@ impl VirtualManifest {
workspace: WorkspaceConfig,
profiles: Option<TomlProfiles>,
features: Features,
resolve_behavior: Option<ResolveBehavior>,
) -> VirtualManifest {
VirtualManifest {
replace,
Expand All @@ -572,6 +585,7 @@ impl VirtualManifest {
profiles,
warnings: Warnings::new(),
features,
resolve_behavior,
}
}

Expand Down Expand Up @@ -602,6 +616,13 @@ impl VirtualManifest {
pub fn features(&self) -> &Features {
&self.features
}

/// The style of resolver behavior to use, declared with the `resolver` field.
///
/// Returns `None` if it is not specified.
pub fn resolve_behavior(&self) -> Option<ResolveBehavior> {
self.resolve_behavior
}
}

impl Target {
Expand Down
38 changes: 18 additions & 20 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,27 @@ use crate::core::interning::InternedString;
use crate::core::resolver::{HasDevUnits, Resolve};
use crate::core::source::MaybePackage;
use crate::core::{Dependency, Manifest, PackageId, SourceId, Target};
use crate::core::{FeatureMap, SourceMap, Summary};
use crate::core::{FeatureMap, SourceMap, Summary, Workspace};
use crate::ops;
use crate::util::config::PackageCacheLock;
use crate::util::errors::{CargoResult, CargoResultExt, HttpNot200};
use crate::util::network::Retry;
use crate::util::{self, internal, Config, Progress, ProgressStyle};

pub const MANIFEST_PREAMBLE: &str = "\
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# \"normalize\" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
";

/// Information about a package that is available somewhere in the file system.
///
/// A package is a `Cargo.toml` file plus all the files that are part of it.
Expand Down Expand Up @@ -209,29 +223,13 @@ impl Package {
}
}

pub fn to_registry_toml(&self, config: &Config) -> CargoResult<String> {
pub fn to_registry_toml(&self, ws: &Workspace<'_>) -> CargoResult<String> {
let manifest = self
.manifest()
.original()
.prepare_for_publish(config, self.root())?;
.prepare_for_publish(ws, self.root())?;
let toml = toml::to_string(&manifest)?;
Ok(format!(
"# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO\n\
#\n\
# When uploading crates to the registry Cargo will automatically\n\
# \"normalize\" Cargo.toml files for maximal compatibility\n\
# with all versions of Cargo and also rewrite `path` dependencies\n\
# to registry (e.g., crates.io) dependencies\n\
#\n\
# If you believe there's an error in this file please file an\n\
# issue against the rust-lang/cargo repository. If you're\n\
# editing this file be aware that the upstream Cargo.toml\n\
# will likely look very different (and much more reasonable)\n\
\n\
{}\
",
toml
))
Ok(format!("{}\n{}", MANIFEST_PREAMBLE, toml))
}

/// Returns if package should include `Cargo.lock`.
Expand Down
17 changes: 12 additions & 5 deletions src/cargo/core/resolver/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
use crate::core::compiler::{CompileKind, RustcTargetData};
use crate::core::dependency::{DepKind, Dependency};
use crate::core::resolver::types::FeaturesSet;
use crate::core::resolver::Resolve;
use crate::core::resolver::{Resolve, ResolveBehavior};
use crate::core::{FeatureValue, InternedString, PackageId, PackageIdSpec, PackageSet, Workspace};
use crate::util::{CargoResult, Config};
use crate::util::CargoResult;
use std::collections::{BTreeSet, HashMap, HashSet};
use std::rc::Rc;

Expand Down Expand Up @@ -110,9 +110,9 @@ impl FeaturesFor {
}

impl FeatureOpts {
fn new(config: &Config, has_dev_units: HasDevUnits) -> CargoResult<FeatureOpts> {
fn new(ws: &Workspace<'_>, has_dev_units: HasDevUnits) -> CargoResult<FeatureOpts> {
let mut opts = FeatureOpts::default();
let unstable_flags = config.cli_unstable();
let unstable_flags = ws.config().cli_unstable();
opts.package_features = unstable_flags.package_features;
let mut enable = |feat_opts: &Vec<String>| {
opts.new_resolver = true;
Expand All @@ -136,6 +136,12 @@ impl FeatureOpts {
if let Some(feat_opts) = unstable_flags.features.as_ref() {
enable(feat_opts)?;
}
match ws.resolve_behavior() {
ResolveBehavior::V1 => {}
ResolveBehavior::V2 => {
enable(&vec!["all".to_string()]).unwrap();
}
}
// This env var is intended for testing only.
if let Ok(env_opts) = std::env::var("__CARGO_FORCE_NEW_FEATURES") {
if env_opts == "1" {
Expand All @@ -146,6 +152,7 @@ impl FeatureOpts {
}
}
if let HasDevUnits::Yes = has_dev_units {
// Dev deps cannot be decoupled when they are in use.
opts.decouple_dev_deps = false;
}
Ok(opts)
Expand Down Expand Up @@ -268,7 +275,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
use crate::util::profile;
let _p = profile::start("resolve features");

let opts = FeatureOpts::new(ws.config(), has_dev_units)?;
let opts = FeatureOpts::new(ws, has_dev_units)?;
if !opts.new_resolver {
// Legacy mode.
return Ok(ResolvedFeatures {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub use self::encode::{EncodableDependency, EncodablePackageId, EncodableResolve
pub use self::errors::{ActivateError, ActivateResult, ResolveError};
pub use self::features::HasDevUnits;
pub use self::resolve::{Resolve, ResolveVersion};
pub use self::types::ResolveOpts;
pub use self::types::{ResolveBehavior, ResolveOpts};

mod conflict_cache;
mod context;
Expand Down
29 changes: 29 additions & 0 deletions src/cargo/core/resolver/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,35 @@ impl ResolverProgress {
/// optimized comparison operators like `is_subset` at the interfaces.
pub type FeaturesSet = Rc<BTreeSet<InternedString>>;

/// Resolver behavior, used to opt-in to new behavior that is
/// backwards-incompatible via the `resolver` field in the manifest.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum ResolveBehavior {
/// V1 is the original resolver behavior.
V1,
/// V2 adds the new feature resolver.
V2,
}

impl ResolveBehavior {
pub fn from_manifest(resolver: &str) -> CargoResult<ResolveBehavior> {
match resolver {
"2" => Ok(ResolveBehavior::V2),
s => anyhow::bail!(
"`resolver` setting `{}` is not valid, only valid option is \"2\"",
s
),
}
}

pub fn to_manifest(&self) -> Option<String> {
match self {
ResolveBehavior::V1 => None,
ResolveBehavior::V2 => Some("2".to_string()),
}
}
}

/// Options for how the resolve should work.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct ResolveOpts {
Expand Down
Loading