1 // This test enumerates as many compiler-builtin ungated attributes as
2 // possible (that is, all the mutually compatible ones), and checks
3 // that we get "expected" (*) warnings for each in the various weird
4 // places that users might put them in the syntax.
6 // (*): The word "expected" is in quotes above because the cases where
7 // warnings are and are not emitted might not match a user's intuition
8 // nor the rustc developers' intent. I am really just trying to
9 // capture today's behavior in a test, not so that it become enshrined
10 // as the absolute behavior going forward, but rather so that we do
11 // not change the behavior in the future without even being *aware* of
12 // the change when it happens.
14 // At the time of authoring, the attributes here are listed in the
15 // order that they occur in libsyntax/feature_gate.rs.
17 // Any builtin attributes that:
19 // - are not stable, or
21 // - could not be included here covering the same cases as the other
22 // attributes without raising an *error* from rustc (note though
23 // that warnings are of course expected)
25 // have their own test case referenced by filename in an inline
28 // The test feeds numeric inputs to each attribute that accepts them
29 // without error. We do this for two reasons: (1.) to exercise how
30 // inputs are handled by each, and (2.) to ease searching for related
31 // occurrences in the source text.
33 #![warn(unused_attributes, unknown_lints)]
34 #![allow(stable_features)]
36 // UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES
38 #![warn(x5400)] //~ WARN unknown lint: `x5400`
39 #![allow(x5300)] //~ WARN unknown lint: `x5300`
40 #![forbid(x5200)] //~ WARN unknown lint: `x5200`
41 #![deny(x5100)] //~ WARN unknown lint: `x5100`
42 #![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
43 #![macro_export] //~ WARN unused attribute
44 #![plugin_registrar] //~ WARN unused attribute
45 // skipping testing of cfg
46 // skipping testing of cfg_attr
47 #![main] //~ WARN unused attribute
48 #![start] //~ WARN unused attribute
49 // see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200"
50 // see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100"
52 //~^ WARN unused attribute
53 #![path = "3800"] //~ WARN unused attribute
54 #![automatically_derived] //~ WARN unused attribute
56 #![no_link] //~ WARN unused attribute
57 // see issue-43106-gating-of-derive.rs
58 #![should_panic] //~ WARN unused attribute
59 #![ignore] //~ WARN unused attribute
60 #![no_implicit_prelude]
61 #![reexport_test_harness_main = "2900"]
62 // see gated-link-args.rs
63 // see issue-43106-gating-of-macro_escape.rs for crate-level; but non crate-level is below at "2700"
64 // (cannot easily test gating of crate-level #[no_std]; but non crate-level is below at "2600")
65 #![proc_macro_derive()] //~ WARN unused attribute
68 #![export_name = "2200"]
69 // see issue-43106-gating-of-inline.rs
71 #![link_name = "1900"]
72 #![link_section = "1800"]
73 // see issue-43106-gating-of-rustc_deprecated.rs
75 // see issue-43106-gating-of-stable.rs
76 // see issue-43106-gating-of-unstable.rs
77 // see issue-43106-gating-of-deprecated.rs
78 #![windows_subsystem = "1000"]
80 // UNGATED CRATE-LEVEL BUILT-IN ATTRIBUTES
82 #![crate_name = "0900"]
83 #![crate_type = "bin"] // cannot pass "0800" here
85 // For #![crate_id], see issue #43142. (I cannot bear to enshrine current behavior in a test)
87 // FIXME(#44232) we should warn that this isn't used.
90 // For #![no_start], see issue #43144. (I cannot bear to enshrine current behavior in a test)
92 // (cannot easily gating state of crate-level #[no_main]; but non crate-level is below at "0400")
94 #![recursion_limit = "0200"]
95 #![type_length_limit = "0100"]
97 // USES OF BUILT-IN ATTRIBUTES IN OTHER ("UNUSUAL") PLACES
100 //~^ WARN unknown lint: `x5400`
102 mod inner { #![warn(x5400)] }
103 //~^ WARN unknown lint: `x5400`
105 #[warn(x5400)] fn f() { }
106 //~^ WARN unknown lint: `x5400`
108 #[warn(x5400)] struct S;
109 //~^ WARN unknown lint: `x5400`
111 #[warn(x5400)] type T = S;
112 //~^ WARN unknown lint: `x5400`
114 #[warn(x5400)] impl S { }
115 //~^ WARN unknown lint: `x5400`
119 //~^ WARN unknown lint: `x5300`
121 mod inner { #![allow(x5300)] }
122 //~^ WARN unknown lint: `x5300`
124 #[allow(x5300)] fn f() { }
125 //~^ WARN unknown lint: `x5300`
127 #[allow(x5300)] struct S;
128 //~^ WARN unknown lint: `x5300`
130 #[allow(x5300)] type T = S;
131 //~^ WARN unknown lint: `x5300`
133 #[allow(x5300)] impl S { }
134 //~^ WARN unknown lint: `x5300`
138 //~^ WARN unknown lint: `x5200`
140 mod inner { #![forbid(x5200)] }
141 //~^ WARN unknown lint: `x5200`
143 #[forbid(x5200)] fn f() { }
144 //~^ WARN unknown lint: `x5200`
146 #[forbid(x5200)] struct S;
147 //~^ WARN unknown lint: `x5200`
149 #[forbid(x5200)] type T = S;
150 //~^ WARN unknown lint: `x5200`
152 #[forbid(x5200)] impl S { }
153 //~^ WARN unknown lint: `x5200`
157 //~^ WARN unknown lint: `x5100`
159 mod inner { #![deny(x5100)] }
160 //~^ WARN unknown lint: `x5100`
162 #[deny(x5100)] fn f() { }
163 //~^ WARN unknown lint: `x5100`
165 #[deny(x5100)] struct S;
166 //~^ WARN unknown lint: `x5100`
168 #[deny(x5100)] type T = S;
169 //~^ WARN unknown lint: `x5100`
171 #[deny(x5100)] impl S { }
172 //~^ WARN unknown lint: `x5100`
177 mod inner { #![macro_use] }
179 #[macro_use] fn f() { }
180 //~^ WARN unused attribute
182 #[macro_use] struct S;
183 //~^ WARN unused attribute
185 #[macro_use] type T = S;
186 //~^ WARN unused attribute
188 #[macro_use] impl S { }
189 //~^ WARN unused attribute
193 //~^ WARN unused attribute
195 mod inner { #![macro_export] }
196 //~^ WARN unused attribute
198 #[macro_export] fn f() { }
199 //~^ WARN unused attribute
201 #[macro_export] struct S;
202 //~^ WARN unused attribute
204 #[macro_export] type T = S;
205 //~^ WARN unused attribute
207 #[macro_export] impl S { }
208 //~^ WARN unused attribute
212 //~^ WARN unused attribute
213 mod plugin_registrar
{
214 mod inner { #![plugin_registrar] }
215 //~^ WARN unused attribute
217 // for `fn f()` case, see gated-plugin_registrar.rs
219 #[plugin_registrar] struct S;
220 //~^ WARN unused attribute
222 #[plugin_registrar] type T = S;
223 //~^ WARN unused attribute
225 #[plugin_registrar] impl S { }
226 //~^ WARN unused attribute
230 //~^ WARN unused attribute
232 mod inner { #![main] }
233 //~^ WARN unused attribute
235 // for `fn f()` case, see feature-gate-main.rs
238 //~^ WARN unused attribute
241 //~^ WARN unused attribute
244 //~^ WARN unused attribute
248 //~^ WARN unused attribute
250 mod inner { #![start] }
251 //~^ WARN unused attribute
253 // for `fn f()` case, see feature-gate-start.rs
256 //~^ WARN unused attribute
259 //~^ WARN unused attribute
262 //~^ WARN unused attribute
265 // At time of unit test authorship, if compiling without `--test` then
266 // non-crate-level #[test] attributes seem to be ignored.
269 mod test { mod inner { #![test] }
280 // At time of unit test authorship, if compiling without `--test` then
281 // non-crate-level #[bench] attributes seem to be ignored.
285 mod inner { #![bench] }
299 mod inner { #![repr()] }
305 #[repr()] type T = S;
312 mod inner { #![path="3800"] }
314 #[path = "3800"] fn f() { }
315 //~^ WARN unused attribute
317 #[path = "3800"] struct S;
318 //~^ WARN unused attribute
320 #[path = "3800"] type T = S;
321 //~^ WARN unused attribute
323 #[path = "3800"] impl S { }
324 //~^ WARN unused attribute
327 #[automatically_derived]
328 //~^ WARN unused attribute
329 mod automatically_derived
{
330 mod inner { #![automatically_derived] }
331 //~^ WARN unused attribute
333 #[automatically_derived] fn f() { }
334 //~^ WARN unused attribute
336 #[automatically_derived] struct S;
337 //~^ WARN unused attribute
339 #[automatically_derived] type T = S;
340 //~^ WARN unused attribute
342 #[automatically_derived] impl S { }
343 //~^ WARN unused attribute
348 mod inner { #![no_mangle] }
350 #[no_mangle] fn f() { }
352 #[no_mangle] struct S;
354 #[no_mangle] type T = S;
356 #[no_mangle] impl S { }
360 //~^ WARN unused attribute
362 mod inner { #![no_link] }
363 //~^ WARN unused attribute
365 #[no_link] fn f() { }
366 //~^ WARN unused attribute
369 //~^ WARN unused attribute
371 #[no_link]type T = S;
372 //~^ WARN unused attribute
374 #[no_link] impl S { }
375 //~^ WARN unused attribute
379 //~^ WARN unused attribute
381 mod inner { #![should_panic] }
382 //~^ WARN unused attribute
384 #[should_panic] fn f() { }
385 //~^ WARN unused attribute
387 #[should_panic] struct S;
388 //~^ WARN unused attribute
390 #[should_panic] type T = S;
391 //~^ WARN unused attribute
393 #[should_panic] impl S { }
394 //~^ WARN unused attribute
398 //~^ WARN unused attribute
400 mod inner { #![ignore] }
401 //~^ WARN unused attribute
404 //~^ WARN unused attribute
407 //~^ WARN unused attribute
409 #[ignore] type T = S;
410 //~^ WARN unused attribute
413 //~^ WARN unused attribute
416 #[no_implicit_prelude]
417 //~^ WARN unused attribute
418 mod no_implicit_prelude
{
419 mod inner { #![no_implicit_prelude] }
420 //~^ WARN unused attribute
422 #[no_implicit_prelude] fn f() { }
423 //~^ WARN unused attribute
425 #[no_implicit_prelude] struct S;
426 //~^ WARN unused attribute
428 #[no_implicit_prelude] type T = S;
429 //~^ WARN unused attribute
431 #[no_implicit_prelude] impl S { }
432 //~^ WARN unused attribute
435 #[reexport_test_harness_main = "2900"]
436 //~^ WARN unused attribute
437 mod reexport_test_harness_main
{
438 mod inner { #![reexport_test_harness_main="2900"] }
439 //~^ WARN unused attribute
441 #[reexport_test_harness_main = "2900"] fn f() { }
442 //~^ WARN unused attribute
444 #[reexport_test_harness_main = "2900"] struct S;
445 //~^ WARN unused attribute
447 #[reexport_test_harness_main = "2900"] type T = S;
448 //~^ WARN unused attribute
450 #[reexport_test_harness_main = "2900"] impl S { }
451 //~^ WARN unused attribute
454 // Cannot feed "2700" to `#[macro_escape]` without signaling an error.
456 //~^ WARN macro_escape is a deprecated synonym for macro_use
458 mod inner { #![macro_escape] }
459 //~^ WARN macro_escape is a deprecated synonym for macro_use
461 #[macro_escape] fn f() { }
462 //~^ WARN unused attribute
464 #[macro_escape] struct S;
465 //~^ WARN unused attribute
467 #[macro_escape] type T = S;
468 //~^ WARN unused attribute
470 #[macro_escape] impl S { }
471 //~^ WARN unused attribute
475 //~^ WARN unused attribute
476 //~| WARN crate-level attribute should be an inner attribute
478 mod inner { #![no_std] }
479 //~^ WARN unused attribute
480 //~| WARN crate-level attribute should be in the root module
483 //~^ WARN unused attribute
484 //~| WARN crate-level attribute should be an inner attribute
487 //~^ WARN unused attribute
488 //~| WARN crate-level attribute should be an inner attribute
490 #[no_std] type T = S;
491 //~^ WARN unused attribute
492 //~| WARN crate-level attribute should be an inner attribute
495 //~^ WARN unused attribute
496 //~| WARN crate-level attribute should be an inner attribute
499 // At time of authorship, #[proc_macro_derive = "2500"] signals error
500 // when it occurs on a mod (apart from crate-level). Therefore it goes
501 // into its own file; see issue-43106-gating-of-proc_macro_derive.rs
505 mod inner { #![doc="2400"] }
507 #[doc = "2400"] fn f() { }
509 #[doc = "2400"] struct S;
511 #[doc = "2400"] type T = S;
513 #[doc = "2400"] impl S { }
518 mod inner { #![cold] }
529 #[export_name = "2200"]
531 mod inner { #![export_name="2200"] }
533 #[export_name = "2200"] fn f() { }
535 #[export_name = "2200"] struct S;
537 #[export_name = "2200"] type T = S;
539 #[export_name = "2200"] impl S { }
542 // Note that this test has a `skip-codegen`, so it
543 // will never invoke the linker. These are here nonetheless to point
544 // out that we allow them at non-crate-level (though I do not know
545 // whether they have the same effect here as at crate-level).
549 mod inner { #![link()] }
555 #[link()] type T = S;
560 #[link_name = "1900"]
562 mod inner { #![link_name="1900"] }
564 #[link_name = "1900"] fn f() { }
566 #[link_name = "1900"] struct S;
568 #[link_name = "1900"] type T = S;
570 #[link_name = "1900"] impl S { }
573 #[link_section = "1800"]
575 mod inner { #![link_section="1800"] }
577 #[link_section = "1800"] fn f() { }
579 #[link_section = "1800"] struct S;
581 #[link_section = "1800"] type T = S;
583 #[link_section = "1800"] impl S { }
586 struct StructForDeprecated
;
590 mod inner { #![deprecated] }
592 #[deprecated] fn f() { }
594 #[deprecated] struct S1;
596 #[deprecated] type T = super::StructForDeprecated;
598 #[deprecated] impl super::StructForDeprecated { }
603 mod inner { #![must_use] }
605 #[must_use] fn f() { }
607 #[must_use] struct S;
609 #[must_use] type T = S;
611 #[must_use] impl S { }
614 #[windows_subsystem = "1000"]
615 mod windows_subsystem
{
616 mod inner { #![windows_subsystem="1000"] }
618 #[windows_subsystem = "1000"] fn f() { }
620 #[windows_subsystem = "1000"] struct S;
622 #[windows_subsystem = "1000"] type T = S;
624 #[windows_subsystem = "1000"] impl S { }
627 // BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES
629 #[crate_name = "0900"]
630 //~^ WARN unused attribute
631 //~| WARN crate-level attribute should be an inner attribute
633 mod inner { #![crate_name="0900"] }
634 //~^ WARN unused attribute
635 //~| WARN crate-level attribute should be in the root module
637 #[crate_name = "0900"] fn f() { }
638 //~^ WARN unused attribute
639 //~| WARN crate-level attribute should be an inner attribute
641 #[crate_name = "0900"] struct S;
642 //~^ WARN unused attribute
643 //~| WARN crate-level attribute should be an inner attribute
645 #[crate_name = "0900"] type T = S;
646 //~^ WARN unused attribute
647 //~| WARN crate-level attribute should be an inner attribute
649 #[crate_name = "0900"] impl S { }
650 //~^ WARN unused attribute
651 //~| WARN crate-level attribute should be an inner attribute
654 #[crate_type = "0800"]
655 //~^ WARN unused attribute
656 //~| WARN crate-level attribute should be an inner attribute
658 mod inner { #![crate_type="0800"] }
659 //~^ WARN unused attribute
660 //~| WARN crate-level attribute should be in the root module
662 #[crate_type = "0800"] fn f() { }
663 //~^ WARN unused attribute
664 //~| WARN crate-level attribute should be an inner attribute
666 #[crate_type = "0800"] struct S;
667 //~^ WARN unused attribute
668 //~| WARN crate-level attribute should be an inner attribute
670 #[crate_type = "0800"] type T = S;
671 //~^ WARN unused attribute
672 //~| WARN crate-level attribute should be an inner attribute
674 #[crate_type = "0800"] impl S { }
675 //~^ WARN unused attribute
676 //~| WARN crate-level attribute should be an inner attribute
680 //~^ WARN unused attribute
681 //~| WARN crate-level attribute should be an inner attribute
683 mod inner { #![feature(x0600)] }
684 //~^ WARN unused attribute
685 //~| WARN crate-level attribute should be in the root module
687 #[feature(x0600)] fn f() { }
688 //~^ WARN unused attribute
689 //~| WARN crate-level attribute should be an inner attribute
691 #[feature(x0600)] struct S;
692 //~^ WARN unused attribute
693 //~| WARN crate-level attribute should be an inner attribute
695 #[feature(x0600)] type T = S;
696 //~^ WARN unused attribute
697 //~| WARN crate-level attribute should be an inner attribute
699 #[feature(x0600)] impl S { }
700 //~^ WARN unused attribute
701 //~| WARN crate-level attribute should be an inner attribute
706 //~^ WARN unused attribute
707 //~| WARN crate-level attribute should be an inner attribute
709 mod inner { #![no_main] }
710 //~^ WARN unused attribute
711 //~| WARN crate-level attribute should be in the root module
713 #[no_main] fn f() { }
714 //~^ WARN unused attribute
715 //~| WARN crate-level attribute should be an inner attribute
718 //~^ WARN unused attribute
719 //~| WARN crate-level attribute should be an inner attribute
721 #[no_main] type T = S;
722 //~^ WARN unused attribute
723 //~| WARN crate-level attribute should be an inner attribute
725 #[no_main] impl S { }
726 //~^ WARN unused attribute
727 //~| WARN crate-level attribute should be an inner attribute
732 mod inner { #![no_builtins] }
734 #[no_builtins] fn f() { }
736 #[no_builtins] struct S;
738 #[no_builtins] type T = S;
740 #[no_builtins] impl S { }
743 #[recursion_limit="0200"]
744 //~^ WARN unused attribute
745 //~| WARN crate-level attribute should be an inner attribute
746 mod recursion_limit
{
747 mod inner { #![recursion_limit="0200"] }
748 //~^ WARN unused attribute
749 //~| WARN crate-level attribute should be in the root module
751 #[recursion_limit="0200"] fn f() { }
752 //~^ WARN unused attribute
753 //~| WARN crate-level attribute should be an inner attribute
755 #[recursion_limit="0200"] struct S;
756 //~^ WARN unused attribute
757 //~| WARN crate-level attribute should be an inner attribute
759 #[recursion_limit="0200"] type T = S;
760 //~^ WARN unused attribute
761 //~| WARN crate-level attribute should be an inner attribute
763 #[recursion_limit="0200"] impl S { }
764 //~^ WARN unused attribute
765 //~| WARN crate-level attribute should be an inner attribute
768 #[type_length_limit="0100"]
769 //~^ WARN unused attribute
770 //~| WARN crate-level attribute should be an inner attribute
771 mod type_length_limit
{
772 mod inner { #![type_length_limit="0100"] }
773 //~^ WARN unused attribute
774 //~| WARN crate-level attribute should be in the root module
776 #[type_length_limit="0100"] fn f() { }
777 //~^ WARN unused attribute
778 //~| WARN crate-level attribute should be an inner attribute
780 #[type_length_limit="0100"] struct S;
781 //~^ WARN unused attribute
782 //~| WARN crate-level attribute should be an inner attribute
784 #[type_length_limit="0100"] type T = S;
785 //~^ WARN unused attribute
786 //~| WARN crate-level attribute should be an inner attribute
788 #[type_length_limit="0100"] impl S { }
789 //~^ WARN unused attribute
790 //~| WARN crate-level attribute should be an inner attribute