Skip to content

Commit a82a23c

Browse files
committed
Change how workspace resolve behavior is calculated.
This fixes an issue where warnings would be printed for packages migrating to 2021 in a workspace (that the "resolver" field is ignored, which is wrong). This also places the default resolver logic in one place, and should make it easier to update later.
1 parent c303213 commit a82a23c

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

src/cargo/core/workspace.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::core::features::Features;
1313
use crate::core::registry::PackageRegistry;
1414
use crate::core::resolver::features::RequestedFeatures;
1515
use crate::core::resolver::ResolveBehavior;
16-
use crate::core::{Dependency, PackageId, PackageIdSpec};
16+
use crate::core::{Dependency, Edition, PackageId, PackageIdSpec};
1717
use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
1818
use crate::ops;
1919
use crate::sources::PathSource;
@@ -88,7 +88,7 @@ pub struct Workspace<'cfg> {
8888
ignore_lock: bool,
8989

9090
/// The resolver behavior specified with the `resolver` field.
91-
resolve_behavior: Option<ResolveBehavior>,
91+
resolve_behavior: ResolveBehavior,
9292

9393
/// Workspace-level custom metadata
9494
custom_metadata: Option<toml::Value>,
@@ -164,10 +164,7 @@ impl<'cfg> Workspace<'cfg> {
164164
.load_workspace_config()?
165165
.and_then(|cfg| cfg.custom_metadata);
166166
ws.find_members()?;
167-
ws.resolve_behavior = match ws.root_maybe() {
168-
MaybePackage::Package(p) => p.manifest().resolve_behavior(),
169-
MaybePackage::Virtual(vm) => vm.resolve_behavior(),
170-
};
167+
ws.set_resolve_behavior();
171168
ws.validate()?;
172169
Ok(ws)
173170
}
@@ -189,7 +186,7 @@ impl<'cfg> Workspace<'cfg> {
189186
require_optional_deps: true,
190187
loaded_packages: RefCell::new(HashMap::new()),
191188
ignore_lock: false,
192-
resolve_behavior: None,
189+
resolve_behavior: ResolveBehavior::V1,
193190
custom_metadata: None,
194191
}
195192
}
@@ -203,11 +200,11 @@ impl<'cfg> Workspace<'cfg> {
203200
let mut ws = Workspace::new_default(current_manifest, config);
204201
ws.root_manifest = Some(root_path.join("Cargo.toml"));
205202
ws.target_dir = config.target_dir()?;
206-
ws.resolve_behavior = manifest.resolve_behavior();
207203
ws.packages
208204
.packages
209205
.insert(root_path, MaybePackage::Virtual(manifest));
210206
ws.find_members()?;
207+
ws.set_resolve_behavior();
211208
// TODO: validation does not work because it walks up the directory
212209
// tree looking for the root which is a fake file that doesn't exist.
213210
Ok(ws)
@@ -231,7 +228,6 @@ impl<'cfg> Workspace<'cfg> {
231228
let mut ws = Workspace::new_default(package.manifest_path().to_path_buf(), config);
232229
ws.is_ephemeral = true;
233230
ws.require_optional_deps = require_optional_deps;
234-
ws.resolve_behavior = package.manifest().resolve_behavior();
235231
let key = ws.current_manifest.parent().unwrap();
236232
let id = package.package_id();
237233
let package = MaybePackage::Package(package);
@@ -244,9 +240,28 @@ impl<'cfg> Workspace<'cfg> {
244240
ws.members.push(ws.current_manifest.clone());
245241
ws.member_ids.insert(id);
246242
ws.default_members.push(ws.current_manifest.clone());
243+
ws.set_resolve_behavior();
247244
Ok(ws)
248245
}
249246

247+
fn set_resolve_behavior(&mut self) {
248+
// - If resolver is specified in the workspace definition, use that.
249+
// - If the root package specifies the resolver, use that.
250+
// - If the root package specifies edition 2021, use v2.
251+
// - Otherwise, use the default v1.
252+
self.resolve_behavior = match self.root_maybe() {
253+
MaybePackage::Package(p) => p.manifest().resolve_behavior().or_else(|| {
254+
if p.manifest().edition() >= Edition::Edition2021 {
255+
Some(ResolveBehavior::V2)
256+
} else {
257+
None
258+
}
259+
}),
260+
MaybePackage::Virtual(vm) => vm.resolve_behavior(),
261+
}
262+
.unwrap_or(ResolveBehavior::V1);
263+
}
264+
250265
/// Returns the current package of this workspace.
251266
///
252267
/// Note that this can return an error if it the current manifest is
@@ -634,7 +649,7 @@ impl<'cfg> Workspace<'cfg> {
634649
}
635650

636651
pub fn resolve_behavior(&self) -> ResolveBehavior {
637-
self.resolve_behavior.unwrap_or(ResolveBehavior::V1)
652+
self.resolve_behavior
638653
}
639654

640655
/// Returns `true` if this workspace uses the new CLI features behavior.
@@ -843,11 +858,11 @@ impl<'cfg> Workspace<'cfg> {
843858
if !manifest.patch().is_empty() {
844859
emit_warning("patch")?;
845860
}
846-
if manifest.resolve_behavior().is_some()
847-
&& manifest.resolve_behavior() != self.resolve_behavior
848-
{
849-
// Only warn if they don't match.
850-
emit_warning("resolver")?;
861+
if let Some(behavior) = manifest.resolve_behavior() {
862+
if behavior != self.resolve_behavior {
863+
// Only warn if they don't match.
864+
emit_warning("resolver")?;
865+
}
851866
}
852867
}
853868
}

src/cargo/util/toml/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,13 +1132,7 @@ impl TomlManifest {
11321132
project.resolver.as_ref(),
11331133
me.workspace.as_ref().and_then(|ws| ws.resolver.as_ref()),
11341134
) {
1135-
(None, None) => {
1136-
if edition == Edition::Edition2021 {
1137-
Some(ResolveBehavior::V2)
1138-
} else {
1139-
None
1140-
}
1141-
}
1135+
(None, None) => None,
11421136
(Some(s), None) | (None, Some(s)) => Some(ResolveBehavior::from_manifest(s)?),
11431137
(Some(_), Some(_)) => {
11441138
bail!("cannot specify `resolver` field in both `[workspace]` and `[package]`")

0 commit comments

Comments
 (0)