]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/builtin_attr.rs
Add builtin attributes for use in nameres
[rust.git] / crates / hir_def / src / builtin_attr.rs
1 //! Builtin attributes resolved by nameres.
2 //!
3 //! The actual definitions were copied from rustc's `compiler/rustc_feature/src/builtin_attrs.rs`.
4 //!
5 //! The macros were adjusted to only expand to the attribute name, since that is all we need to do
6 //! name resolution, and `BUILTIN_ATTRIBUTES` is almost entirely unchanged from the original, to
7 //! ease updating.
8
9 /// Ignored attribute namespaces used by tools.
10 pub const TOOL_MODULES: &[&str] = &["rustfmt", "clippy"];
11
12 type BuiltinAttribute = &'static str;
13
14 macro_rules! ungated {
15     ($attr:ident, $typ:expr, $tpl:expr $(,)?) => {
16         stringify!($attr)
17     };
18 }
19
20 macro_rules! gated {
21     ($attr:ident $($rest:tt)*) => {
22         stringify!($attr)
23     };
24 }
25
26 macro_rules! rustc_attr {
27     (TEST, $attr:ident $($rest:tt)*) => {
28         stringify!($attr)
29     };
30     ($attr:ident $($rest:tt)*) => {
31         stringify!($attr)
32     };
33 }
34
35 /// Attributes that have a special meaning to rustc or rustdoc.
36 #[rustfmt::skip]
37 pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
38     // ==========================================================================
39     // Stable attributes:
40     // ==========================================================================
41
42     // Conditional compilation:
43     ungated!(cfg, Normal, template!(List: "predicate")),
44     ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")),
45
46     // Testing:
47     ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")),
48     ungated!(
49         should_panic, Normal,
50         template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
51     ),
52     // FIXME(Centril): This can be used on stable but shouldn't.
53     ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")),
54
55     // Macros:
56     ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
57     ungated!(automatically_derived, Normal, template!(Word)),
58     // FIXME(#14407)
59     ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
60     ungated!(macro_escape, Normal, template!(Word)), // Deprecated synonym for `macro_use`.
61     ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")),
62     ungated!(proc_macro, Normal, template!(Word)),
63     ungated!(
64         proc_macro_derive, Normal,
65         template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
66     ),
67     ungated!(proc_macro_attribute, Normal, template!(Word)),
68
69     // Lints:
70     ungated!(warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
71     ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
72     ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
73     ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
74     ungated!(must_use, AssumedUsed, template!(Word, NameValueStr: "reason")),
75     // FIXME(#14407)
76     ungated!(
77         deprecated, Normal,
78         template!(
79             Word,
80             List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
81             NameValueStr: "reason"
82         ),
83     ),
84
85     // Crate properties:
86     ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")),
87     ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")),
88     ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")),
89
90     // ABI, linking, symbols, and FFI
91     ungated!(
92         link, AssumedUsed,
93         template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...""#),
94     ),
95     ungated!(link_name, AssumedUsed, template!(NameValueStr: "name")),
96     ungated!(no_link, Normal, template!(Word)),
97     ungated!(repr, Normal, template!(List: "C")),
98     ungated!(export_name, AssumedUsed, template!(NameValueStr: "name")),
99     ungated!(link_section, AssumedUsed, template!(NameValueStr: "name")),
100     ungated!(no_mangle, AssumedUsed, template!(Word)),
101     ungated!(used, AssumedUsed, template!(Word)),
102
103     // Limits:
104     ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")),
105     ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")),
106     gated!(
107         const_eval_limit, CrateLevel, template!(NameValueStr: "N"), const_eval_limit,
108         experimental!(const_eval_limit)
109     ),
110
111     // Entry point:
112     ungated!(main, Normal, template!(Word)),
113     ungated!(start, Normal, template!(Word)),
114     ungated!(no_start, CrateLevel, template!(Word)),
115     ungated!(no_main, CrateLevel, template!(Word)),
116
117     // Modules, prelude, and resolution:
118     ungated!(path, Normal, template!(NameValueStr: "file")),
119     ungated!(no_std, CrateLevel, template!(Word)),
120     ungated!(no_implicit_prelude, Normal, template!(Word)),
121     ungated!(non_exhaustive, AssumedUsed, template!(Word)),
122
123     // Runtime
124     ungated!(windows_subsystem, AssumedUsed, template!(NameValueStr: "windows|console")),
125     ungated!(panic_handler, Normal, template!(Word)), // RFC 2070
126
127     // Code generation:
128     ungated!(inline, AssumedUsed, template!(Word, List: "always|never")),
129     ungated!(cold, AssumedUsed, template!(Word)),
130     ungated!(no_builtins, AssumedUsed, template!(Word)),
131     ungated!(target_feature, AssumedUsed, template!(List: r#"enable = "name""#)),
132     ungated!(track_caller, AssumedUsed, template!(Word)),
133     gated!(
134         no_sanitize, AssumedUsed,
135         template!(List: "address, memory, thread"),
136         experimental!(no_sanitize)
137     ),
138
139     // FIXME: #14408 assume docs are used since rustdoc looks at them.
140     ungated!(doc, AssumedUsed, template!(List: "hidden|inline|...", NameValueStr: "string")),
141
142     // ==========================================================================
143     // Unstable attributes:
144     // ==========================================================================
145
146     // Linking:
147     gated!(naked, AssumedUsed, template!(Word), naked_functions, experimental!(naked)),
148     gated!(
149         link_args, Normal, template!(NameValueStr: "args"),
150         "the `link_args` attribute is experimental and not portable across platforms, \
151         it is recommended to use `#[link(name = \"foo\")] instead",
152     ),
153     gated!(
154         link_ordinal, AssumedUsed, template!(List: "ordinal"), raw_dylib,
155         experimental!(link_ordinal)
156     ),
157
158     // Plugins:
159     // XXX Modified for use in rust-analyzer
160     gated!(plugin_registrar),
161     gated!(plugin),
162
163     // Testing:
164     gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)),
165     gated!(
166         test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks,
167         "custom test frameworks are an unstable feature",
168     ),
169     // RFC #1268
170     gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)),
171     gated!(
172         thread_local, AssumedUsed, template!(Word),
173         "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
174     ),
175     gated!(no_core, CrateLevel, template!(Word), experimental!(no_core)),
176     // RFC 2412
177     gated!(
178         optimize, AssumedUsed, template!(List: "size|speed"), optimize_attribute,
179         experimental!(optimize),
180     ),
181     // RFC 2867
182     gated!(instruction_set, AssumedUsed, template!(List: "set"), isa_attribute, experimental!(instruction_set)),
183
184     gated!(ffi_returns_twice, AssumedUsed, template!(Word), experimental!(ffi_returns_twice)),
185     gated!(ffi_pure, AssumedUsed, template!(Word), experimental!(ffi_pure)),
186     gated!(ffi_const, AssumedUsed, template!(Word), experimental!(ffi_const)),
187     gated!(
188         register_attr, CrateLevel, template!(List: "attr1, attr2, ..."),
189         experimental!(register_attr),
190     ),
191     gated!(
192         register_tool, CrateLevel, template!(List: "tool1, tool2, ..."),
193         experimental!(register_tool),
194     ),
195
196     gated!(cmse_nonsecure_entry, AssumedUsed, template!(Word), experimental!(cmse_nonsecure_entry)),
197
198     // ==========================================================================
199     // Internal attributes: Stability, deprecation, and unsafe:
200     // ==========================================================================
201
202     ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")),
203     // FIXME(#14407) -- only looked at on-demand so we can't
204     // guarantee they'll have already been checked.
205     ungated!(
206         rustc_deprecated, AssumedUsed,
207         template!(List: r#"since = "version", reason = "...""#)
208     ),
209     // FIXME(#14407)
210     ungated!(stable, AssumedUsed, template!(List: r#"feature = "name", since = "version""#)),
211     // FIXME(#14407)
212     ungated!(
213         unstable, AssumedUsed,
214         template!(List: r#"feature = "name", reason = "...", issue = "N""#),
215     ),
216     // FIXME(#14407)
217     ungated!(rustc_const_unstable, AssumedUsed, template!(List: r#"feature = "name""#)),
218     // FIXME(#14407)
219     ungated!(rustc_const_stable, AssumedUsed, template!(List: r#"feature = "name""#)),
220     gated!(
221         allow_internal_unstable, AssumedUsed, template!(Word, List: "feat1, feat2, ..."),
222         "allow_internal_unstable side-steps feature gating and stability checks",
223     ),
224     gated!(
225         rustc_allow_const_fn_unstable, AssumedUsed, template!(Word, List: "feat1, feat2, ..."),
226         "rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
227     ),
228     gated!(
229         allow_internal_unsafe, Normal, template!(Word),
230         "allow_internal_unsafe side-steps the unsafe_code lint",
231     ),
232
233     // ==========================================================================
234     // Internal attributes: Type system related:
235     // ==========================================================================
236
237     gated!(fundamental, AssumedUsed, template!(Word), experimental!(fundamental)),
238     gated!(
239         may_dangle, Normal, template!(Word), dropck_eyepatch,
240         "`may_dangle` has unstable semantics and may be removed in the future",
241     ),
242
243     // ==========================================================================
244     // Internal attributes: Runtime related:
245     // ==========================================================================
246
247     rustc_attr!(rustc_allocator, AssumedUsed, template!(Word), IMPL_DETAIL),
248     rustc_attr!(rustc_allocator_nounwind, AssumedUsed, template!(Word), IMPL_DETAIL),
249     gated!(alloc_error_handler, Normal, template!(Word), experimental!(alloc_error_handler)),
250     gated!(
251         default_lib_allocator, AssumedUsed, template!(Word), allocator_internals,
252         experimental!(default_lib_allocator),
253     ),
254     gated!(
255         needs_allocator, Normal, template!(Word), allocator_internals,
256         experimental!(needs_allocator),
257     ),
258     gated!(panic_runtime, AssumedUsed, template!(Word), experimental!(panic_runtime)),
259     gated!(needs_panic_runtime, AssumedUsed, template!(Word), experimental!(needs_panic_runtime)),
260     gated!(
261         unwind, AssumedUsed, template!(List: "allowed|aborts"), unwind_attributes,
262         experimental!(unwind),
263     ),
264     gated!(
265         compiler_builtins, AssumedUsed, template!(Word),
266         "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
267         which contains compiler-rt intrinsics and will never be stable",
268     ),
269     gated!(
270         profiler_runtime, AssumedUsed, template!(Word),
271         "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
272         which contains the profiler runtime and will never be stable",
273     ),
274
275     // ==========================================================================
276     // Internal attributes, Linkage:
277     // ==========================================================================
278
279     gated!(
280         linkage, AssumedUsed, template!(NameValueStr: "external|internal|..."),
281         "the `linkage` attribute is experimental and not portable across platforms",
282     ),
283     rustc_attr!(rustc_std_internal_symbol, AssumedUsed, template!(Word), INTERNAL_UNSTABLE),
284
285     // ==========================================================================
286     // Internal attributes, Macro related:
287     // ==========================================================================
288
289     rustc_attr!(rustc_builtin_macro, AssumedUsed, template!(Word), IMPL_DETAIL),
290     rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
291     rustc_attr!(
292         rustc_macro_transparency, AssumedUsed,
293         template!(NameValueStr: "transparent|semitransparent|opaque"),
294         "used internally for testing macro hygiene",
295     ),
296
297     // ==========================================================================
298     // Internal attributes, Diagnostics related:
299     // ==========================================================================
300
301     rustc_attr!(
302         rustc_on_unimplemented, AssumedUsed,
303         template!(
304             List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
305             NameValueStr: "message"
306         ),
307         INTERNAL_UNSTABLE
308     ),
309     // Enumerates "identity-like" conversion methods to suggest on type mismatch.
310     rustc_attr!(rustc_conversion_suggestion, AssumedUsed, template!(Word), INTERNAL_UNSTABLE),
311
312     // ==========================================================================
313     // Internal attributes, Const related:
314     // ==========================================================================
315
316     rustc_attr!(rustc_promotable, AssumedUsed, template!(Word), IMPL_DETAIL),
317     rustc_attr!(rustc_args_required_const, AssumedUsed, template!(List: "N"), INTERNAL_UNSTABLE),
318
319     // ==========================================================================
320     // Internal attributes, Layout related:
321     // ==========================================================================
322
323     rustc_attr!(
324         rustc_layout_scalar_valid_range_start, AssumedUsed, template!(List: "value"),
325         "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
326         niche optimizations in libcore and will never be stable",
327     ),
328     rustc_attr!(
329         rustc_layout_scalar_valid_range_end, AssumedUsed, template!(List: "value"),
330         "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
331         niche optimizations in libcore and will never be stable",
332     ),
333     rustc_attr!(
334         rustc_nonnull_optimization_guaranteed, AssumedUsed, template!(Word),
335         "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
336         niche optimizations in libcore and will never be stable",
337     ),
338
339     // ==========================================================================
340     // Internal attributes, Misc:
341     // ==========================================================================
342     gated!(
343         lang, Normal, template!(NameValueStr: "name"), lang_items,
344         "language items are subject to change",
345     ),
346     gated!(rustc_diagnostic_item), // XXX modified in rust-analyzer
347     gated!(
348         // Used in resolve:
349         prelude_import, AssumedUsed, template!(Word),
350         "`#[prelude_import]` is for use by rustc only",
351     ),
352     gated!(
353         rustc_paren_sugar, Normal, template!(Word), unboxed_closures,
354         "unboxed_closures are still evolving",
355     ),
356     rustc_attr!(
357         rustc_inherit_overflow_checks, AssumedUsed, template!(Word),
358         "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
359         overflow checking behavior of several libcore functions that are inlined \
360         across crates and will never be stable",
361     ),
362     rustc_attr!(rustc_reservation_impl, Normal, template!(NameValueStr: "reservation message"),
363                 "the `#[rustc_reservation_impl]` attribute is internally used \
364                  for reserving for `for<T> From<!> for T` impl"
365     ),
366     rustc_attr!(
367         rustc_test_marker, Normal, template!(Word),
368         "the `#[rustc_test_marker]` attribute is used internally to track tests",
369     ),
370     rustc_attr!(
371         rustc_unsafe_specialization_marker, Normal, template!(Word),
372         "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations"
373     ),
374     rustc_attr!(
375         rustc_specialization_trait, Normal, template!(Word),
376         "the `#[rustc_specialization_trait]` attribute is used to check specializations"
377     ),
378
379     // ==========================================================================
380     // Internal attributes, Testing:
381     // ==========================================================================
382
383     rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
384     rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word)),
385     rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
386     rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
387     rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
388     rustc_attr!(
389         TEST, rustc_error, AssumedUsed,
390         template!(Word, List: "delay_span_bug_from_inside_query")
391     ),
392     rustc_attr!(TEST, rustc_dump_user_substs, AssumedUsed, template!(Word)),
393     rustc_attr!(TEST, rustc_if_this_changed, AssumedUsed, template!(Word, List: "DepNode")),
394     rustc_attr!(TEST, rustc_then_this_would_need, AssumedUsed, template!(List: "DepNode")),
395     rustc_attr!(
396         TEST, rustc_dirty, AssumedUsed,
397         template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
398     ),
399     rustc_attr!(
400         TEST, rustc_clean, AssumedUsed,
401         template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
402     ),
403     rustc_attr!(
404         TEST, rustc_partition_reused, AssumedUsed,
405         template!(List: r#"cfg = "...", module = "...""#),
406     ),
407     rustc_attr!(
408         TEST, rustc_partition_codegened, AssumedUsed,
409         template!(List: r#"cfg = "...", module = "...""#),
410     ),
411     rustc_attr!(
412         TEST, rustc_expected_cgu_reuse, AssumedUsed,
413         template!(List: r#"cfg = "...", module = "...", kind = "...""#),
414     ),
415     rustc_attr!(TEST, rustc_synthetic, AssumedUsed, template!(Word)),
416     rustc_attr!(TEST, rustc_symbol_name, AssumedUsed, template!(Word)),
417     rustc_attr!(TEST, rustc_polymorphize_error, AssumedUsed, template!(Word)),
418     rustc_attr!(TEST, rustc_def_path, AssumedUsed, template!(Word)),
419     rustc_attr!(TEST, rustc_mir, AssumedUsed, template!(List: "arg1, arg2, ...")),
420     rustc_attr!(TEST, rustc_dump_program_clauses, AssumedUsed, template!(Word)),
421     rustc_attr!(TEST, rustc_dump_env_program_clauses, AssumedUsed, template!(Word)),
422     rustc_attr!(TEST, rustc_object_lifetime_default, AssumedUsed, template!(Word)),
423     rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)),
424     gated!(
425         omit_gdb_pretty_printer_section, AssumedUsed, template!(Word),
426         "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
427     ),
428 ];