50
50
//! improved.
51
51
52
52
use std:: cell:: Cell ;
53
+ use std:: collections:: BTreeSet ;
53
54
use std:: collections:: { BTreeMap , HashMap , HashSet } ;
54
55
use std:: io;
55
56
use std:: marker;
@@ -74,9 +75,11 @@ use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
74
75
use crate :: core:: compiler:: future_incompat:: {
75
76
FutureBreakageItem , OnDiskReport , FUTURE_INCOMPAT_FILE ,
76
77
} ;
77
- use crate :: core:: { PackageId , Shell , TargetKind } ;
78
+ use crate :: core:: resolver:: ResolveBehavior ;
79
+ use crate :: core:: { FeatureValue , PackageId , Shell , TargetKind } ;
78
80
use crate :: drop_eprint;
79
81
use crate :: util:: diagnostic_server:: { self , DiagnosticPrinter } ;
82
+ use crate :: util:: interning:: InternedString ;
80
83
use crate :: util:: machine_message:: { self , Message as _} ;
81
84
use crate :: util:: CargoResult ;
82
85
use crate :: util:: { self , internal, profile} ;
@@ -607,6 +610,7 @@ impl<'cfg> DrainState<'cfg> {
607
610
Err ( e) => {
608
611
let msg = "The following warnings were emitted during compilation:" ;
609
612
self . emit_warnings ( Some ( msg) , & unit, cx) ?;
613
+ self . back_compat_notice ( cx, & unit) ?;
610
614
return Err ( e) ;
611
615
}
612
616
}
@@ -1154,4 +1158,59 @@ impl<'cfg> DrainState<'cfg> {
1154
1158
}
1155
1159
Ok ( ( ) )
1156
1160
}
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
+ }
1157
1216
}
0 commit comments