Skip to content

Commit f2c22a3

Browse files
committed
Auto merge of #9602 - ehuss:diesel-warning, r=alexcrichton
Add a compatibility notice for diesel and the new resolver. This adds a notice about a compatibility issue with diesel and the new feature resolver. This will display a notice if it detects the scenario where diesel causes a build error. It also prints a not when using `cargo fix --edition` when it detects a setup that may fail.
2 parents 9548b78 + 9c809b7 commit f2c22a3

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed

src/cargo/core/compiler/job_queue.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
//! improved.
5151
5252
use std::cell::Cell;
53+
use std::collections::BTreeSet;
5354
use std::collections::{BTreeMap, HashMap, HashSet};
5455
use std::io;
5556
use std::marker;
@@ -74,9 +75,11 @@ use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
7475
use crate::core::compiler::future_incompat::{
7576
FutureBreakageItem, OnDiskReport, FUTURE_INCOMPAT_FILE,
7677
};
77-
use crate::core::{PackageId, Shell, TargetKind};
78+
use crate::core::resolver::ResolveBehavior;
79+
use crate::core::{FeatureValue, PackageId, Shell, TargetKind};
7880
use crate::drop_eprint;
7981
use crate::util::diagnostic_server::{self, DiagnosticPrinter};
82+
use crate::util::interning::InternedString;
8083
use crate::util::machine_message::{self, Message as _};
8184
use crate::util::CargoResult;
8285
use crate::util::{self, internal, profile};
@@ -607,6 +610,7 @@ impl<'cfg> DrainState<'cfg> {
607610
Err(e) => {
608611
let msg = "The following warnings were emitted during compilation:";
609612
self.emit_warnings(Some(msg), &unit, cx)?;
613+
self.back_compat_notice(cx, &unit)?;
610614
return Err(e);
611615
}
612616
}
@@ -1154,4 +1158,59 @@ impl<'cfg> DrainState<'cfg> {
11541158
}
11551159
Ok(())
11561160
}
1161+
1162+
fn back_compat_notice(&self, cx: &Context<'_, '_>, unit: &Unit) -> CargoResult<()> {
1163+
if unit.pkg.name() != "diesel"
1164+
|| unit.pkg.version().major != 1
1165+
|| cx.bcx.ws.resolve_behavior() == ResolveBehavior::V1
1166+
|| !unit.pkg.package_id().source_id().is_registry()
1167+
|| !unit.features.is_empty()
1168+
{
1169+
return Ok(());
1170+
}
1171+
let other_diesel = match cx
1172+
.bcx
1173+
.unit_graph
1174+
.keys()
1175+
.filter(|unit| unit.pkg.name() == "diesel" && !unit.features.is_empty())
1176+
.next()
1177+
{
1178+
Some(u) => u,
1179+
// Unlikely due to features.
1180+
None => return Ok(()),
1181+
};
1182+
let mut features_suggestion: BTreeSet<_> = other_diesel.features.iter().collect();
1183+
let fmap = other_diesel.pkg.summary().features();
1184+
// Remove any unnecessary features.
1185+
for feature in &other_diesel.features {
1186+
if let Some(feats) = fmap.get(feature) {
1187+
for feat in feats {
1188+
if let FeatureValue::Feature(f) = feat {
1189+
features_suggestion.remove(&f);
1190+
}
1191+
}
1192+
}
1193+
}
1194+
features_suggestion.remove(&InternedString::new("default"));
1195+
let features_suggestion = toml::to_string(&features_suggestion).unwrap();
1196+
1197+
cx.bcx.config.shell().note(&format!(
1198+
"\
1199+
This error may be due to an interaction between diesel and Cargo's new
1200+
feature resolver. Some workarounds you may want to consider:
1201+
- Add a build-dependency in Cargo.toml on diesel to force Cargo to add the appropriate
1202+
features. This may look something like this:
1203+
1204+
[build-dependencies]
1205+
diesel = {{ version = \"{}\", features = {} }}
1206+
1207+
- Try using the previous resolver by setting `resolver = \"1\"` in `Cargo.toml`
1208+
(see <https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions>
1209+
for more information).
1210+
",
1211+
unit.pkg.version(),
1212+
features_suggestion
1213+
))?;
1214+
Ok(())
1215+
}
11571216
}

src/cargo/ops/fix.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use rustfix::{self, CodeFix};
5353

5454
use crate::core::compiler::RustcTargetData;
5555
use crate::core::resolver::features::{FeatureOpts, FeatureResolver};
56-
use crate::core::resolver::{HasDevUnits, ResolveBehavior};
56+
use crate::core::resolver::{HasDevUnits, Resolve, ResolveBehavior};
5757
use crate::core::{Edition, MaybePackage, Workspace};
5858
use crate::ops::{self, CompileOptions};
5959
use crate::util::diagnostic_server::{Message, RustfixDiagnosticServer};
@@ -292,6 +292,25 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
292292
report(differences.features, "features");
293293
report(differences.optional_deps, "optional dependency");
294294
drop_eprint!(config, "\n");
295+
report_maybe_diesel(config, &ws_resolve.targeted_resolve)?;
296+
Ok(())
297+
}
298+
299+
fn report_maybe_diesel(config: &Config, resolve: &Resolve) -> CargoResult<()> {
300+
if resolve
301+
.iter()
302+
.any(|pid| pid.name() == "diesel" && pid.version().major == 1)
303+
&& resolve.iter().any(|pid| pid.name() == "diesel_migrations")
304+
{
305+
config.shell().note(
306+
"\
307+
This project appears to use both diesel and diesel_migrations. These packages have
308+
a known issue where the build may fail due to the version 2 resolver preventing
309+
feature unification between those two packages. See
310+
<https://github.com/rust-lang/cargo/issues/9450> for some potential workarounds.
311+
",
312+
)?;
313+
}
295314
Ok(())
296315
}
297316

0 commit comments

Comments
 (0)