1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // This test enumerates as many compiler-builtin ungated attributes as
12 // possible (that is, all the mutually compatible ones), and checks
13 // that we get "expected" (*) warnings for each in the various weird
14 // places that users might put them in the syntax.
16 // (*): The word "expected" is in quotes above because the cases where
17 // warnings are and are not emitted might not match a user's intuition
18 // nor the rustc developers' intent. I am really just trying to
19 // capture today's behavior in a test, not so that it become enshrined
20 // as the absolute behavior going forward, but rather so that we do
21 // not change the behavior in the future without even being *aware* of
22 // the change when it happens.
24 // At the time of authoring, the attributes here are listed in the
25 // order that they occur in libsyntax/feature_gate.rs.
27 // Any builtin attributes that:
29 // - are not stable, or
31 // - could not be included here covering the same cases as the other
32 // attributes without raising an *error* from rustc (note though
33 // that warnings are of course expected)
35 // have their own test case referenced by filename in an inline
38 // The test feeds numeric inputs to each attribute that accepts them
39 // without error. We do this for two reasons: (1.) to exercise how
40 // inputs are handled by each, and (2.) to ease searching for related
41 // occurrences in the source text.
43 #![feature(rustc_attrs)] // For `rustc_error`; see note below.
44 #![warn(unused_attributes, unknown_lints)]
46 #![allow(stable_features)]
48 // UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES
50 #![warn (x5400)] //~ WARN unknown lint: `x5400`
51 #![allow (x5300)] //~ WARN unknown lint: `x5300`
52 #![forbid (x5200)] //~ WARN unknown lint: `x5200`
53 #![deny (x5100)] //~ WARN unknown lint: `x5100`
54 #![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
55 #![macro_export = "4800"] //~ WARN unused attribute
56 #![plugin_registrar = "4700"] //~ WARN unused attribute
57 // skipping testing of cfg
58 // skipping testing of cfg_attr
59 #![main = "x4400"] //~ WARN unused attribute
60 #![start = "x4300"] //~ WARN unused attribute
61 // see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200"
62 // see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100"
64 //~^ WARN unused attribute
65 //~| WARN `repr` attribute isn't configurable with a literal
66 #![path = "3800"] //~ WARN unused attribute
67 #![abi = "3700"] //~ WARN unused attribute
68 #![automatically_derived = "3600"] //~ WARN unused attribute
69 #![no_mangle = "3500"]
70 #![no_link = "3400"] //~ WARN unused attribute
71 // see issue-43106-gating-of-derive.rs
72 #![should_panic = "3200"] //~ WARN unused attribute
73 #![ignore = "3100"] //~ WARN unused attribute
74 #![no_implicit_prelude = "3000"]
75 #![reexport_test_harness_main = "2900"]
76 // see gated-link-args.rs
77 // see issue-43106-gating-of-macro_escape.rs for crate-level; but non crate-level is below at "2700"
78 // (cannot easily test gating of crate-level #[no_std]; but non crate-level is below at "2600")
79 #![proc_macro_derive = "2500"] //~ WARN unused attribute
82 #![export_name = "2200"]
83 // see issue-43106-gating-of-inline.rs
85 #![link_name = "1900"]
86 #![link_section = "1800"]
87 #![no_builtins = "1700"] // Yikes, dupe'd on BUILTIN_ATTRIBUTES list (see "0300")
88 #![no_mangle = "1600"] // Yikes, dupe'd on BUILTIN_ATTRIBUTES list (see "3500")
89 // see issue-43106-gating-of-rustc_deprecated.rs
91 // see issue-43106-gating-of-stable.rs
92 // see issue-43106-gating-of-unstable.rs
93 // see issue-43106-gating-of-deprecated.rs
94 #![windows_subsystem = "1000"]
96 // UNGATED CRATE-LEVEL BUILT-IN ATTRIBUTES
98 #![crate_name = "0900"]
99 #![crate_type = "bin"] // cannot pass "0800" here
101 // For #![crate_id], see issue #43142. (I cannot bear to enshrine current behavior in a test)
103 // FIXME(#44232) we should warn that this isn't used.
106 // For #![no_start], see issue #43144. (I cannot bear to enshrine current behavior in a test)
108 // (cannot easily gating state of crate-level #[no_main]; but non crate-level is below at "0400")
109 #![no_builtins = "0300"]
110 #![recursion_limit = "0200"]
111 #![type_length_limit = "0100"]
113 // USES OF BUILT-IN ATTRIBUTES IN OTHER ("UNUSUAL") PLACES
116 //~^ WARN unknown lint: `x5400`
118 mod inner { #![warn(x5400)] }
119 //~^ WARN unknown lint: `x5400`
121 #[warn(x5400)] fn f() { }
122 //~^ WARN unknown lint: `x5400`
124 #[warn(x5400)] struct S;
125 //~^ WARN unknown lint: `x5400`
127 #[warn(x5400)] type T = S;
128 //~^ WARN unknown lint: `x5400`
130 #[warn(x5400)] impl S { }
131 //~^ WARN unknown lint: `x5400`
135 //~^ WARN unknown lint: `x5300`
137 mod inner { #![allow(x5300)] }
138 //~^ WARN unknown lint: `x5300`
140 #[allow(x5300)] fn f() { }
141 //~^ WARN unknown lint: `x5300`
143 #[allow(x5300)] struct S;
144 //~^ WARN unknown lint: `x5300`
146 #[allow(x5300)] type T = S;
147 //~^ WARN unknown lint: `x5300`
149 #[allow(x5300)] impl S { }
150 //~^ WARN unknown lint: `x5300`
154 //~^ WARN unknown lint: `x5200`
156 mod inner { #![forbid(x5200)] }
157 //~^ WARN unknown lint: `x5200`
159 #[forbid(x5200)] fn f() { }
160 //~^ WARN unknown lint: `x5200`
162 #[forbid(x5200)] struct S;
163 //~^ WARN unknown lint: `x5200`
165 #[forbid(x5200)] type T = S;
166 //~^ WARN unknown lint: `x5200`
168 #[forbid(x5200)] impl S { }
169 //~^ WARN unknown lint: `x5200`
173 //~^ WARN unknown lint: `x5100`
175 mod inner { #![deny(x5100)] }
176 //~^ WARN unknown lint: `x5100`
178 #[deny(x5100)] fn f() { }
179 //~^ WARN unknown lint: `x5100`
181 #[deny(x5100)] struct S;
182 //~^ WARN unknown lint: `x5100`
184 #[deny(x5100)] type T = S;
185 //~^ WARN unknown lint: `x5100`
187 #[deny(x5100)] impl S { }
188 //~^ WARN unknown lint: `x5100`
193 mod inner { #![macro_use] }
195 #[macro_use] fn f() { }
196 //~^ WARN unused attribute
198 #[macro_use] struct S;
199 //~^ WARN unused attribute
201 #[macro_use] type T = S;
202 //~^ WARN unused attribute
204 #[macro_use] impl S { }
205 //~^ WARN unused attribute
208 #[macro_export = "4800"]
209 //~^ WARN unused attribute
211 mod inner { #![macro_export="4800"] }
212 //~^ WARN unused attribute
214 #[macro_export = "4800"] fn f() { }
215 //~^ WARN unused attribute
217 #[macro_export = "4800"] struct S;
218 //~^ WARN unused attribute
220 #[macro_export = "4800"] type T = S;
221 //~^ WARN unused attribute
223 #[macro_export = "4800"] impl S { }
224 //~^ WARN unused attribute
227 #[plugin_registrar = "4700"]
228 //~^ WARN unused attribute
229 mod plugin_registrar {
230 mod inner { #![plugin_registrar="4700"] }
231 //~^ WARN unused attribute
233 // for `fn f()` case, see gated-plugin_registrar.rs
235 #[plugin_registrar = "4700"] struct S;
236 //~^ WARN unused attribute
238 #[plugin_registrar = "4700"] type T = S;
239 //~^ WARN unused attribute
241 #[plugin_registrar = "4700"] impl S { }
242 //~^ WARN unused attribute
246 //~^ WARN unused attribute
248 mod inner { #![main="4300"] }
249 //~^ WARN unused attribute
251 // for `fn f()` case, see feature-gate-main.rs
253 #[main = "4400"] struct S;
254 //~^ WARN unused attribute
256 #[main = "4400"] type T = S;
257 //~^ WARN unused attribute
259 #[main = "4400"] impl S { }
260 //~^ WARN unused attribute
264 //~^ WARN unused attribute
266 mod inner { #![start="4300"] }
267 //~^ WARN unused attribute
269 // for `fn f()` case, see feature-gate-start.rs
271 #[start = "4300"] struct S;
272 //~^ WARN unused attribute
274 #[start = "4300"] type T = S;
275 //~^ WARN unused attribute
277 #[start = "4300"] impl S { }
278 //~^ WARN unused attribute
281 // At time of unit test authorship, if compiling without `--test` then
282 // non-crate-level #[test] attributes seem to be ignored.
285 mod test { mod inner { #![test="4200"] }
296 // At time of unit test authorship, if compiling without `--test` then
297 // non-crate-level #[bench] attributes seem to be ignored.
301 mod inner { #![bench="4100"] }
314 //~^ WARN unused attribute
315 //~| WARN `repr` attribute isn't configurable with a literal
317 mod inner { #![repr="3900"] }
318 //~^ WARN unused attribute
319 //~| WARN `repr` attribute isn't configurable with a literal
321 #[repr = "3900"] fn f() { }
322 //~^ WARN unused attribute
323 //~| WARN `repr` attribute isn't configurable with a literal
327 #[repr = "3900"] type T = S;
328 //~^ WARN unused attribute
329 //~| WARN `repr` attribute isn't configurable with a literal
331 #[repr = "3900"] impl S { }
332 //~^ WARN unused attribute
333 //~| WARN `repr` attribute isn't configurable with a literal
338 mod inner { #![path="3800"] }
340 #[path = "3800"] fn f() { }
341 //~^ WARN unused attribute
343 #[path = "3800"] struct S;
344 //~^ WARN unused attribute
346 #[path = "3800"] type T = S;
347 //~^ WARN unused attribute
349 #[path = "3800"] impl S { }
350 //~^ WARN unused attribute
354 //~^ WARN unused attribute
356 mod inner { #![abi="3700"] }
357 //~^ WARN unused attribute
359 #[abi = "3700"] fn f() { }
360 //~^ WARN unused attribute
362 #[abi = "3700"] struct S;
363 //~^ WARN unused attribute
365 #[abi = "3700"] type T = S;
366 //~^ WARN unused attribute
368 #[abi = "3700"] impl S { }
369 //~^ WARN unused attribute
372 #[automatically_derived = "3600"]
373 //~^ WARN unused attribute
374 mod automatically_derived {
375 mod inner { #![automatically_derived="3600"] }
376 //~^ WARN unused attribute
378 #[automatically_derived = "3600"] fn f() { }
379 //~^ WARN unused attribute
381 #[automatically_derived = "3600"] struct S;
382 //~^ WARN unused attribute
384 #[automatically_derived = "3600"] type T = S;
385 //~^ WARN unused attribute
387 #[automatically_derived = "3600"] impl S { }
388 //~^ WARN unused attribute
391 #[no_mangle = "3500"]
393 mod inner { #![no_mangle="3500"] }
395 #[no_mangle = "3500"] fn f() { }
396 //~^ WARN function is marked #[no_mangle], but not exported
398 #[no_mangle = "3500"] struct S;
400 #[no_mangle = "3500"] type T = S;
402 #[no_mangle = "3500"] impl S { }
406 //~^ WARN unused attribute
408 mod inner { #![no_link="3400"] }
409 //~^ WARN unused attribute
411 #[no_link = "3400"] fn f() { }
412 //~^ WARN unused attribute
414 #[no_link = "3400"] struct S;
415 //~^ WARN unused attribute
417 #[no_link = "3400"]type T = S;
418 //~^ WARN unused attribute
420 #[no_link = "3400"] impl S { }
421 //~^ WARN unused attribute
424 #[should_panic = "3200"]
425 //~^ WARN unused attribute
427 mod inner { #![should_panic="3200"] }
428 //~^ WARN unused attribute
430 #[should_panic = "3200"] fn f() { }
431 //~^ WARN unused attribute
433 #[should_panic = "3200"] struct S;
434 //~^ WARN unused attribute
436 #[should_panic = "3200"] type T = S;
437 //~^ WARN unused attribute
439 #[should_panic = "3200"] impl S { }
440 //~^ WARN unused attribute
444 //~^ WARN unused attribute
446 mod inner { #![ignore="3100"] }
447 //~^ WARN unused attribute
449 #[ignore = "3100"] fn f() { }
450 //~^ WARN unused attribute
452 #[ignore = "3100"] struct S;
453 //~^ WARN unused attribute
455 #[ignore = "3100"] type T = S;
456 //~^ WARN unused attribute
458 #[ignore = "3100"] impl S { }
459 //~^ WARN unused attribute
462 #[no_implicit_prelude = "3000"]
463 //~^ WARN unused attribute
464 mod no_implicit_prelude {
465 mod inner { #![no_implicit_prelude="3000"] }
466 //~^ WARN unused attribute
468 #[no_implicit_prelude = "3000"] fn f() { }
469 //~^ WARN unused attribute
471 #[no_implicit_prelude = "3000"] struct S;
472 //~^ WARN unused attribute
474 #[no_implicit_prelude = "3000"] type T = S;
475 //~^ WARN unused attribute
477 #[no_implicit_prelude = "3000"] impl S { }
478 //~^ WARN unused attribute
481 #[reexport_test_harness_main = "2900"]
482 //~^ WARN unused attribute
483 mod reexport_test_harness_main {
484 mod inner { #![reexport_test_harness_main="2900"] }
485 //~^ WARN unused attribute
487 #[reexport_test_harness_main = "2900"] fn f() { }
488 //~^ WARN unused attribute
490 #[reexport_test_harness_main = "2900"] struct S;
491 //~^ WARN unused attribute
493 #[reexport_test_harness_main = "2900"] type T = S;
494 //~^ WARN unused attribute
496 #[reexport_test_harness_main = "2900"] impl S { }
497 //~^ WARN unused attribute
500 // Cannot feed "2700" to `#[macro_escape]` without signaling an error.
502 //~^ WARN macro_escape is a deprecated synonym for macro_use
504 mod inner { #![macro_escape] }
505 //~^ WARN macro_escape is a deprecated synonym for macro_use
507 #[macro_escape] fn f() { }
508 //~^ WARN unused attribute
510 #[macro_escape] struct S;
511 //~^ WARN unused attribute
513 #[macro_escape] type T = S;
514 //~^ WARN unused attribute
516 #[macro_escape] impl S { }
517 //~^ WARN unused attribute
521 //~^ WARN unused attribute
522 //~| WARN crate-level attribute should be an inner attribute
524 mod inner { #![no_std="2600"] }
525 //~^ WARN unused attribute
526 //~| WARN crate-level attribute should be in the root module
528 #[no_std = "2600"] fn f() { }
529 //~^ WARN unused attribute
530 //~| WARN crate-level attribute should be an inner attribute
532 #[no_std = "2600"] struct S;
533 //~^ WARN unused attribute
534 //~| WARN crate-level attribute should be an inner attribute
536 #[no_std = "2600"] type T = S;
537 //~^ WARN unused attribute
538 //~| WARN crate-level attribute should be an inner attribute
540 #[no_std = "2600"] impl S { }
541 //~^ WARN unused attribute
542 //~| WARN crate-level attribute should be an inner attribute
545 // At time of authorship, #[proc_macro_derive = "2500"] signals error
546 // when it occurs on a mod (apart from crate-level). Therefore it goes
547 // into its own file; see issue-43106-gating-of-proc_macro_derive.rs
551 mod inner { #![doc="2400"] }
553 #[doc = "2400"] fn f() { }
555 #[doc = "2400"] struct S;
557 #[doc = "2400"] type T = S;
559 #[doc = "2400"] impl S { }
564 mod inner { #![cold="2300"] }
566 #[cold = "2300"] fn f() { }
568 #[cold = "2300"] struct S;
570 #[cold = "2300"] type T = S;
572 #[cold = "2300"] impl S { }
575 #[export_name = "2200"]
577 mod inner { #![export_name="2200"] }
579 #[export_name = "2200"] fn f() { }
581 #[export_name = "2200"] struct S;
583 #[export_name = "2200"] type T = S;
585 #[export_name = "2200"] impl S { }
588 // Note that this test ends with a `#[rustc_error] fn main()`, so it
589 // will never invoke the linker. These are here nonetheless to point
590 // out that we allow them at non-crate-level (though I do not know
591 // whether they have the same effect here as at crate-level).
595 mod inner { #![link="2000"] }
597 #[link = "2000"] fn f() { }
599 #[link = "2000"] struct S;
601 #[link = "2000"] type T = S;
603 #[link = "2000"] impl S { }
606 #[link_name = "1900"]
608 mod inner { #![link_name="1900"] }
610 #[link_name = "1900"] fn f() { }
612 #[link_name = "1900"] struct S;
614 #[link_name = "1900"] type T = S;
616 #[link_name = "1900"] impl S { }
619 #[link_section = "1800"]
621 mod inner { #![link_section="1800"] }
623 #[link_section = "1800"] fn f() { }
625 #[link_section = "1800"] struct S;
627 #[link_section = "1800"] type T = S;
629 #[link_section = "1800"] impl S { }
632 struct StructForDeprecated;
634 #[deprecated = "1500"]
636 mod inner { #![deprecated="1500"] }
638 #[deprecated = "1500"] fn f() { }
640 #[deprecated = "1500"] struct S1;
642 #[deprecated = "1500"] type T = super::StructForDeprecated;
644 #[deprecated = "1500"] impl super::StructForDeprecated { }
649 mod inner { #![must_use="1400"] }
651 #[must_use = "1400"] fn f() { }
653 #[must_use = "1400"] struct S;
655 #[must_use = "1400"] type T = S;
657 #[must_use = "1400"] impl S { }
660 #[windows_subsystem = "1000"]
661 mod windows_subsystem {
662 mod inner { #![windows_subsystem="1000"] }
664 #[windows_subsystem = "1000"] fn f() { }
666 #[windows_subsystem = "1000"] struct S;
668 #[windows_subsystem = "1000"] type T = S;
670 #[windows_subsystem = "1000"] impl S { }
673 // BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES
675 #[crate_name = "0900"]
676 //~^ WARN unused attribute
677 //~| WARN crate-level attribute should be an inner attribute
679 mod inner { #![crate_name="0900"] }
680 //~^ WARN unused attribute
681 //~| WARN crate-level attribute should be in the root module
683 #[crate_name = "0900"] fn f() { }
684 //~^ WARN unused attribute
685 //~| WARN crate-level attribute should be an inner attribute
687 #[crate_name = "0900"] struct S;
688 //~^ WARN unused attribute
689 //~| WARN crate-level attribute should be an inner attribute
691 #[crate_name = "0900"] type T = S;
692 //~^ WARN unused attribute
693 //~| WARN crate-level attribute should be an inner attribute
695 #[crate_name = "0900"] impl S { }
696 //~^ WARN unused attribute
697 //~| WARN crate-level attribute should be an inner attribute
700 #[crate_type = "0800"]
701 //~^ WARN unused attribute
702 //~| WARN crate-level attribute should be an inner attribute
704 mod inner { #![crate_type="0800"] }
705 //~^ WARN unused attribute
706 //~| WARN crate-level attribute should be in the root module
708 #[crate_type = "0800"] fn f() { }
709 //~^ WARN unused attribute
710 //~| WARN crate-level attribute should be an inner attribute
712 #[crate_type = "0800"] struct S;
713 //~^ WARN unused attribute
714 //~| WARN crate-level attribute should be an inner attribute
716 #[crate_type = "0800"] type T = S;
717 //~^ WARN unused attribute
718 //~| WARN crate-level attribute should be an inner attribute
720 #[crate_type = "0800"] impl S { }
721 //~^ WARN unused attribute
722 //~| WARN crate-level attribute should be an inner attribute
726 //~^ WARN unused attribute
727 //~| WARN crate-level attribute should be an inner attribute
729 mod inner { #![feature(x0600)] }
730 //~^ WARN unused attribute
731 //~| WARN crate-level attribute should be in the root module
733 #[feature(x0600)] fn f() { }
734 //~^ WARN unused attribute
735 //~| WARN crate-level attribute should be an inner attribute
737 #[feature(x0600)] struct S;
738 //~^ WARN unused attribute
739 //~| WARN crate-level attribute should be an inner attribute
741 #[feature(x0600)] type T = S;
742 //~^ WARN unused attribute
743 //~| WARN crate-level attribute should be an inner attribute
745 #[feature(x0600)] impl S { }
746 //~^ WARN unused attribute
747 //~| WARN crate-level attribute should be an inner attribute
752 //~^ WARN unused attribute
753 //~| WARN crate-level attribute should be an inner attribute
755 mod inner { #![no_main="0400"] }
756 //~^ WARN unused attribute
757 //~| WARN crate-level attribute should be in the root module
759 #[no_main = "0400"] fn f() { }
760 //~^ WARN unused attribute
761 //~| WARN crate-level attribute should be an inner attribute
763 #[no_main = "0400"] struct S;
764 //~^ WARN unused attribute
765 //~| WARN crate-level attribute should be an inner attribute
767 #[no_main = "0400"] type T = S;
768 //~^ WARN unused attribute
769 //~| WARN crate-level attribute should be an inner attribute
771 #[no_main = "0400"] impl S { }
772 //~^ WARN unused attribute
773 //~| WARN crate-level attribute should be an inner attribute
776 #[no_builtins = "0300"]
778 mod inner { #![no_builtins="0200"] }
780 #[no_builtins = "0300"] fn f() { }
782 #[no_builtins = "0300"] struct S;
784 #[no_builtins = "0300"] type T = S;
786 #[no_builtins = "0300"] impl S { }
789 #[recursion_limit="0200"]
790 //~^ WARN unused attribute
791 //~| WARN crate-level attribute should be an inner attribute
792 mod recursion_limit {
793 mod inner { #![recursion_limit="0200"] }
794 //~^ WARN unused attribute
795 //~| WARN crate-level attribute should be in the root module
797 #[recursion_limit="0200"] fn f() { }
798 //~^ WARN unused attribute
799 //~| WARN crate-level attribute should be an inner attribute
801 #[recursion_limit="0200"] struct S;
802 //~^ WARN unused attribute
803 //~| WARN crate-level attribute should be an inner attribute
805 #[recursion_limit="0200"] type T = S;
806 //~^ WARN unused attribute
807 //~| WARN crate-level attribute should be an inner attribute
809 #[recursion_limit="0200"] impl S { }
810 //~^ WARN unused attribute
811 //~| WARN crate-level attribute should be an inner attribute
814 #[type_length_limit="0100"]
815 //~^ WARN unused attribute
816 //~| WARN crate-level attribute should be an inner attribute
817 mod type_length_limit {
818 mod inner { #![type_length_limit="0100"] }
819 //~^ WARN unused attribute
820 //~| WARN crate-level attribute should be in the root module
822 #[type_length_limit="0100"] fn f() { }
823 //~^ WARN unused attribute
824 //~| WARN crate-level attribute should be an inner attribute
826 #[type_length_limit="0100"] struct S;
827 //~^ WARN unused attribute
828 //~| WARN crate-level attribute should be an inner attribute
830 #[type_length_limit="0100"] type T = S;
831 //~^ WARN unused attribute
832 //~| WARN crate-level attribute should be an inner attribute
834 #[type_length_limit="0100"] impl S { }
835 //~^ WARN unused attribute
836 //~| WARN crate-level attribute should be an inner attribute
839 // Since we expect for the mix of attributes used here to compile
840 // successfully, and we are just testing for the expected warnings of
841 // various (mis)uses of attributes, we use the `rustc_error` attribute
842 // on the `fn main()`.
845 fn main() { //~ ERROR compilation successful
846 println!("Hello World");