]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/features.rs
Stabilize namespaced and weak dependency features.
[cargo.git] / tests / testsuite / features.rs
CommitLineData
83571aee
EH
1//! Tests for `[features]` table.
2
9115b2c3 3use cargo_test_support::paths::CargoPathExt;
ab73b2c3 4use cargo_test_support::registry::{Dependency, Package};
4ae79d2f 5use cargo_test_support::{basic_manifest, project};
2b46d039 6
0e0d9688 7#[cargo_test]
6950bbb0 8fn invalid1() {
7fe2fbc8 9 let p = project()
1e682848
AC
10 .file(
11 "Cargo.toml",
12 r#"
6f8c7d5a
EH
13 [project]
14 name = "foo"
15 version = "0.0.1"
16 authors = []
2b46d039 17
6f8c7d5a
EH
18 [features]
19 bar = ["baz"]
20 "#,
fecb7246
AC
21 )
22 .file("src/main.rs", "")
d43ee1dd 23 .build();
2b46d039 24
85984a87
DW
25 p.cargo("build")
26 .with_status(101)
27 .with_stderr(
1e682848 28 "\
29cdad4f 29[ERROR] failed to parse manifest at `[..]`
2b46d039 30
d14abb6e 31Caused by:
bcfdf9fb 32 feature `bar` includes `baz` which is neither a dependency nor another feature
1e682848 33",
fecb7246
AC
34 )
35 .run();
6950bbb0 36}
2b46d039 37
0e0d9688 38#[cargo_test]
43a063c8
EH
39fn same_name() {
40 // Feature with the same name as a dependency.
7fe2fbc8 41 let p = project()
1e682848
AC
42 .file(
43 "Cargo.toml",
44 r#"
6f8c7d5a
EH
45 [project]
46 name = "foo"
47 version = "0.0.1"
48 authors = []
2b46d039 49
6f8c7d5a
EH
50 [features]
51 bar = ["baz"]
bcfdf9fb 52 baz = []
2b46d039 53
6f8c7d5a 54 [dependencies.bar]
bcfdf9fb 55 path = "bar"
6f8c7d5a 56 "#,
fecb7246
AC
57 )
58 .file("src/main.rs", "")
bcfdf9fb
EH
59 .file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0"))
60 .file("bar/src/lib.rs", "")
d43ee1dd 61 .build();
2b46d039 62
43a063c8
EH
63 p.cargo("tree -f")
64 .arg("{p} [{f}]")
65 .with_stderr("")
66 .with_stdout(
1e682848 67 "\
43a063c8
EH
68foo v0.0.1 ([..]) []
69└── bar v1.0.0 ([..]) []
70",
71 )
72 .run();
2b46d039 73
43a063c8
EH
74 p.cargo("tree --features bar -f")
75 .arg("{p} [{f}]")
76 .with_stderr("")
77 .with_stdout(
78 "\
79foo v0.0.1 ([..]) [bar,baz]
80└── bar v1.0.0 ([..]) []
1e682848 81",
fecb7246
AC
82 )
83 .run();
6950bbb0 84}
2b46d039 85
0e0d9688 86#[cargo_test]
6950bbb0 87fn invalid3() {
7fe2fbc8 88 let p = project()
1e682848
AC
89 .file(
90 "Cargo.toml",
91 r#"
6f8c7d5a
EH
92 [project]
93 name = "foo"
94 version = "0.0.1"
95 authors = []
2b46d039 96
6f8c7d5a
EH
97 [features]
98 bar = ["baz"]
2b46d039 99
6f8c7d5a
EH
100 [dependencies.baz]
101 path = "foo"
102 "#,
fecb7246
AC
103 )
104 .file("src/main.rs", "")
d43ee1dd 105 .build();
2b46d039 106
85984a87
DW
107 p.cargo("build")
108 .with_status(101)
109 .with_stderr(
1e682848 110 "\
29cdad4f 111[ERROR] failed to parse manifest at `[..]`
2b46d039 112
d14abb6e 113Caused by:
bcfdf9fb
EH
114 feature `bar` includes `baz`, but `baz` is not an optional dependency
115 A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition.
1e682848 116",
fecb7246
AC
117 )
118 .run();
6950bbb0 119}
2b46d039 120
0e0d9688 121#[cargo_test]
6950bbb0 122fn invalid4() {
7fe2fbc8 123 let p = project()
1e682848
AC
124 .file(
125 "Cargo.toml",
126 r#"
6f8c7d5a
EH
127 [project]
128 name = "foo"
129 version = "0.0.1"
130 authors = []
2b46d039 131
6f8c7d5a
EH
132 [dependencies.bar]
133 path = "bar"
134 features = ["bar"]
135 "#,
fecb7246
AC
136 )
137 .file("src/main.rs", "")
ab19c483 138 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
d43ee1dd
NK
139 .file("bar/src/lib.rs", "")
140 .build();
2b46d039 141
85984a87
DW
142 p.cargo("build")
143 .with_status(101)
144 .with_stderr(
1e682848 145 "\
5d4402ce
E
146error: failed to select a version for `bar`.
147 ... required by package `foo v0.0.1 ([..])`
148versions that meet the requirements `*` are: 0.0.1
149
2cbd1ddc 150the package `foo` depends on `bar`, with features: `bar` but `bar` does not have these features.
5d4402ce 151
5d4402ce 152
1e682848 153failed to select a version for `bar` which could resolve this conflict",
fecb7246
AC
154 )
155 .run();
2b46d039 156
ab19c483 157 p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1"));
1e682848 158
85984a87
DW
159 p.cargo("build --features test")
160 .with_status(101)
bcfdf9fb 161 .with_stderr("error: Package `foo v0.0.1 ([..])` does not have the feature `test`")
85984a87 162 .run();
6950bbb0 163}
2b46d039 164
0e0d9688 165#[cargo_test]
6950bbb0 166fn invalid5() {
7fe2fbc8 167 let p = project()
1e682848
AC
168 .file(
169 "Cargo.toml",
170 r#"
6f8c7d5a
EH
171 [project]
172 name = "foo"
173 version = "0.0.1"
174 authors = []
2b46d039 175
6f8c7d5a
EH
176 [dev-dependencies.bar]
177 path = "bar"
178 optional = true
179 "#,
fecb7246
AC
180 )
181 .file("src/main.rs", "")
d43ee1dd 182 .build();
2b46d039 183
85984a87
DW
184 p.cargo("build")
185 .with_status(101)
186 .with_stderr(
1e682848 187 "\
29cdad4f 188[ERROR] failed to parse manifest at `[..]`
2b46d039 189
d14abb6e 190Caused by:
bcfdf9fb 191 dev-dependencies are not allowed to be optional: `bar`
1e682848 192",
fecb7246
AC
193 )
194 .run();
6950bbb0 195}
2b46d039 196
0e0d9688 197#[cargo_test]
6950bbb0 198fn invalid6() {
7fe2fbc8 199 let p = project()
1e682848
AC
200 .file(
201 "Cargo.toml",
202 r#"
6f8c7d5a
EH
203 [project]
204 name = "foo"
205 version = "0.0.1"
206 authors = []
f5f34e85 207
6f8c7d5a
EH
208 [features]
209 foo = ["bar/baz"]
210 "#,
fecb7246
AC
211 )
212 .file("src/main.rs", "")
d43ee1dd 213 .build();
f5f34e85 214
85984a87
DW
215 p.cargo("build --features foo")
216 .with_status(101)
217 .with_stderr(
1e682848 218 "\
29cdad4f 219[ERROR] failed to parse manifest at `[..]`
f5f34e85 220
d14abb6e 221Caused by:
bcfdf9fb 222 feature `foo` includes `bar/baz`, but `bar` is not a dependency
1e682848 223",
fecb7246
AC
224 )
225 .run();
6950bbb0 226}
f5f34e85 227
0e0d9688 228#[cargo_test]
6950bbb0 229fn invalid7() {
7fe2fbc8 230 let p = project()
1e682848
AC
231 .file(
232 "Cargo.toml",
233 r#"
6f8c7d5a
EH
234 [project]
235 name = "foo"
236 version = "0.0.1"
237 authors = []
f5f34e85 238
6f8c7d5a
EH
239 [features]
240 foo = ["bar/baz"]
241 bar = []
242 "#,
fecb7246
AC
243 )
244 .file("src/main.rs", "")
d43ee1dd 245 .build();
f5f34e85 246
85984a87
DW
247 p.cargo("build --features foo")
248 .with_status(101)
249 .with_stderr(
1e682848 250 "\
29cdad4f 251[ERROR] failed to parse manifest at `[..]`
f5f34e85 252
d14abb6e 253Caused by:
bcfdf9fb 254 feature `foo` includes `bar/baz`, but `bar` is not a dependency
1e682848 255",
fecb7246
AC
256 )
257 .run();
6950bbb0 258}
f5f34e85 259
0e0d9688 260#[cargo_test]
6950bbb0 261fn invalid8() {
7fe2fbc8 262 let p = project()
1e682848
AC
263 .file(
264 "Cargo.toml",
265 r#"
6f8c7d5a
EH
266 [project]
267 name = "foo"
268 version = "0.0.1"
269 authors = []
f5f34e85 270
6f8c7d5a
EH
271 [dependencies.bar]
272 path = "bar"
273 features = ["foo/bar"]
274 "#,
fecb7246
AC
275 )
276 .file("src/main.rs", "")
ab19c483 277 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
d43ee1dd
NK
278 .file("bar/src/lib.rs", "")
279 .build();
f5f34e85 280
85984a87
DW
281 p.cargo("build --features foo")
282 .with_status(101)
85854b18
EH
283 .with_stderr(
284 "\
285error: failed to parse manifest at `[CWD]/Cargo.toml`
286
287Caused by:
288 feature `foo/bar` in dependency `bar` is not allowed to contain slashes
289 If you want to enable features [..]
290",
291 )
85984a87 292 .run();
848f8b59
BF
293}
294
0e0d9688 295#[cargo_test]
c72df674 296fn invalid9() {
7fe2fbc8 297 let p = project()
1e682848
AC
298 .file(
299 "Cargo.toml",
300 r#"
6f8c7d5a
EH
301 [project]
302 name = "foo"
303 version = "0.0.1"
304 authors = []
c72df674 305
6f8c7d5a
EH
306 [dependencies.bar]
307 path = "bar"
308 "#,
fecb7246
AC
309 )
310 .file("src/main.rs", "fn main() {}")
ab19c483 311 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
d43ee1dd
NK
312 .file("bar/src/lib.rs", "")
313 .build();
c72df674 314
35ff555b 315 p.cargo("build --features bar")
19a95790 316 .with_stderr(
35ff555b
E
317 "\
318error: Package `foo v0.0.1 ([..])` does not have feature `bar`. It has a required dependency with that name, but only optional dependencies can be used as features.
319",
320 ).with_status(101).run();
c72df674
RJ
321}
322
0e0d9688 323#[cargo_test]
c72df674 324fn invalid10() {
7fe2fbc8 325 let p = project()
1e682848
AC
326 .file(
327 "Cargo.toml",
328 r#"
6f8c7d5a
EH
329 [project]
330 name = "foo"
331 version = "0.0.1"
332 authors = []
c72df674 333
6f8c7d5a
EH
334 [dependencies.bar]
335 path = "bar"
336 features = ["baz"]
337 "#,
fecb7246
AC
338 )
339 .file("src/main.rs", "fn main() {}")
1e682848
AC
340 .file(
341 "bar/Cargo.toml",
342 r#"
6f8c7d5a
EH
343 [package]
344 name = "bar"
345 version = "0.0.1"
346 authors = []
c72df674 347
6f8c7d5a
EH
348 [dependencies.baz]
349 path = "baz"
350 "#,
fecb7246
AC
351 )
352 .file("bar/src/lib.rs", "")
ab19c483 353 .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
d43ee1dd
NK
354 .file("bar/baz/src/lib.rs", "")
355 .build();
c72df674 356
85984a87 357 p.cargo("build").with_stderr("\
35ff555b
E
358error: failed to select a version for `bar`.
359 ... required by package `foo v0.0.1 ([..])`
360versions that meet the requirements `*` are: 0.0.1
361
362the package `foo` depends on `bar`, with features: `baz` but `bar` does not have these features.
363 It has a required dependency with that name, but only optional dependencies can be used as features.
364
365
366failed to select a version for `bar` which could resolve this conflict
367").with_status(101)
368 .run();
c72df674
RJ
369}
370
0e0d9688 371#[cargo_test]
848f8b59 372fn no_transitive_dep_feature_requirement() {
7fe2fbc8 373 let p = project()
1e682848
AC
374 .file(
375 "Cargo.toml",
376 r#"
6f8c7d5a
EH
377 [project]
378 name = "foo"
379 version = "0.0.1"
380 authors = []
848f8b59 381
6f8c7d5a
EH
382 [dependencies.derived]
383 path = "derived"
848f8b59 384
6f8c7d5a
EH
385 [features]
386 default = ["derived/bar/qux"]
387 "#,
fecb7246
AC
388 )
389 .file(
1e682848
AC
390 "src/main.rs",
391 r#"
6f8c7d5a
EH
392 extern crate derived;
393 fn main() { derived::test(); }
394 "#,
fecb7246
AC
395 )
396 .file(
1e682848
AC
397 "derived/Cargo.toml",
398 r#"
6f8c7d5a
EH
399 [package]
400 name = "derived"
401 version = "0.0.1"
402 authors = []
848f8b59 403
6f8c7d5a
EH
404 [dependencies.bar]
405 path = "../bar"
406 "#,
fecb7246
AC
407 )
408 .file("derived/src/lib.rs", "extern crate bar; pub use bar::test;")
1e682848
AC
409 .file(
410 "bar/Cargo.toml",
411 r#"
6f8c7d5a
EH
412 [package]
413 name = "bar"
414 version = "0.0.1"
415 authors = []
848f8b59 416
6f8c7d5a
EH
417 [features]
418 qux = []
419 "#,
fecb7246
AC
420 )
421 .file(
1e682848
AC
422 "bar/src/lib.rs",
423 r#"
6f8c7d5a
EH
424 #[cfg(feature = "qux")]
425 pub fn test() { print!("test"); }
426 "#,
fecb7246
AC
427 )
428 .build();
85984a87
DW
429 p.cargo("build")
430 .with_status(101)
85854b18
EH
431 .with_stderr(
432 "\
433error: failed to parse manifest at `[CWD]/Cargo.toml`
434
435Caused by:
436 multiple slashes in feature `derived/bar/qux` (included by feature `default`) are not allowed
437",
438 )
85984a87 439 .run();
6950bbb0 440}
f5f34e85 441
0e0d9688 442#[cargo_test]
6950bbb0 443fn no_feature_doesnt_build() {
7fe2fbc8 444 let p = project()
1e682848
AC
445 .file(
446 "Cargo.toml",
447 r#"
6f8c7d5a
EH
448 [project]
449 name = "foo"
450 version = "0.0.1"
451 authors = []
2b46d039 452
6f8c7d5a
EH
453 [dependencies.bar]
454 path = "bar"
455 optional = true
456 "#,
fecb7246
AC
457 )
458 .file(
1e682848
AC
459 "src/main.rs",
460 r#"
6f8c7d5a
EH
461 #[cfg(feature = "bar")]
462 extern crate bar;
463 #[cfg(feature = "bar")]
464 fn main() { bar::bar(); println!("bar") }
465 #[cfg(not(feature = "bar"))]
466 fn main() {}
467 "#,
fecb7246
AC
468 )
469 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
d43ee1dd
NK
470 .file("bar/src/lib.rs", "pub fn bar() {}")
471 .build();
2b46d039 472
85984a87 473 p.cargo("build")
2cd9cce6 474 .with_stderr(
1e682848 475 "\
89f43938 476[COMPILING] foo v0.0.1 ([CWD])
34628b65 477[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 478",
fecb7246
AC
479 )
480 .run();
2554afe7 481 p.process(&p.bin("foo")).with_stdout("").run();
1e682848 482
85984a87 483 p.cargo("build --features bar")
2cd9cce6 484 .with_stderr(
1e682848 485 "\
89f43938
ZL
486[COMPILING] bar v0.0.1 ([CWD]/bar)
487[COMPILING] foo v0.0.1 ([CWD])
34628b65 488[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 489",
fecb7246
AC
490 )
491 .run();
2554afe7 492 p.process(&p.bin("foo")).with_stdout("bar\n").run();
6950bbb0 493}
2b46d039 494
0e0d9688 495#[cargo_test]
6950bbb0 496fn default_feature_pulled_in() {
7fe2fbc8 497 let p = project()
1e682848
AC
498 .file(
499 "Cargo.toml",
500 r#"
6f8c7d5a
EH
501 [project]
502 name = "foo"
503 version = "0.0.1"
504 authors = []
2b46d039 505
6f8c7d5a
EH
506 [features]
507 default = ["bar"]
2b46d039 508
6f8c7d5a
EH
509 [dependencies.bar]
510 path = "bar"
511 optional = true
512 "#,
fecb7246
AC
513 )
514 .file(
1e682848
AC
515 "src/main.rs",
516 r#"
6f8c7d5a
EH
517 #[cfg(feature = "bar")]
518 extern crate bar;
519 #[cfg(feature = "bar")]
520 fn main() { bar::bar(); println!("bar") }
521 #[cfg(not(feature = "bar"))]
522 fn main() {}
523 "#,
fecb7246
AC
524 )
525 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
d43ee1dd
NK
526 .file("bar/src/lib.rs", "pub fn bar() {}")
527 .build();
2b46d039 528
85984a87 529 p.cargo("build")
2cd9cce6 530 .with_stderr(
1e682848 531 "\
89f43938
ZL
532[COMPILING] bar v0.0.1 ([CWD]/bar)
533[COMPILING] foo v0.0.1 ([CWD])
34628b65 534[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 535",
fecb7246
AC
536 )
537 .run();
2554afe7 538 p.process(&p.bin("foo")).with_stdout("bar\n").run();
1e682848 539
85984a87 540 p.cargo("build --no-default-features")
2cd9cce6 541 .with_stderr(
1e682848 542 "\
89f43938 543[COMPILING] foo v0.0.1 ([CWD])
34628b65 544[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 545",
fecb7246
AC
546 )
547 .run();
2554afe7 548 p.process(&p.bin("foo")).with_stdout("").run();
6950bbb0 549}
2b46d039 550
0e0d9688 551#[cargo_test]
6950bbb0 552fn cyclic_feature() {
7fe2fbc8 553 let p = project()
1e682848
AC
554 .file(
555 "Cargo.toml",
556 r#"
6f8c7d5a
EH
557 [project]
558 name = "foo"
559 version = "0.0.1"
560 authors = []
2b46d039 561
6f8c7d5a
EH
562 [features]
563 default = ["default"]
564 "#,
fecb7246
AC
565 )
566 .file("src/main.rs", "")
d43ee1dd 567 .build();
2b46d039 568
85984a87
DW
569 p.cargo("build")
570 .with_status(101)
f7c91ba6 571 .with_stderr("[ERROR] cyclic feature dependency: feature `default` depends on itself")
85984a87 572 .run();
6950bbb0 573}
2b46d039 574
0e0d9688 575#[cargo_test]
6950bbb0 576fn cyclic_feature2() {
7fe2fbc8 577 let p = project()
1e682848
AC
578 .file(
579 "Cargo.toml",
580 r#"
6f8c7d5a
EH
581 [project]
582 name = "foo"
583 version = "0.0.1"
584 authors = []
2b46d039 585
6f8c7d5a
EH
586 [features]
587 foo = ["bar"]
588 bar = ["foo"]
589 "#,
fecb7246
AC
590 )
591 .file("src/main.rs", "fn main() {}")
d43ee1dd 592 .build();
2b46d039 593
85984a87 594 p.cargo("build").with_stdout("").run();
6950bbb0 595}
2b46d039 596
0e0d9688 597#[cargo_test]
6950bbb0 598fn groups_on_groups_on_groups() {
7fe2fbc8 599 let p = project()
1e682848
AC
600 .file(
601 "Cargo.toml",
602 r#"
6f8c7d5a
EH
603 [project]
604 name = "foo"
605 version = "0.0.1"
606 authors = []
2b46d039 607
6f8c7d5a
EH
608 [features]
609 default = ["f1"]
610 f1 = ["f2", "bar"]
611 f2 = ["f3", "f4"]
612 f3 = ["f5", "f6", "baz"]
613 f4 = ["f5", "f7"]
614 f5 = ["f6"]
615 f6 = ["f7"]
616 f7 = ["bar"]
617
618 [dependencies.bar]
619 path = "bar"
620 optional = true
621
622 [dependencies.baz]
623 path = "baz"
624 optional = true
625 "#,
fecb7246
AC
626 )
627 .file(
1e682848
AC
628 "src/main.rs",
629 r#"
6f8c7d5a
EH
630 #[allow(unused_extern_crates)]
631 extern crate bar;
632 #[allow(unused_extern_crates)]
633 extern crate baz;
634 fn main() {}
635 "#,
fecb7246
AC
636 )
637 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
2b46d039 638 .file("bar/src/lib.rs", "pub fn bar() {}")
ab19c483 639 .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
d43ee1dd
NK
640 .file("baz/src/lib.rs", "pub fn baz() {}")
641 .build();
2b46d039 642
85984a87 643 p.cargo("build")
2cd9cce6 644 .with_stderr(
1e682848 645 "\
89f43938
ZL
646[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
647[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
648[COMPILING] foo v0.0.1 ([CWD])
34628b65 649[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 650",
fecb7246
AC
651 )
652 .run();
6950bbb0 653}
2b46d039 654
0e0d9688 655#[cargo_test]
6950bbb0 656fn many_cli_features() {
7fe2fbc8 657 let p = project()
1e682848
AC
658 .file(
659 "Cargo.toml",
660 r#"
6f8c7d5a
EH
661 [project]
662 name = "foo"
663 version = "0.0.1"
664 authors = []
2b46d039 665
6f8c7d5a
EH
666 [dependencies.bar]
667 path = "bar"
668 optional = true
2b46d039 669
6f8c7d5a
EH
670 [dependencies.baz]
671 path = "baz"
672 optional = true
673 "#,
fecb7246
AC
674 )
675 .file(
1e682848
AC
676 "src/main.rs",
677 r#"
6f8c7d5a
EH
678 #[allow(unused_extern_crates)]
679 extern crate bar;
680 #[allow(unused_extern_crates)]
681 extern crate baz;
682 fn main() {}
683 "#,
fecb7246
AC
684 )
685 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
2b46d039 686 .file("bar/src/lib.rs", "pub fn bar() {}")
ab19c483 687 .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
d43ee1dd
NK
688 .file("baz/src/lib.rs", "pub fn baz() {}")
689 .build();
2b46d039 690
85984a87
DW
691 p.cargo("build --features")
692 .arg("bar baz")
2cd9cce6 693 .with_stderr(
1e682848 694 "\
89f43938
ZL
695[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
696[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
697[COMPILING] foo v0.0.1 ([CWD])
34628b65 698[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 699",
fecb7246
AC
700 )
701 .run();
6950bbb0 702}
2b46d039 703
0e0d9688 704#[cargo_test]
6950bbb0 705fn union_features() {
7fe2fbc8 706 let p = project()
1e682848
AC
707 .file(
708 "Cargo.toml",
709 r#"
6f8c7d5a
EH
710 [project]
711 name = "foo"
712 version = "0.0.1"
713 authors = []
2b46d039 714
6f8c7d5a
EH
715 [dependencies.d1]
716 path = "d1"
717 features = ["f1"]
718 [dependencies.d2]
719 path = "d2"
720 features = ["f2"]
721 "#,
fecb7246
AC
722 )
723 .file(
1e682848
AC
724 "src/main.rs",
725 r#"
6f8c7d5a
EH
726 #[allow(unused_extern_crates)]
727 extern crate d1;
728 extern crate d2;
729 fn main() {
730 d2::f1();
731 d2::f2();
732 }
733 "#,
fecb7246
AC
734 )
735 .file(
1e682848
AC
736 "d1/Cargo.toml",
737 r#"
6f8c7d5a
EH
738 [package]
739 name = "d1"
740 version = "0.0.1"
741 authors = []
2b46d039 742
6f8c7d5a
EH
743 [features]
744 f1 = ["d2"]
2b46d039 745
6f8c7d5a
EH
746 [dependencies.d2]
747 path = "../d2"
748 features = ["f1"]
749 optional = true
750 "#,
fecb7246
AC
751 )
752 .file("d1/src/lib.rs", "")
1e682848
AC
753 .file(
754 "d2/Cargo.toml",
755 r#"
6f8c7d5a
EH
756 [package]
757 name = "d2"
758 version = "0.0.1"
759 authors = []
2b46d039 760
6f8c7d5a
EH
761 [features]
762 f1 = []
763 f2 = []
764 "#,
fecb7246
AC
765 )
766 .file(
1e682848
AC
767 "d2/src/lib.rs",
768 r#"
6f8c7d5a
EH
769 #[cfg(feature = "f1")] pub fn f1() {}
770 #[cfg(feature = "f2")] pub fn f2() {}
771 "#,
fecb7246
AC
772 )
773 .build();
2b46d039 774
85984a87 775 p.cargo("build")
2cd9cce6 776 .with_stderr(
1e682848 777 "\
89f43938
ZL
778[COMPILING] d2 v0.0.1 ([CWD]/d2)
779[COMPILING] d1 v0.0.1 ([CWD]/d1)
780[COMPILING] foo v0.0.1 ([CWD])
34628b65 781[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 782",
fecb7246
AC
783 )
784 .run();
6950bbb0 785}
99087dd3 786
0e0d9688 787#[cargo_test]
6950bbb0 788fn many_features_no_rebuilds() {
7fe2fbc8 789 let p = project()
1e682848
AC
790 .file(
791 "Cargo.toml",
792 r#"
6f8c7d5a
EH
793 [package]
794 name = "b"
795 version = "0.1.0"
796 authors = []
99087dd3 797
6f8c7d5a
EH
798 [dependencies.a]
799 path = "a"
800 features = ["fall"]
801 "#,
fecb7246
AC
802 )
803 .file("src/main.rs", "fn main() {}")
1e682848
AC
804 .file(
805 "a/Cargo.toml",
806 r#"
6f8c7d5a
EH
807 [package]
808 name = "a"
809 version = "0.1.0"
810 authors = []
99087dd3 811
6f8c7d5a
EH
812 [features]
813 ftest = []
814 ftest2 = []
815 fall = ["ftest", "ftest2"]
816 "#,
fecb7246
AC
817 )
818 .file("a/src/lib.rs", "")
d43ee1dd 819 .build();
99087dd3 820
85984a87 821 p.cargo("build")
2cd9cce6 822 .with_stderr(
1e682848 823 "\
89f43938
ZL
824[COMPILING] a v0.1.0 ([CWD]/a)
825[COMPILING] b v0.1.0 ([CWD])
34628b65 826[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 827",
fecb7246
AC
828 )
829 .run();
763ba535 830 p.root().move_into_the_past();
99087dd3 831
85984a87
DW
832 p.cargo("build -v")
833 .with_stderr(
1e682848 834 "\
29cdad4f
AK
835[FRESH] a v0.1.0 ([..]/a)
836[FRESH] b v0.1.0 ([..])
34628b65 837[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 838",
fecb7246
AC
839 )
840 .run();
6950bbb0 841}
e53e981d
VH
842
843// Tests that all cmd lines work with `--features ""`
0e0d9688 844#[cargo_test]
6950bbb0 845fn empty_features() {
85984a87 846 let p = project().file("src/main.rs", "fn main() {}").build();
e53e981d 847
85984a87 848 p.cargo("build --features").arg("").run();
6950bbb0 849}
f5f34e85
AC
850
851// Tests that all cmd lines work with `--features ""`
0e0d9688 852#[cargo_test]
6950bbb0 853fn transitive_features() {
7fe2fbc8 854 let p = project()
1e682848
AC
855 .file(
856 "Cargo.toml",
857 r#"
6f8c7d5a
EH
858 [project]
859 name = "foo"
860 version = "0.0.1"
861 authors = []
f5f34e85 862
6f8c7d5a
EH
863 [features]
864 foo = ["bar/baz"]
f5f34e85 865
6f8c7d5a
EH
866 [dependencies.bar]
867 path = "bar"
868 "#,
fecb7246
AC
869 )
870 .file("src/main.rs", "extern crate bar; fn main() { bar::baz(); }")
1e682848
AC
871 .file(
872 "bar/Cargo.toml",
873 r#"
6f8c7d5a
EH
874 [package]
875 name = "bar"
876 version = "0.0.1"
877 authors = []
f5f34e85 878
6f8c7d5a
EH
879 [features]
880 baz = []
881 "#,
fecb7246
AC
882 )
883 .file(
85984a87
DW
884 "bar/src/lib.rs",
885 r#"#[cfg(feature = "baz")] pub fn baz() {}"#,
fecb7246
AC
886 )
887 .build();
f5f34e85 888
85984a87 889 p.cargo("build --features foo").run();
6950bbb0 890}
8670b56a 891
0e0d9688 892#[cargo_test]
6950bbb0 893fn everything_in_the_lockfile() {
7fe2fbc8 894 let p = project()
1e682848
AC
895 .file(
896 "Cargo.toml",
897 r#"
6f8c7d5a
EH
898 [project]
899 name = "foo"
900 version = "0.0.1"
901 authors = []
8670b56a 902
6f8c7d5a
EH
903 [features]
904 f1 = ["d1/f1"]
905 f2 = ["d2"]
906
907 [dependencies.d1]
908 path = "d1"
909 [dependencies.d2]
910 path = "d2"
911 optional = true
912 [dependencies.d3]
913 path = "d3"
914 optional = true
915 "#,
fecb7246
AC
916 )
917 .file("src/main.rs", "fn main() {}")
1e682848
AC
918 .file(
919 "d1/Cargo.toml",
920 r#"
6f8c7d5a
EH
921 [package]
922 name = "d1"
923 version = "0.0.1"
924 authors = []
8670b56a 925
6f8c7d5a
EH
926 [features]
927 f1 = []
928 "#,
fecb7246
AC
929 )
930 .file("d1/src/lib.rs", "")
ab19c483 931 .file("d2/Cargo.toml", &basic_manifest("d2", "0.0.2"))
8670b56a 932 .file("d2/src/lib.rs", "")
1e682848
AC
933 .file(
934 "d3/Cargo.toml",
935 r#"
6f8c7d5a
EH
936 [package]
937 name = "d3"
938 version = "0.0.3"
939 authors = []
8670b56a 940
6f8c7d5a
EH
941 [features]
942 f3 = []
943 "#,
fecb7246
AC
944 )
945 .file("d3/src/lib.rs", "")
d43ee1dd 946 .build();
8670b56a 947
85984a87 948 p.cargo("fetch").run();
4ae79d2f 949 let lockfile = p.read_lockfile();
1e682848
AC
950 assert!(
951 lockfile.contains(r#"name = "d1""#),
952 "d1 not found\n{}",
953 lockfile
954 );
955 assert!(
956 lockfile.contains(r#"name = "d2""#),
957 "d2 not found\n{}",
958 lockfile
959 );
960 assert!(
961 lockfile.contains(r#"name = "d3""#),
962 "d3 not found\n{}",
963 lockfile
964 );
6950bbb0 965}
40d1c10a 966
0e0d9688 967#[cargo_test]
6950bbb0 968fn no_rebuild_when_frobbing_default_feature() {
7fe2fbc8 969 let p = project()
1e682848
AC
970 .file(
971 "Cargo.toml",
972 r#"
6f8c7d5a
EH
973 [package]
974 name = "foo"
975 version = "0.1.0"
976 authors = []
40d1c10a 977
6f8c7d5a
EH
978 [dependencies]
979 a = { path = "a" }
980 b = { path = "b" }
981 "#,
fecb7246
AC
982 )
983 .file("src/lib.rs", "")
1e682848
AC
984 .file(
985 "b/Cargo.toml",
986 r#"
6f8c7d5a
EH
987 [package]
988 name = "b"
989 version = "0.1.0"
990 authors = []
40d1c10a 991
6f8c7d5a
EH
992 [dependencies]
993 a = { path = "../a", features = ["f1"], default-features = false }
994 "#,
fecb7246
AC
995 )
996 .file("b/src/lib.rs", "")
1e682848
AC
997 .file(
998 "a/Cargo.toml",
999 r#"
6f8c7d5a
EH
1000 [package]
1001 name = "a"
1002 version = "0.1.0"
1003 authors = []
40d1c10a 1004
6f8c7d5a
EH
1005 [features]
1006 default = ["f1"]
1007 f1 = []
1008 "#,
fecb7246
AC
1009 )
1010 .file("a/src/lib.rs", "")
d43ee1dd 1011 .build();
40d1c10a 1012
85984a87
DW
1013 p.cargo("build").run();
1014 p.cargo("build").with_stdout("").run();
1015 p.cargo("build").with_stdout("").run();
6950bbb0 1016}
0ba5a7a2 1017
0e0d9688 1018#[cargo_test]
6950bbb0 1019fn unions_work_with_no_default_features() {
7fe2fbc8 1020 let p = project()
1e682848
AC
1021 .file(
1022 "Cargo.toml",
1023 r#"
6f8c7d5a
EH
1024 [package]
1025 name = "foo"
1026 version = "0.1.0"
1027 authors = []
0ba5a7a2 1028
6f8c7d5a
EH
1029 [dependencies]
1030 a = { path = "a" }
1031 b = { path = "b" }
1032 "#,
fecb7246
AC
1033 )
1034 .file("src/lib.rs", "extern crate a; pub fn foo() { a::a(); }")
1e682848
AC
1035 .file(
1036 "b/Cargo.toml",
1037 r#"
6f8c7d5a
EH
1038 [package]
1039 name = "b"
1040 version = "0.1.0"
1041 authors = []
0ba5a7a2 1042
6f8c7d5a
EH
1043 [dependencies]
1044 a = { path = "../a", features = [], default-features = false }
1045 "#,
fecb7246
AC
1046 )
1047 .file("b/src/lib.rs", "")
1e682848
AC
1048 .file(
1049 "a/Cargo.toml",
1050 r#"
6f8c7d5a
EH
1051 [package]
1052 name = "a"
1053 version = "0.1.0"
1054 authors = []
0ba5a7a2 1055
6f8c7d5a
EH
1056 [features]
1057 default = ["f1"]
1058 f1 = []
1059 "#,
fecb7246
AC
1060 )
1061 .file("a/src/lib.rs", r#"#[cfg(feature = "f1")] pub fn a() {}"#)
d43ee1dd 1062 .build();
0ba5a7a2 1063
85984a87
DW
1064 p.cargo("build").run();
1065 p.cargo("build").with_stdout("").run();
1066 p.cargo("build").with_stdout("").run();
6950bbb0 1067}
70152d80 1068
0e0d9688 1069#[cargo_test]
6950bbb0 1070fn optional_and_dev_dep() {
7fe2fbc8 1071 let p = project()
1e682848
AC
1072 .file(
1073 "Cargo.toml",
1074 r#"
6f8c7d5a
EH
1075 [package]
1076 name = "test"
1077 version = "0.1.0"
1078 authors = []
70152d80 1079
6f8c7d5a
EH
1080 [dependencies]
1081 foo = { path = "foo", optional = true }
1082 [dev-dependencies]
1083 foo = { path = "foo" }
1084 "#,
fecb7246
AC
1085 )
1086 .file("src/lib.rs", "")
ab19c483 1087 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
d43ee1dd
NK
1088 .file("foo/src/lib.rs", "")
1089 .build();
70152d80 1090
85984a87
DW
1091 p.cargo("build")
1092 .with_stderr(
1e682848 1093 "\
29cdad4f 1094[COMPILING] test v0.1.0 ([..])
34628b65 1095[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 1096",
fecb7246
AC
1097 )
1098 .run();
6950bbb0 1099}
e2e1751a 1100
0e0d9688 1101#[cargo_test]
6950bbb0 1102fn activating_feature_activates_dep() {
7fe2fbc8 1103 let p = project()
1e682848
AC
1104 .file(
1105 "Cargo.toml",
1106 r#"
6f8c7d5a
EH
1107 [package]
1108 name = "test"
1109 version = "0.1.0"
1110 authors = []
e2e1751a 1111
6f8c7d5a
EH
1112 [dependencies]
1113 foo = { path = "foo", optional = true }
e2e1751a 1114
6f8c7d5a
EH
1115 [features]
1116 a = ["foo/a"]
1117 "#,
fecb7246
AC
1118 )
1119 .file(
85984a87
DW
1120 "src/lib.rs",
1121 "extern crate foo; pub fn bar() { foo::bar(); }",
fecb7246
AC
1122 )
1123 .file(
1e682848
AC
1124 "foo/Cargo.toml",
1125 r#"
6f8c7d5a
EH
1126 [package]
1127 name = "foo"
1128 version = "0.1.0"
1129 authors = []
e2e1751a 1130
6f8c7d5a
EH
1131 [features]
1132 a = []
1133 "#,
fecb7246
AC
1134 )
1135 .file("foo/src/lib.rs", r#"#[cfg(feature = "a")] pub fn bar() {}"#)
d43ee1dd 1136 .build();
e2e1751a 1137
85984a87 1138 p.cargo("build --features a -v").run();
6950bbb0 1139}
6f28ef2d 1140
0e0d9688 1141#[cargo_test]
6f28ef2d 1142fn dep_feature_in_cmd_line() {
7fe2fbc8 1143 let p = project()
1e682848
AC
1144 .file(
1145 "Cargo.toml",
1146 r#"
6f8c7d5a
EH
1147 [project]
1148 name = "foo"
1149 version = "0.0.1"
1150 authors = []
6f28ef2d 1151
6f8c7d5a
EH
1152 [dependencies.derived]
1153 path = "derived"
1154 "#,
fecb7246
AC
1155 )
1156 .file(
1e682848
AC
1157 "src/main.rs",
1158 r#"
6f8c7d5a
EH
1159 extern crate derived;
1160 fn main() { derived::test(); }
1161 "#,
fecb7246
AC
1162 )
1163 .file(
1e682848
AC
1164 "derived/Cargo.toml",
1165 r#"
6f8c7d5a
EH
1166 [package]
1167 name = "derived"
1168 version = "0.0.1"
1169 authors = []
6f28ef2d 1170
6f8c7d5a
EH
1171 [dependencies.bar]
1172 path = "../bar"
6f28ef2d 1173
6f8c7d5a
EH
1174 [features]
1175 default = []
1176 derived-feat = ["bar/some-feat"]
1177 "#,
fecb7246
AC
1178 )
1179 .file("derived/src/lib.rs", "extern crate bar; pub use bar::test;")
1e682848
AC
1180 .file(
1181 "bar/Cargo.toml",
1182 r#"
6f8c7d5a
EH
1183 [package]
1184 name = "bar"
1185 version = "0.0.1"
1186 authors = []
6f28ef2d 1187
6f8c7d5a
EH
1188 [features]
1189 some-feat = []
1190 "#,
fecb7246
AC
1191 )
1192 .file(
1e682848
AC
1193 "bar/src/lib.rs",
1194 r#"
6f8c7d5a
EH
1195 #[cfg(feature = "some-feat")]
1196 pub fn test() { print!("test"); }
1197 "#,
fecb7246
AC
1198 )
1199 .build();
6f28ef2d
BF
1200
1201 // The foo project requires that feature "some-feat" in "bar" is enabled.
1202 // Building without any features enabled should fail:
f58d107e
EH
1203 p.cargo("build")
1204 .with_status(101)
1205 .with_stderr_contains("[..]unresolved import `bar::test`")
1206 .run();
6f28ef2d
BF
1207
1208 // We should be able to enable the feature "derived-feat", which enables "some-feat",
1209 // on the command line. The feature is enabled, thus building should be successful:
85984a87 1210 p.cargo("build --features derived/derived-feat").run();
6f28ef2d
BF
1211
1212 // Trying to enable features of transitive dependencies is an error
85984a87
DW
1213 p.cargo("build --features bar/some-feat")
1214 .with_status(101)
bcfdf9fb 1215 .with_stderr("error: package `foo v0.0.1 ([..])` does not have a dependency named `bar`")
85984a87 1216 .run();
6f28ef2d
BF
1217
1218 // Hierarchical feature specification should still be disallowed
85984a87
DW
1219 p.cargo("build --features derived/bar/some-feat")
1220 .with_status(101)
85854b18 1221 .with_stderr("[ERROR] multiple slashes in feature `derived/bar/some-feat` is not allowed")
85984a87 1222 .run();
1f88ad53 1223}
1f8b3988 1224
0e0d9688 1225#[cargo_test]
1f8b3988 1226fn all_features_flag_enables_all_features() {
7fe2fbc8 1227 let p = project()
1e682848
AC
1228 .file(
1229 "Cargo.toml",
1230 r#"
6f8c7d5a
EH
1231 [project]
1232 name = "foo"
1233 version = "0.0.1"
1234 authors = []
1f8b3988 1235
6f8c7d5a
EH
1236 [features]
1237 foo = []
1238 bar = []
1f8b3988 1239
6f8c7d5a
EH
1240 [dependencies.baz]
1241 path = "baz"
1242 optional = true
1243 "#,
fecb7246
AC
1244 )
1245 .file(
1e682848
AC
1246 "src/main.rs",
1247 r#"
6f8c7d5a
EH
1248 #[cfg(feature = "foo")]
1249 pub fn foo() {}
1f8b3988 1250
6f8c7d5a
EH
1251 #[cfg(feature = "bar")]
1252 pub fn bar() {
1253 extern crate baz;
1254 baz::baz();
1255 }
1f8b3988 1256
6f8c7d5a
EH
1257 fn main() {
1258 foo();
1259 bar();
1260 }
1261 "#,
fecb7246
AC
1262 )
1263 .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
d43ee1dd
NK
1264 .file("baz/src/lib.rs", "pub fn baz() {}")
1265 .build();
1f8b3988 1266
85984a87 1267 p.cargo("build --all-features").run();
1f8b3988 1268}
72f84271 1269
0e0d9688 1270#[cargo_test]
72f84271 1271fn many_cli_features_comma_delimited() {
7fe2fbc8 1272 let p = project()
1e682848
AC
1273 .file(
1274 "Cargo.toml",
1275 r#"
6f8c7d5a
EH
1276 [project]
1277 name = "foo"
1278 version = "0.0.1"
1279 authors = []
72f84271 1280
6f8c7d5a
EH
1281 [dependencies.bar]
1282 path = "bar"
1283 optional = true
72f84271 1284
6f8c7d5a
EH
1285 [dependencies.baz]
1286 path = "baz"
1287 optional = true
1288 "#,
fecb7246
AC
1289 )
1290 .file(
1e682848
AC
1291 "src/main.rs",
1292 r#"
6f8c7d5a
EH
1293 #[allow(unused_extern_crates)]
1294 extern crate bar;
1295 #[allow(unused_extern_crates)]
1296 extern crate baz;
1297 fn main() {}
1298 "#,
fecb7246
AC
1299 )
1300 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
72f84271 1301 .file("bar/src/lib.rs", "pub fn bar() {}")
ab19c483 1302 .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
d43ee1dd
NK
1303 .file("baz/src/lib.rs", "pub fn baz() {}")
1304 .build();
72f84271 1305
85984a87 1306 p.cargo("build --features bar,baz")
2cd9cce6 1307 .with_stderr(
1e682848 1308 "\
89f43938
ZL
1309[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
1310[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
1311[COMPILING] foo v0.0.1 ([CWD])
72f84271 1312[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 1313",
fecb7246
AC
1314 )
1315 .run();
72f84271
RV
1316}
1317
0e0d9688 1318#[cargo_test]
72f84271 1319fn many_cli_features_comma_and_space_delimited() {
7fe2fbc8 1320 let p = project()
1e682848
AC
1321 .file(
1322 "Cargo.toml",
1323 r#"
6f8c7d5a
EH
1324 [project]
1325 name = "foo"
1326 version = "0.0.1"
1327 authors = []
72f84271 1328
6f8c7d5a
EH
1329 [dependencies.bar]
1330 path = "bar"
1331 optional = true
72f84271 1332
6f8c7d5a
EH
1333 [dependencies.baz]
1334 path = "baz"
1335 optional = true
72f84271 1336
6f8c7d5a
EH
1337 [dependencies.bam]
1338 path = "bam"
1339 optional = true
72f84271 1340
6f8c7d5a
EH
1341 [dependencies.bap]
1342 path = "bap"
1343 optional = true
1344 "#,
fecb7246
AC
1345 )
1346 .file(
1e682848
AC
1347 "src/main.rs",
1348 r#"
6f8c7d5a
EH
1349 #[allow(unused_extern_crates)]
1350 extern crate bar;
1351 #[allow(unused_extern_crates)]
1352 extern crate baz;
1353 #[allow(unused_extern_crates)]
1354 extern crate bam;
1355 #[allow(unused_extern_crates)]
1356 extern crate bap;
1357 fn main() {}
1358 "#,
fecb7246
AC
1359 )
1360 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
72f84271 1361 .file("bar/src/lib.rs", "pub fn bar() {}")
ab19c483 1362 .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
72f84271 1363 .file("baz/src/lib.rs", "pub fn baz() {}")
ab19c483 1364 .file("bam/Cargo.toml", &basic_manifest("bam", "0.0.1"))
72f84271 1365 .file("bam/src/lib.rs", "pub fn bam() {}")
ab19c483 1366 .file("bap/Cargo.toml", &basic_manifest("bap", "0.0.1"))
d43ee1dd
NK
1367 .file("bap/src/lib.rs", "pub fn bap() {}")
1368 .build();
72f84271 1369
85984a87
DW
1370 p.cargo("build --features")
1371 .arg("bar,baz bam bap")
2cd9cce6 1372 .with_stderr(
1e682848 1373 "\
89f43938
ZL
1374[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
1375[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
1376[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
1377[COMPILING] ba[..] v0.0.1 ([CWD]/ba[..])
1378[COMPILING] foo v0.0.1 ([CWD])
72f84271 1379[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 1380",
fecb7246
AC
1381 )
1382 .run();
72f84271 1383}
8d0b31b9 1384
0e0d9688 1385#[cargo_test]
02b0dba3
AC
1386fn only_dep_is_optional() {
1387 Package::new("bar", "0.1.0").publish();
1388
7fe2fbc8 1389 let p = project()
02b0dba3
AC
1390 .file(
1391 "Cargo.toml",
1392 r#"
1393 [project]
1394 name = "foo"
1395 version = "0.0.1"
1396 authors = []
1397
1398 [features]
1399 foo = ['bar']
1400
1401 [dependencies]
1402 bar = { version = "0.1", optional = true }
1403
1404 [dev-dependencies]
1405 bar = "0.1"
1406 "#,
fecb7246
AC
1407 )
1408 .file("src/main.rs", "fn main() {}")
02b0dba3
AC
1409 .build();
1410
85984a87 1411 p.cargo("build").run();
02b0dba3 1412}
a70d5197 1413
0e0d9688 1414#[cargo_test]
a70d5197
AC
1415fn all_features_all_crates() {
1416 Package::new("bar", "0.1.0").publish();
1417
7fe2fbc8 1418 let p = project()
a70d5197
AC
1419 .file(
1420 "Cargo.toml",
1421 r#"
1422 [project]
1423 name = "foo"
1424 version = "0.0.1"
1425 authors = []
1426
1427 [workspace]
1428 members = ['bar']
1429 "#,
fecb7246
AC
1430 )
1431 .file("src/main.rs", "fn main() {}")
a70d5197
AC
1432 .file(
1433 "bar/Cargo.toml",
1434 r#"
1435 [project]
1436 name = "bar"
1437 version = "0.0.1"
1438 authors = []
1439
1440 [features]
1441 foo = []
1442 "#,
fecb7246
AC
1443 )
1444 .file("bar/src/main.rs", "#[cfg(feature = \"foo\")] fn main() {}")
a70d5197
AC
1445 .build();
1446
ecf824f7 1447 p.cargo("build --all-features --workspace").run();
a70d5197 1448}
b29d4d48 1449
0e0d9688 1450#[cargo_test]
b29d4d48
EH
1451fn feature_off_dylib() {
1452 let p = project()
1453 .file(
1454 "Cargo.toml",
1455 r#"
6f8c7d5a
EH
1456 [workspace]
1457 members = ["bar"]
b29d4d48 1458
6f8c7d5a
EH
1459 [package]
1460 name = "foo"
1461 version = "0.0.1"
b29d4d48 1462
6f8c7d5a
EH
1463 [lib]
1464 crate-type = ["dylib"]
b29d4d48 1465
6f8c7d5a
EH
1466 [features]
1467 f1 = []
1468 "#,
b29d4d48
EH
1469 )
1470 .file(
1471 "src/lib.rs",
1472 r#"
6f8c7d5a
EH
1473 pub fn hello() -> &'static str {
1474 if cfg!(feature = "f1") {
1475 "f1"
1476 } else {
1477 "no f1"
1478 }
b29d4d48 1479 }
6f8c7d5a 1480 "#,
b29d4d48
EH
1481 )
1482 .file(
1483 "bar/Cargo.toml",
1484 r#"
6f8c7d5a
EH
1485 [package]
1486 name = "bar"
1487 version = "0.0.1"
b29d4d48 1488
6f8c7d5a
EH
1489 [dependencies]
1490 foo = { path = ".." }
1491 "#,
b29d4d48
EH
1492 )
1493 .file(
1494 "bar/src/main.rs",
1495 r#"
6f8c7d5a 1496 extern crate foo;
b29d4d48 1497
6f8c7d5a
EH
1498 fn main() {
1499 assert_eq!(foo::hello(), "no f1");
1500 }
1501 "#,
b29d4d48
EH
1502 )
1503 .build();
1504
1505 // Build the dylib with `f1` feature.
1506 p.cargo("build --features f1").run();
1507 // Check that building without `f1` uses a dylib without `f1`.
1508 p.cargo("run -p bar").run();
1509}
86037b8a 1510
0e0d9688 1511#[cargo_test]
86037b8a
FB
1512fn warn_if_default_features() {
1513 let p = project()
1514 .file(
1515 "Cargo.toml",
1516 r#"
6f8c7d5a
EH
1517 [project]
1518 name = "foo"
1519 version = "0.0.1"
1520 authors = []
86037b8a 1521
6f8c7d5a
EH
1522 [dependencies.bar]
1523 path = "bar"
1524 optional = true
86037b8a 1525
6f8c7d5a
EH
1526 [features]
1527 default-features = ["bar"]
1528 "#,
fecb7246
AC
1529 )
1530 .file("src/main.rs", "fn main() {}")
1531 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
86037b8a
FB
1532 .file("bar/src/lib.rs", "pub fn bar() {}")
1533 .build();
1534
1535 p.cargo("build")
d522344f
FB
1536 .with_stderr(
1537 r#"
1538[WARNING] `default-features = [".."]` was found in [features]. Did you mean to use `default = [".."]`?
86037b8a
FB
1539[COMPILING] foo v0.0.1 ([CWD])
1540[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
d522344f 1541 "#.trim(),
86037b8a
FB
1542 ).run();
1543}
dbc2c2b5 1544
0e0d9688 1545#[cargo_test]
dbc2c2b5
AC
1546fn no_feature_for_non_optional_dep() {
1547 let p = project()
1548 .file(
1549 "Cargo.toml",
1550 r#"
1551 [project]
1552 name = "foo"
1553 version = "0.0.1"
1554 authors = []
1555
1556 [dependencies]
1557 bar = { path = "bar" }
6f8c7d5a 1558 "#,
dbc2c2b5
AC
1559 )
1560 .file(
1561 "src/main.rs",
1562 r#"
1563 #[cfg(not(feature = "bar"))]
1564 fn main() {
1565 }
1566 "#,
1567 )
1568 .file(
1569 "bar/Cargo.toml",
1570 r#"
1571 [project]
1572 name = "bar"
1573 version = "0.0.1"
1574 authors = []
1575
1576 [features]
1577 a = []
6f8c7d5a 1578 "#,
dbc2c2b5
AC
1579 )
1580 .file("bar/src/lib.rs", "pub fn bar() {}")
1581 .build();
1582
1583 p.cargo("build --features bar/a").run();
1584}
51c26b67
WVM
1585
1586#[cargo_test]
1587fn features_option_given_twice() {
1588 let p = project()
1589 .file(
1590 "Cargo.toml",
1591 r#"
1592 [project]
1593 name = "foo"
1594 version = "0.0.1"
1595 authors = []
1596
1597 [features]
1598 a = []
1599 b = []
6f8c7d5a 1600 "#,
51c26b67
WVM
1601 )
1602 .file(
1603 "src/main.rs",
1604 r#"
1605 #[cfg(all(feature = "a", feature = "b"))]
1606 fn main() {}
1607 "#,
1608 )
1609 .build();
1610
1611 p.cargo("build --features a --features b").run();
1612}
1613
1614#[cargo_test]
1615fn multi_multi_features() {
1616 let p = project()
1617 .file(
1618 "Cargo.toml",
1619 r#"
1620 [project]
1621 name = "foo"
1622 version = "0.0.1"
1623 authors = []
1624
1625 [features]
1626 a = []
1627 b = []
1628 c = []
1629 "#,
1630 )
1631 .file(
1632 "src/main.rs",
1633 r#"
1634 #[cfg(all(feature = "a", feature = "b", feature = "c"))]
1635 fn main() {}
1636 "#,
1637 )
1638 .build();
1639
1640 p.cargo("build --features a --features").arg("b c").run();
1641}
1fa02e77
AC
1642
1643#[cargo_test]
1644fn cli_parse_ok() {
1645 let p = project()
1646 .file(
1647 "Cargo.toml",
1648 r#"
1649 [project]
1650 name = "foo"
1651 version = "0.0.1"
1652 authors = []
1653
1654 [features]
1655 a = []
1656 "#,
1657 )
1658 .file(
1659 "src/main.rs",
1660 r#"
1661 #[cfg(feature = "a")]
1662 fn main() {
1663 assert_eq!(std::env::args().nth(1).unwrap(), "b");
1664 }
1665 "#,
1666 )
1667 .build();
1668
1669 p.cargo("run --features a b").run();
1670}
bf474ba5
EH
1671
1672#[cargo_test]
4d524ea5
EH
1673fn all_features_virtual_ws() {
1674 // What happens with `--all-features` in the root of a virtual workspace.
1675 // Some of this behavior is a little strange (member dependencies also
1676 // have all features enabled, one might expect `f4` to be disabled).
1677 let p = project()
1678 .file(
1679 "Cargo.toml",
1680 r#"
1681 [workspace]
1682 members = ["a", "b"]
1683 "#,
1684 )
1685 .file(
1686 "a/Cargo.toml",
1687 r#"
1688 [package]
1689 name = "a"
1690 version = "0.1.0"
1691 edition = "2018"
1692
1693 [dependencies]
1694 b = {path="../b", optional=true}
1695
1696 [features]
1697 default = ["f1"]
1698 f1 = []
1699 f2 = []
1700 "#,
1701 )
1702 .file(
1703 "a/src/main.rs",
1704 r#"
1705 fn main() {
1706 if cfg!(feature="f1") {
1707 println!("f1");
1708 }
1709 if cfg!(feature="f2") {
1710 println!("f2");
1711 }
1712 #[cfg(feature="b")]
1713 b::f();
1714 }
1715 "#,
1716 )
1717 .file(
1718 "b/Cargo.toml",
1719 r#"
1720 [package]
1721 name = "b"
1722 version = "0.1.0"
1723
1724 [features]
1725 default = ["f3"]
1726 f3 = []
1727 f4 = []
1728 "#,
1729 )
1730 .file(
1731 "b/src/lib.rs",
1732 r#"
1733 pub fn f() {
1734 if cfg!(feature="f3") {
1735 println!("f3");
1736 }
1737 if cfg!(feature="f4") {
1738 println!("f4");
1739 }
1740 }
1741 "#,
1742 )
1743 .build();
1744
1745 p.cargo("run").with_stdout("f1\n").run();
1746 p.cargo("run --all-features")
1747 .with_stdout("f1\nf2\nf3\nf4\n")
1748 .run();
1749 // In `a`, it behaves differently. :(
1750 p.cargo("run --all-features")
1751 .cwd("a")
1752 .with_stdout("f1\nf2\nf3\n")
1753 .run();
1754}
7caa1612
EH
1755
1756#[cargo_test]
1757fn slash_optional_enables() {
1758 // --features dep/feat will enable `dep` and set its feature.
1759 let p = project()
1760 .file(
1761 "Cargo.toml",
1762 r#"
1763 [package]
1764 name = "foo"
1765 version = "0.1.0"
1766
1767 [dependencies]
1768 dep = {path="dep", optional=true}
1769 "#,
1770 )
1771 .file(
1772 "src/lib.rs",
1773 r#"
1774 #[cfg(not(feature="dep"))]
1775 compile_error!("dep not set");
1776 "#,
1777 )
1778 .file(
1779 "dep/Cargo.toml",
1780 r#"
1781 [package]
1782 name = "dep"
1783 version = "0.1.0"
1784
1785 [features]
1786 feat = []
1787 "#,
1788 )
1789 .file(
1790 "dep/src/lib.rs",
1791 r#"
1792 #[cfg(not(feature="feat"))]
1793 compile_error!("feat not set");
1794 "#,
1795 )
1796 .build();
1797
1798 p.cargo("check")
1799 .with_status(101)
1800 .with_stderr_contains("[..]dep not set[..]")
1801 .run();
1802
1803 p.cargo("check --features dep/feat").run();
1804}
ab73b2c3
EH
1805
1806#[cargo_test]
1807fn registry_summary_order_doesnt_matter() {
1808 // Checks for an issue where the resolver depended on the order of entries
1809 // in the registry summary. If there was a non-optional dev-dependency
1810 // that appeared before an optional normal dependency, then the resolver
1811 // would not activate the optional dependency with a pkg/featname feature
1812 // syntax.
1813 Package::new("dep", "0.1.0")
1814 .feature("feat1", &[])
1815 .file(
1816 "src/lib.rs",
1817 r#"
1818 #[cfg(feature="feat1")]
1819 pub fn work() {
1820 println!("it works");
1821 }
1822 "#,
1823 )
1824 .publish();
1825 Package::new("bar", "0.1.0")
1826 .feature("bar_feat", &["dep/feat1"])
1827 .add_dep(Dependency::new("dep", "0.1.0").dev())
1828 .add_dep(Dependency::new("dep", "0.1.0").optional(true))
1829 .file(
1830 "src/lib.rs",
1831 r#"
1832 // This will fail to compile without `dep` optional dep activated.
1833 extern crate dep;
1834
1835 pub fn doit() {
1836 dep::work();
1837 }
1838 "#,
1839 )
1840 .publish();
1841
1842 let p = project()
1843 .file(
1844 "Cargo.toml",
1845 r#"
1846 [package]
1847 name = "foo"
1848 version = "0.1.0"
1849 edition = "2018"
1850
1851 [dependencies]
1852 bar = { version="0.1", features = ["bar_feat"] }
1853 "#,
1854 )
1855 .file(
1856 "src/main.rs",
1857 r#"
1858 fn main() {
1859 bar::doit();
1860 }
1861 "#,
1862 )
1863 .build();
1864
1865 p.cargo("run")
1866 .with_stderr(
1867 "\
1868[UPDATING] [..]
1869[DOWNLOADING] crates ...
1870[DOWNLOADED] [..]
1871[DOWNLOADED] [..]
1872[COMPILING] dep v0.1.0
1873[COMPILING] bar v0.1.0
1874[COMPILING] foo v0.1.0 [..]
1875[FINISHED] [..]
1876[RUNNING] `target/debug/foo[EXE]`
1877",
1878 )
1879 .with_stdout("it works")
1880 .run();
1881}
19a95790
AT
1882
1883#[cargo_test]
1884fn nonexistent_required_features() {
1885 Package::new("required_dependency", "0.1.0")
1886 .feature("simple", &[])
1887 .publish();
1888 Package::new("optional_dependency", "0.2.0")
1889 .feature("optional", &[])
1890 .publish();
1891 let p = project()
1892 .file(
1893 "Cargo.toml",
1894 r#"
1895 [project]
1896 name = "foo"
1897 version = "0.1.0"
1898 [features]
1899 existing = []
1900 fancy = ["optional_dependency"]
1901 [dependencies]
1902 required_dependency = { version = "0.1", optional = false}
1903 optional_dependency = { version = "0.2", optional = true}
1904 [[example]]
1905 name = "ololo"
1906 required-features = ["not_present",
1907 "existing",
1908 "fancy",
1909 "required_dependency/not_existing",
1910 "required_dependency/simple",
1911 "optional_dependency/optional",
6f8c7d5a
EH
1912 "not_specified_dependency/some_feature"]
1913 "#,
19a95790
AT
1914 )
1915 .file("src/main.rs", "fn main() {}")
1916 .file("examples/ololo.rs", "fn main() {}")
1917 .build();
1918
1919 p.cargo("build --examples")
1920 .with_stderr_contains(
bcfdf9fb
EH
1921 "\
1922[WARNING] invalid feature `not_present` in required-features of target `ololo`: \
1923 `not_present` is not present in [features] section
1924[WARNING] invalid feature `required_dependency/not_existing` in required-features \
1925 of target `ololo`: feature `not_existing` does not exist in package \
1926 `required_dependency v0.1.0`
1927[WARNING] invalid feature `not_specified_dependency/some_feature` in required-features \
1928 of target `ololo`: dependency `not_specified_dependency` does not exist
6f8c7d5a 1929",
19a95790
AT
1930 )
1931 .run();
1932}
b731190d
EH
1933
1934#[cargo_test]
85854b18 1935fn invalid_feature_names_warning() {
b731190d
EH
1936 // Warnings for more restricted feature syntax.
1937 let p = project()
1938 .file(
1939 "Cargo.toml",
1940 r#"
1941 [package]
1942 name = "foo"
1943 version = "0.1.0"
1944
1945 [features]
1946 # Some valid, but unusual names, shouldn't warn.
1947 "c++17" = []
1948 "128bit" = []
1949 "_foo" = []
1950 "feat-name" = []
1951 "feat_name" = []
ea1a73a1 1952 "foo.bar" = []
b731190d
EH
1953
1954 # Invalid names.
1955 "+foo" = []
1956 "-foo" = []
1957 ".foo" = []
b731190d 1958 "foo:bar" = []
b731190d
EH
1959 "foo?" = []
1960 "?foo" = []
1961 "ⒶⒷⒸ" = []
1962 "a¼" = []
1963 "#,
1964 )
1965 .file("src/lib.rs", "")
1966 .build();
1967
1968 // Unfortunately the warnings are duplicated due to the Summary being
1969 // loaded twice (once in the Workspace, and once in PackageRegistry) and
1970 // Cargo does not have a de-duplication system. This should probably be
1971 // OK, since I'm not expecting this to affect anyone.
1972 p.cargo("check")
1973 .with_stderr("\
1974[WARNING] invalid character `+` in feature `+foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
1975This was previously accepted but is being phased out; it will become a hard error in a future release.
1976For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
1977[WARNING] invalid character `-` in feature `-foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
1978This was previously accepted but is being phased out; it will become a hard error in a future release.
1979For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
1980[WARNING] invalid character `.` in feature `.foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
1981This was previously accepted but is being phased out; it will become a hard error in a future release.
1982For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
1983[WARNING] invalid character `?` in feature `?foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
1984This was previously accepted but is being phased out; it will become a hard error in a future release.
1985For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 1986[WARNING] invalid character `¼` in feature `a¼` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
1987This was previously accepted but is being phased out; it will become a hard error in a future release.
1988For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 1989[WARNING] invalid character `:` in feature `foo:bar` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
1990This was previously accepted but is being phased out; it will become a hard error in a future release.
1991For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 1992[WARNING] invalid character `?` in feature `foo?` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
1993This was previously accepted but is being phased out; it will become a hard error in a future release.
1994For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
1995[WARNING] invalid character `Ⓐ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
1996This was previously accepted but is being phased out; it will become a hard error in a future release.
1997For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 1998[WARNING] invalid character `Ⓑ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
1999This was previously accepted but is being phased out; it will become a hard error in a future release.
2000For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 2001[WARNING] invalid character `Ⓒ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
2002This was previously accepted but is being phased out; it will become a hard error in a future release.
2003For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
2004[WARNING] invalid character `+` in feature `+foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
2005This was previously accepted but is being phased out; it will become a hard error in a future release.
2006For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
2007[WARNING] invalid character `-` in feature `-foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
2008This was previously accepted but is being phased out; it will become a hard error in a future release.
2009For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
2010[WARNING] invalid character `.` in feature `.foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
2011This was previously accepted but is being phased out; it will become a hard error in a future release.
2012For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
2013[WARNING] invalid character `?` in feature `?foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
2014This was previously accepted but is being phased out; it will become a hard error in a future release.
2015For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 2016[WARNING] invalid character `¼` in feature `a¼` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
2017This was previously accepted but is being phased out; it will become a hard error in a future release.
2018For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 2019[WARNING] invalid character `:` in feature `foo:bar` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
2020This was previously accepted but is being phased out; it will become a hard error in a future release.
2021For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 2022[WARNING] invalid character `?` in feature `foo?` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
2023This was previously accepted but is being phased out; it will become a hard error in a future release.
2024For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
2025[WARNING] invalid character `Ⓐ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`)
2026This was previously accepted but is being phased out; it will become a hard error in a future release.
2027For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 2028[WARNING] invalid character `Ⓑ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
2029This was previously accepted but is being phased out; it will become a hard error in a future release.
2030For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
ea1a73a1 2031[WARNING] invalid character `Ⓒ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters)
b731190d
EH
2032This was previously accepted but is being phased out; it will become a hard error in a future release.
2033For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project.
2034[CHECKING] foo v0.1.0 [..]
2035[FINISHED] [..]
2036")
2037 .run();
2038}
85854b18
EH
2039
2040#[cargo_test]
2041fn invalid_feature_names_error() {
2042 // Errors for more restricted feature syntax.
2043 let p = project()
2044 .file(
2045 "Cargo.toml",
2046 r#"
2047 [package]
2048 name = "foo"
2049 version = "0.1.0"
2050
2051 [features]
2052 "foo/bar" = []
2053 "#,
2054 )
2055 .file("src/lib.rs", "")
2056 .build();
2057
2058 p.cargo("check")
2059 .with_status(101)
2060 .with_stderr(
2061 "\
2062error: failed to parse manifest at `[CWD]/Cargo.toml`
2063
2064Caused by:
2065 feature named `foo/bar` is not allowed to contain slashes
2066",
2067 )
2068 .run();
2069}