5050//! improved.
5151
5252use std:: cell:: Cell ;
53+ use std:: collections:: BTreeSet ;
5354use std:: collections:: { BTreeMap , HashMap , HashSet } ;
5455use std:: io;
5556use std:: marker;
@@ -74,9 +75,11 @@ use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
7475use 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 } ;
7880use crate :: drop_eprint;
7981use crate :: util:: diagnostic_server:: { self , DiagnosticPrinter } ;
82+ use crate :: util:: interning:: InternedString ;
8083use crate :: util:: machine_message:: { self , Message as _} ;
8184use crate :: util:: CargoResult ;
8285use 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}
0 commit comments