@@ -221,35 +221,47 @@ fn activate_deps<R: Registry>(cx: Context,
221
221
log ! ( 5 , "{}[{}]>{} trying {}" , parent. get_name( ) , cur, dep. get_name( ) ,
222
222
candidate. get_version( ) ) ;
223
223
let mut my_cx = cx. clone ( ) ;
224
- {
224
+ let early_return = {
225
225
my_cx. resolve . graph . link ( parent. get_package_id ( ) . clone ( ) ,
226
226
candidate. get_package_id ( ) . clone ( ) ) ;
227
227
let prev = match my_cx. activations . entry ( key. clone ( ) ) {
228
228
Occupied ( e) => e. into_mut ( ) ,
229
229
Vacant ( e) => e. set ( Vec :: new ( ) ) ,
230
230
} ;
231
- if !prev. iter ( ) . any ( |c| c == candidate) {
231
+ if prev. iter ( ) . any ( |c| c == candidate) {
232
+ match cx. resolve . features ( candidate. get_package_id ( ) ) {
233
+ Some ( prev_features) => {
234
+ features. iter ( ) . all ( |f| prev_features. contains ( f) )
235
+ }
236
+ None => features. len ( ) == 0 ,
237
+ }
238
+ } else {
232
239
my_cx. resolve . graph . add ( candidate. get_package_id ( ) . clone ( ) , [ ] ) ;
233
240
prev. push ( candidate. clone ( ) ) ;
241
+ false
234
242
}
235
- }
243
+ } ;
236
244
237
- // Dependency graphs are required to be a DAG. Non-transitive
238
- // dependencies (dev-deps), however, can never introduce a cycle, so we
239
- // skip them.
240
- if dep. is_transitive ( ) &&
241
- !cx. visited . borrow_mut ( ) . insert ( candidate. get_package_id ( ) . clone ( ) ) {
242
- return Err ( human ( format ! ( "cyclic package dependency: package `{}` \
243
- depends on itself",
244
- candidate. get_package_id( ) ) ) )
245
- }
246
- let my_cx = try!( activate ( my_cx, registry, & * * candidate, method) ) ;
247
- if dep. is_transitive ( ) {
248
- cx. visited . borrow_mut ( ) . remove ( candidate. get_package_id ( ) ) ;
249
- }
250
- let my_cx = match my_cx {
251
- Ok ( cx) => cx,
252
- Err ( e) => { last_err = Some ( e) ; continue }
245
+ let my_cx = if early_return {
246
+ my_cx
247
+ } else {
248
+ // Dependency graphs are required to be a DAG. Non-transitive
249
+ // dependencies (dev-deps), however, can never introduce a cycle, so we
250
+ // skip them.
251
+ if dep. is_transitive ( ) &&
252
+ !cx. visited . borrow_mut ( ) . insert ( candidate. get_package_id ( ) . clone ( ) ) {
253
+ return Err ( human ( format ! ( "cyclic package dependency: package `{}` \
254
+ depends on itself",
255
+ candidate. get_package_id( ) ) ) )
256
+ }
257
+ let my_cx = try!( activate ( my_cx, registry, & * * candidate, method) ) ;
258
+ if dep. is_transitive ( ) {
259
+ cx. visited . borrow_mut ( ) . remove ( candidate. get_package_id ( ) ) ;
260
+ }
261
+ match my_cx {
262
+ Ok ( cx) => cx,
263
+ Err ( e) => { last_err = Some ( e) ; continue }
264
+ }
253
265
} ;
254
266
match try!( activate_deps ( my_cx, registry, parent, deps, cur + 1 ) ) {
255
267
Ok ( cx) => return Ok ( Ok ( cx) ) ,
0 commit comments