@@ -217,43 +217,86 @@ pub fn resolve_with_previous<'a, 'cfg>(
217
217
registry. add_sources ( & [ member. package_id ( ) . source_id ( ) . clone ( ) ] ) ?;
218
218
}
219
219
220
- let method = match method {
221
- Method :: Everything => Method :: Everything ,
222
- Method :: Required {
223
- features,
224
- all_features,
225
- uses_default_features,
226
- ..
227
- } => {
228
- if specs. len ( ) > 1 && !features. is_empty ( ) {
229
- bail ! ( "cannot specify features for more than one package" ) ;
230
- }
231
- let members_requested = ws. members ( )
232
- . filter ( |m| specs. iter ( ) . any ( |spec| spec. matches ( m. package_id ( ) ) ) )
233
- . count ( ) ;
234
- if members_requested == 0 {
220
+ let mut summaries = Vec :: new ( ) ;
221
+ if ws. config ( ) . cli_unstable ( ) . package_features {
222
+ let mut members = Vec :: new ( ) ;
223
+ match method {
224
+ Method :: Everything => members. extend ( ws. members ( ) ) ,
225
+ Method :: Required {
226
+ features,
227
+ all_features,
228
+ uses_default_features,
229
+ ..
230
+ } => {
231
+ if specs. len ( ) > 1 && !features. is_empty ( ) {
232
+ bail ! ( "cannot specify features for more than one package" ) ;
233
+ }
234
+ members. extend (
235
+ ws. members ( )
236
+ . filter ( |m| specs. iter ( ) . any ( |spec| spec. matches ( m. package_id ( ) ) ) ) ,
237
+ ) ;
235
238
// Edge case: running `cargo build -p foo`, where `foo` is not a member
236
- // of current workspace. Resolve whole workspace to get `foo` into the
237
- // resolution graph.
238
- if !( features. is_empty ( ) && !all_features && uses_default_features) {
239
- bail ! ( "cannot specify features for packages outside of workspace" ) ;
239
+ // of current workspace. Add all packages from workspace to get `foo`
240
+ // into the resolution graph.
241
+ if members. is_empty ( ) {
242
+ if !( features. is_empty ( ) && !all_features && uses_default_features) {
243
+ bail ! ( "cannot specify features for packages outside of workspace" ) ;
244
+ }
245
+ members. extend ( ws. members ( ) ) ;
240
246
}
241
- Method :: Everything
242
- } else {
243
- method
244
247
}
245
248
}
246
- } ;
249
+ for member in members {
250
+ let summary = registry. lock ( member. summary ( ) . clone ( ) ) ;
251
+ summaries. push ( ( summary, method) )
252
+ }
253
+ } else {
254
+ for member in ws. members ( ) {
255
+ let method_to_resolve = match method {
256
+ // When everything for a workspace we want to be sure to resolve all
257
+ // members in the workspace, so propagate the `Method::Everything`.
258
+ Method :: Everything => Method :: Everything ,
259
+
260
+ // If we're not resolving everything though then we're constructing the
261
+ // exact crate graph we're going to build. Here we don't necessarily
262
+ // want to keep around all workspace crates as they may not all be
263
+ // built/tested.
264
+ //
265
+ // Additionally, the `method` specified represents command line
266
+ // flags, which really only matters for the current package
267
+ // (determined by the cwd). If other packages are specified (via
268
+ // `-p`) then the command line flags like features don't apply to
269
+ // them.
270
+ //
271
+ // As a result, if this `member` is the current member of the
272
+ // workspace, then we use `method` specified. Otherwise we use a
273
+ // base method with no features specified but using default features
274
+ // for any other packages specified with `-p`.
275
+ Method :: Required { dev_deps, .. } => {
276
+ let base = Method :: Required {
277
+ dev_deps,
278
+ features : & [ ] ,
279
+ all_features : false ,
280
+ uses_default_features : true ,
281
+ } ;
282
+ let member_id = member. package_id ( ) ;
283
+ match ws. current_opt ( ) {
284
+ Some ( current) if member_id == current. package_id ( ) => method,
285
+ _ => {
286
+ if specs. iter ( ) . any ( |spec| spec. matches ( member_id) ) {
287
+ base
288
+ } else {
289
+ continue ;
290
+ }
291
+ }
292
+ }
293
+ }
294
+ } ;
247
295
248
- let summaries = ws. members ( )
249
- . filter ( |m| {
250
- method == Method :: Everything || specs. iter ( ) . any ( |spec| spec. matches ( m. package_id ( ) ) )
251
- } )
252
- . map ( |member| {
253
296
let summary = registry. lock ( member. summary ( ) . clone ( ) ) ;
254
- ( summary, method )
255
- } )
256
- . collect :: < Vec < _ > > ( ) ;
297
+ summaries . push ( ( summary, method_to_resolve ) ) ;
298
+ }
299
+ } ;
257
300
258
301
let root_replace = ws. root_replace ( ) ;
259
302
0 commit comments