]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_span/src/symbol.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / compiler / rustc_span / src / symbol.rs
CommitLineData
476ff2be 1//! An "interner" is a data structure that associates values with usize tags and
0731742a 2//! allows bidirectional lookup; i.e., given a value, one can easily find the
476ff2be
SL
3//! type, and vice versa.
4
f035d41b 5use rustc_arena::DroplessArena;
0731742a 6use rustc_data_structures::fx::FxHashMap;
dfeec247 7use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
3dfed10e 8use rustc_macros::HashStable_Generic;
416331ca 9use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
0731742a 10
dfeec247 11use std::cmp::{Ord, PartialEq, PartialOrd};
dc9dc135 12use std::fmt;
83c7162d 13use std::hash::{Hash, Hasher};
dc9dc135 14use std::str;
476ff2be 15
fc512014 16use crate::{Edition, Span, DUMMY_SP, SESSION_GLOBALS};
0731742a 17
416331ca
XL
18#[cfg(test)]
19mod tests;
20
6a06907d 21// The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
48663c56
XL
22symbols! {
23 // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
24 // this should be rarely necessary though if the keywords are kept in alphabetic order.
25 Keywords {
26 // Special reserved identifiers used internally for elided lifetimes,
27 // unnamed method parameters, crate root module, error recovery etc.
5869c6ff 28 Empty: "",
48663c56
XL
29 PathRoot: "{{root}}",
30 DollarCrate: "$crate",
31 Underscore: "_",
32
33 // Keywords that are used in stable Rust.
34 As: "as",
35 Break: "break",
36 Const: "const",
37 Continue: "continue",
38 Crate: "crate",
39 Else: "else",
40 Enum: "enum",
41 Extern: "extern",
42 False: "false",
43 Fn: "fn",
44 For: "for",
45 If: "if",
46 Impl: "impl",
47 In: "in",
48 Let: "let",
49 Loop: "loop",
50 Match: "match",
51 Mod: "mod",
52 Move: "move",
53 Mut: "mut",
54 Pub: "pub",
55 Ref: "ref",
56 Return: "return",
57 SelfLower: "self",
58 SelfUpper: "Self",
59 Static: "static",
60 Struct: "struct",
61 Super: "super",
62 Trait: "trait",
63 True: "true",
64 Type: "type",
65 Unsafe: "unsafe",
66 Use: "use",
67 Where: "where",
68 While: "while",
69
70 // Keywords that are used in unstable Rust or reserved for future use.
71 Abstract: "abstract",
72 Become: "become",
73 Box: "box",
74 Do: "do",
75 Final: "final",
76 Macro: "macro",
77 Override: "override",
78 Priv: "priv",
79 Typeof: "typeof",
80 Unsized: "unsized",
81 Virtual: "virtual",
82 Yield: "yield",
83
84 // Edition-specific keywords that are used in stable Rust.
e1599b0c
XL
85 Async: "async", // >= 2018 Edition only
86 Await: "await", // >= 2018 Edition only
48663c56
XL
87 Dyn: "dyn", // >= 2018 Edition only
88
89 // Edition-specific keywords that are used in unstable Rust or reserved for future use.
48663c56
XL
90 Try: "try", // >= 2018 Edition only
91
92 // Special lifetime names
93 UnderscoreLifetime: "'_",
94 StaticLifetime: "'static",
95
96 // Weak keywords, have special meaning only in specific contexts.
97 Auto: "auto",
98 Catch: "catch",
99 Default: "default",
74b04a01 100 MacroRules: "macro_rules",
60c5eb7d 101 Raw: "raw",
48663c56
XL
102 Union: "union",
103 }
104
3dfed10e
XL
105 // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
106 //
107 // The symbol is the stringified identifier unless otherwise specified, in
108 // which case the name should mention the non-identifier punctuation.
109 // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
110 // called `sym::proc_macro` because then it's easy to mistakenly think it
111 // represents "proc_macro".
dc9dc135 112 //
1b1a35ee 113 // As well as the symbols listed, there are symbols for the strings
dc9dc135 114 // "0", "1", ..., "9", which are accessible via `sym::integer`.
3dfed10e
XL
115 //
116 // The proc macro will abort if symbols are not in alphabetical order (as
117 // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
118 // users can sort the list by selecting it and executing the command
119 // `:'<,'>!LC_ALL=C sort`.
120 //
121 // There is currently no checking that all symbols are used; that would be
122 // nice to have.
48663c56 123 Symbols {
3dfed10e
XL
124 Alignment,
125 Arc,
126 Argument,
127 ArgumentV1,
128 Arguments,
6a06907d
XL
129 BTreeMap,
130 BTreeSet,
131 BinaryHeap,
132 Borrow,
3dfed10e 133 C,
29967ef6 134 CString,
3dfed10e
XL
135 Center,
136 Clone,
137 Copy,
138 Count,
139 Debug,
5869c6ff
XL
140 DebugStruct,
141 DebugTuple,
3dfed10e
XL
142 Decodable,
143 Decoder,
144 Default,
6a06907d 145 Deref,
3dfed10e
XL
146 Encodable,
147 Encoder,
148 Eq,
149 Equal,
150 Err,
151 Error,
152 FormatSpec,
153 Formatter,
154 From,
155 Future,
156 FxHashMap,
157 FxHashSet,
158 GlobalAlloc,
159 Hash,
160 HashMap,
161 HashSet,
162 Hasher,
163 Implied,
164 Input,
165 IntoIterator,
166 Is,
167 ItemContext,
168 Iterator,
169 Layout,
170 Left,
6a06907d 171 LinkedList,
3dfed10e
XL
172 LintPass,
173 None,
174 Ok,
175 Option,
176 Ord,
177 Ordering,
6a06907d
XL
178 OsStr,
179 OsString,
3dfed10e
XL
180 Output,
181 Param,
182 PartialEq,
183 PartialOrd,
6a06907d
XL
184 Path,
185 PathBuf,
3dfed10e
XL
186 Pending,
187 Pin,
188 Poll,
189 ProcMacro,
190 ProcMacroHack,
191 ProceduralMasqueradeDummyType,
192 Range,
193 RangeFrom,
194 RangeFull,
195 RangeInclusive,
196 RangeTo,
197 RangeToInclusive,
198 Rc,
199 Ready,
6a06907d 200 Receiver,
3dfed10e
XL
201 Result,
202 Return,
203 Right,
204 RustcDecodable,
205 RustcEncodable,
206 Send,
207 Some,
208 StructuralEq,
209 StructuralPartialEq,
210 Sync,
211 Target,
6a06907d
XL
212 ToOwned,
213 ToString,
3dfed10e
XL
214 Try,
215 Ty,
216 TyCtxt,
217 TyKind,
218 Unknown,
219 Vec,
220 Yield,
221 _DECLS,
222 _Self,
223 __D,
224 __H,
225 __S,
226 __next,
227 __try_var,
228 _d,
229 _e,
230 _task_context,
29967ef6 231 a32,
48663c56
XL
232 aarch64_target_feature,
233 abi,
234 abi_amdgpu_kernel,
3dfed10e 235 abi_avr_interrupt,
5869c6ff 236 abi_c_cmse_nonsecure_call,
e74abb32 237 abi_efiapi,
48663c56
XL
238 abi_msp430_interrupt,
239 abi_ptx,
240 abi_sysv64,
241 abi_thiscall,
242 abi_unadjusted,
243 abi_vectorcall,
244 abi_x86_interrupt,
ba9703b0 245 abort,
48663c56 246 aborts,
3dfed10e
XL
247 add,
248 add_assign,
60c5eb7d 249 add_with_overflow,
3dfed10e 250 address,
48663c56
XL
251 advanced_slice_patterns,
252 adx_target_feature,
253 alias,
254 align,
3dfed10e 255 align_offset,
48663c56
XL
256 alignstack,
257 all,
3dfed10e
XL
258 alloc,
259 alloc_error_handler,
260 alloc_layout,
261 alloc_zeroed,
48663c56
XL
262 allocator,
263 allocator_internals,
48663c56 264 allow,
48663c56
XL
265 allow_fail,
266 allow_internal_unsafe,
267 allow_internal_unstable,
3dfed10e 268 allowed,
48663c56 269 always,
dc9dc135 270 and,
3dfed10e 271 and_then,
48663c56 272 any,
dc9dc135 273 arbitrary_enum_discriminant,
48663c56 274 arbitrary_self_types,
f9f354fc 275 arith_offset,
29967ef6 276 arm,
48663c56 277 arm_target_feature,
3dfed10e
XL
278 array,
279 arrays,
29967ef6 280 as_ptr,
3dfed10e 281 as_str,
48663c56 282 asm,
416331ca 283 assert,
f035d41b 284 assert_inhabited,
fc512014 285 assert_macro,
3dfed10e 286 assert_receiver_is_total_eq,
f035d41b
XL
287 assert_uninit_valid,
288 assert_zero_valid,
48663c56 289 associated_consts,
dc9dc135 290 associated_type_bounds,
48663c56
XL
291 associated_type_defaults,
292 associated_types,
f035d41b 293 assume,
60c5eb7d 294 assume_init,
48663c56 295 async_await,
416331ca 296 async_closure,
f035d41b 297 atomics,
3dfed10e 298 att_syntax,
48663c56 299 attr,
48663c56 300 attr_literals,
3dfed10e 301 attributes,
48663c56 302 augmented_assignments,
fc512014 303 auto_traits,
48663c56
XL
304 automatically_derived,
305 avx512_target_feature,
306 await_macro,
3dfed10e 307 bang,
dc9dc135
XL
308 begin_panic,
309 bench,
48663c56
XL
310 bin,
311 bind_by_move_pattern_guards,
dfeec247 312 bindings_after_at,
3dfed10e
XL
313 bitand,
314 bitand_assign,
315 bitor,
316 bitor_assign,
317 bitreverse,
318 bitxor,
319 bitxor_assign,
48663c56 320 block,
dc9dc135 321 bool,
dfeec247 322 borrowck_graphviz_format,
48663c56
XL
323 borrowck_graphviz_postflow,
324 borrowck_graphviz_preflow,
3dfed10e 325 box_free,
48663c56
XL
326 box_patterns,
327 box_syntax,
328 braced_empty_structs,
f035d41b 329 breakpoint,
3dfed10e 330 bridge,
60c5eb7d 331 bswap,
29967ef6 332 c_str,
6a06907d 333 c_unwind,
3dfed10e
XL
334 c_variadic,
335 call,
336 call_mut,
337 call_once,
60c5eb7d 338 caller_location,
fc512014 339 capture_disjoint_fields,
48663c56 340 cdylib,
f035d41b
XL
341 ceilf32,
342 ceilf64,
48663c56 343 cfg,
ba9703b0 344 cfg_accessible,
48663c56
XL
345 cfg_attr,
346 cfg_attr_multi,
416331ca 347 cfg_doctest,
6a06907d 348 cfg_eval,
29967ef6 349 cfg_panic,
60c5eb7d 350 cfg_sanitize,
48663c56
XL
351 cfg_target_feature,
352 cfg_target_has_atomic,
353 cfg_target_thread_local,
354 cfg_target_vendor,
f9f354fc 355 cfg_version,
dc9dc135 356 char,
3dfed10e 357 client,
416331ca 358 clippy,
48663c56
XL
359 clone,
360 clone_closures,
361 clone_from,
1b1a35ee 362 closure,
48663c56 363 closure_to_fn_coercion,
dc9dc135 364 cmp,
48663c56 365 cmpxchg16b_target_feature,
1b1a35ee 366 cmse_nonsecure_entry,
3dfed10e 367 coerce_unsized,
48663c56 368 cold,
416331ca 369 column,
48663c56
XL
370 compile_error,
371 compiler_builtins,
416331ca 372 concat,
48663c56
XL
373 concat_idents,
374 conservative_impl_trait,
375 console,
fc512014 376 const_allocate,
48663c56 377 const_compare_raw_pointers,
dc9dc135 378 const_constructor,
74b04a01 379 const_eval_limit,
1b1a35ee 380 const_evaluatable_checked,
e74abb32 381 const_extern_fn,
48663c56 382 const_fn,
1b1a35ee
XL
383 const_fn_floating_point_arithmetic,
384 const_fn_fn_ptr_basics,
f035d41b 385 const_fn_transmute,
48663c56
XL
386 const_fn_union,
387 const_generics,
5869c6ff 388 const_generics_defaults,
60c5eb7d 389 const_if_match,
29967ef6 390 const_impl_trait,
416331ca 391 const_in_array_repeat_expressions,
3dfed10e 392 const_indexing,
48663c56 393 const_let,
60c5eb7d
XL
394 const_loop,
395 const_mut_refs,
48663c56 396 const_panic,
f035d41b 397 const_precise_live_drops,
3dfed10e 398 const_ptr,
48663c56
XL
399 const_raw_ptr_deref,
400 const_raw_ptr_to_usize_cast,
5869c6ff 401 const_refs_to_cell,
3dfed10e 402 const_slice_ptr,
dfeec247
XL
403 const_trait_bound_opt_out,
404 const_trait_impl,
3dfed10e 405 const_transmute,
1b1a35ee
XL
406 constant,
407 constructor,
48663c56 408 contents,
dc9dc135 409 context,
48663c56 410 convert,
f035d41b 411 copy,
3dfed10e 412 copy_closures,
f035d41b
XL
413 copy_nonoverlapping,
414 copysignf32,
415 copysignf64,
48663c56
XL
416 core,
417 core_intrinsics,
5869c6ff
XL
418 core_panic,
419 core_panic_2015_macro,
fc512014 420 core_panic_macro,
f035d41b
XL
421 cosf32,
422 cosf64,
48663c56
XL
423 crate_id,
424 crate_in_paths,
dc9dc135 425 crate_local,
48663c56
XL
426 crate_name,
427 crate_type,
428 crate_visibility_modifier,
3dfed10e 429 crt_dash_static: "crt-static",
29967ef6 430 cstring_type,
3dfed10e
XL
431 ctlz,
432 ctlz_nonzero,
60c5eb7d
XL
433 ctpop,
434 cttz,
435 cttz_nonzero,
48663c56
XL
436 custom_attribute,
437 custom_derive,
438 custom_inner_attributes,
439 custom_test_frameworks,
3dfed10e
XL
440 d,
441 dead_code,
442 dealloc,
443 debug,
fc512014 444 debug_assert_macro,
3dfed10e
XL
445 debug_assertions,
446 debug_struct,
e1599b0c 447 debug_trait,
3dfed10e
XL
448 debug_trait_builder,
449 debug_tuple,
48663c56 450 decl_macro,
3dfed10e
XL
451 declare_lint_pass,
452 decode,
29967ef6 453 default_alloc_error_handler,
48663c56
XL
454 default_lib_allocator,
455 default_type_parameter_fallback,
456 default_type_params,
60c5eb7d 457 delay_span_bug_from_inside_query,
48663c56
XL
458 deny,
459 deprecated,
dc9dc135 460 deref,
1b1a35ee 461 deref_method,
dc9dc135 462 deref_mut,
1b1a35ee 463 deref_target,
48663c56 464 derive,
29967ef6 465 destructuring_assignment,
e1599b0c 466 diagnostic,
dc9dc135 467 direct,
3dfed10e
XL
468 discriminant_kind,
469 discriminant_type,
ba9703b0 470 discriminant_value,
3dfed10e
XL
471 dispatch_from_dyn,
472 div,
473 div_assign,
48663c56
XL
474 doc,
475 doc_alias,
476 doc_cfg,
477 doc_keyword,
478 doc_masked,
3dfed10e 479 doc_spotlight,
416331ca 480 doctest,
48663c56 481 document_private_items,
48663c56 482 dotdot_in_tuple_patterns,
3dfed10e 483 dotdoteq_in_patterns,
fc512014
XL
484 dreg,
485 dreg_low16,
486 dreg_low8,
3dfed10e
XL
487 drop,
488 drop_in_place,
489 drop_types_in_const,
48663c56
XL
490 dropck_eyepatch,
491 dropck_parametricity,
48663c56 492 dylib,
6a06907d 493 dyn_metadata,
48663c56 494 dyn_trait,
5869c6ff 495 edition_macro_pats,
3dfed10e 496 eh_catch_typeinfo,
48663c56 497 eh_personality,
3dfed10e
XL
498 emit_enum,
499 emit_enum_variant,
500 emit_enum_variant_arg,
501 emit_struct,
502 emit_struct_field,
48663c56 503 enable,
3dfed10e
XL
504 enclosing_scope,
505 encode,
416331ca 506 env,
dc9dc135 507 eq,
29967ef6 508 ermsb_target_feature,
48663c56 509 err,
f035d41b 510 exact_div,
48663c56 511 except,
3dfed10e 512 exchange_malloc,
48663c56
XL
513 exclusive_range_pattern,
514 exhaustive_integer_patterns,
515 exhaustive_patterns,
516 existential_type,
f035d41b
XL
517 exp2f32,
518 exp2f64,
29967ef6 519 expect,
48663c56 520 expected,
3dfed10e
XL
521 expf32,
522 expf64,
48663c56 523 export_name,
dc9dc135 524 expr,
fc512014 525 extended_key_value_attributes,
48663c56 526 extern_absolute_paths,
48663c56
XL
527 extern_crate_item_prelude,
528 extern_crate_self,
529 extern_in_paths,
530 extern_prelude,
531 extern_types,
3dfed10e
XL
532 external_doc,
533 f,
48663c56 534 f16c_target_feature,
dc9dc135 535 f32,
3dfed10e 536 f32_runtime,
dc9dc135 537 f64,
3dfed10e 538 f64_runtime,
f035d41b
XL
539 fabsf32,
540 fabsf64,
3dfed10e 541 fadd_fast,
f035d41b 542 fdiv_fast,
48663c56 543 feature,
29967ef6 544 ffi,
f9f354fc
XL
545 ffi_const,
546 ffi_pure,
48663c56 547 ffi_returns_twice,
dc9dc135 548 field,
48663c56
XL
549 field_init_shorthand,
550 file,
3dfed10e
XL
551 fill,
552 finish,
553 flags,
f035d41b 554 float_to_int_unchecked,
f035d41b 555 floorf32,
3dfed10e 556 floorf64,
f035d41b
XL
557 fmaf32,
558 fmaf64,
dc9dc135
XL
559 fmt,
560 fmt_internals,
f035d41b 561 fmul_fast,
48663c56 562 fn_must_use,
3dfed10e
XL
563 fn_mut,
564 fn_once,
565 fn_once_output,
48663c56 566 forbid,
f035d41b 567 forget,
3dfed10e 568 format,
416331ca 569 format_args,
f035d41b 570 format_args_capture,
3dfed10e 571 format_args_nl,
6a06907d 572 format_macro,
3dfed10e 573 freeze,
fc512014 574 freg,
f035d41b 575 frem_fast,
48663c56 576 from,
dc9dc135 577 from_desugaring,
48663c56
XL
578 from_error,
579 from_generator,
dc9dc135 580 from_method,
48663c56 581 from_ok,
3dfed10e 582 from_size_align_unchecked,
f035d41b 583 from_trait,
3dfed10e 584 from_usize,
f035d41b 585 fsub_fast,
48663c56
XL
586 fundamental,
587 future,
3dfed10e
XL
588 future_trait,
589 ge,
48663c56 590 gen_future,
dfeec247 591 gen_kill,
3dfed10e
XL
592 generator,
593 generator_state,
48663c56
XL
594 generators,
595 generic_associated_types,
596 generic_param_attrs,
ba9703b0 597 get_context,
48663c56
XL
598 global_allocator,
599 global_asm,
600 globs,
3dfed10e 601 gt,
dfeec247 602 half_open_range_patterns,
dc9dc135 603 hash,
6a06907d
XL
604 hashmap_type,
605 hashset_type,
48663c56
XL
606 hexagon_target_feature,
607 hidden,
608 homogeneous_aggregate,
609 html_favicon_url,
610 html_logo_url,
611 html_no_source,
612 html_playground_url,
613 html_root_url,
6a06907d 614 hwaddress,
3dfed10e 615 i,
48663c56
XL
616 i128,
617 i128_type,
618 i16,
619 i32,
620 i64,
621 i8,
622 ident,
623 if_let,
3dfed10e 624 if_let_guard,
48663c56
XL
625 if_while_or_patterns,
626 ignore,
627 impl_header_lifetime_elision,
416331ca 628 impl_lint_pass,
3dfed10e 629 impl_macros,
48663c56
XL
630 impl_trait_in_bindings,
631 import_shadowing,
632 in_band_lifetimes,
633 include,
416331ca
XL
634 include_bytes,
635 include_str,
48663c56 636 inclusive_range_syntax,
3dfed10e
XL
637 index,
638 index_mut,
48663c56
XL
639 infer_outlives_requirements,
640 infer_static_outlives_requirements,
6a06907d 641 inherent_associated_types,
3dfed10e 642 inlateout,
48663c56 643 inline,
29967ef6 644 inline_const,
3dfed10e 645 inout,
29967ef6 646 instruction_set,
48663c56
XL
647 intel,
648 into_iter,
48663c56 649 into_result,
5869c6ff
XL
650 into_trait,
651 intra_doc_pointers,
48663c56
XL
652 intrinsics,
653 irrefutable_let_patterns,
29967ef6 654 isa_attribute,
48663c56
XL
655 isize,
656 issue,
657 issue_5723_bootstrap,
658 issue_tracker_base_url,
dc9dc135 659 item,
48663c56
XL
660 item_like_imports,
661 iter,
48663c56
XL
662 keyword,
663 kind,
fc512014 664 kreg,
48663c56
XL
665 label,
666 label_break_value,
667 lang,
668 lang_items,
f9f354fc 669 lateout,
3dfed10e
XL
670 lazy_normalization_consts,
671 le,
dc9dc135
XL
672 let_chains,
673 lhs,
48663c56 674 lib,
3dfed10e 675 libc,
dc9dc135 676 lifetime,
f035d41b 677 likely,
416331ca 678 line,
48663c56 679 link,
48663c56
XL
680 link_args,
681 link_cfg,
682 link_llvm_intrinsics,
683 link_name,
e74abb32 684 link_ordinal,
48663c56 685 link_section,
3dfed10e 686 linkage,
48663c56 687 lint_reasons,
dc9dc135 688 literal,
ba9703b0 689 llvm_asm,
fc512014 690 local,
48663c56 691 local_inner_macros,
f035d41b
XL
692 log10f32,
693 log10f64,
694 log2f32,
695 log2f64,
3dfed10e
XL
696 log_syntax,
697 logf32,
698 logf64,
48663c56 699 loop_break_value,
3dfed10e 700 lt,
48663c56 701 macro_at_most_once_rep,
6a06907d 702 macro_attributes_in_derive_output,
48663c56
XL
703 macro_escape,
704 macro_export,
705 macro_lifetime_matcher,
706 macro_literal_matcher,
707 macro_reexport,
48663c56
XL
708 macro_use,
709 macro_vis_matcher,
3dfed10e 710 macros_in_extern,
48663c56
XL
711 main,
712 managed_boxes,
3dfed10e
XL
713 manually_drop,
714 map,
48663c56
XL
715 marker,
716 marker_trait_attr,
717 masked,
718 match_beginning_vert,
719 match_default_bindings,
3dfed10e
XL
720 maxnumf32,
721 maxnumf64,
48663c56 722 may_dangle,
3dfed10e 723 maybe_uninit,
60c5eb7d
XL
724 maybe_uninit_uninit,
725 maybe_uninit_zeroed,
726 mem_uninitialized,
727 mem_zeroed,
dc9dc135 728 member_constraints,
74b04a01 729 memory,
48663c56
XL
730 message,
731 meta,
6a06907d 732 metadata_type,
60c5eb7d 733 min_align_of,
f035d41b 734 min_align_of_val,
48663c56 735 min_const_fn,
3dfed10e 736 min_const_generics,
48663c56 737 min_const_unsafe_fn,
ba9703b0 738 min_specialization,
6a06907d 739 min_type_alias_impl_trait,
f035d41b
XL
740 minnumf32,
741 minnumf64,
48663c56 742 mips_target_feature,
1b1a35ee 743 misc,
48663c56 744 module,
416331ca 745 module_path,
48663c56 746 more_struct_aliases,
3dfed10e 747 movbe_target_feature,
74b04a01 748 move_ref_pattern,
3dfed10e
XL
749 mul,
750 mul_assign,
60c5eb7d 751 mul_with_overflow,
48663c56 752 must_use,
3dfed10e
XL
753 mut_ptr,
754 mut_slice_ptr,
48663c56
XL
755 naked,
756 naked_functions,
757 name,
3dfed10e 758 ne,
f035d41b
XL
759 nearbyintf32,
760 nearbyintf64,
48663c56 761 needs_allocator,
60c5eb7d 762 needs_drop,
48663c56 763 needs_panic_runtime,
3dfed10e 764 neg,
48663c56 765 negate_unsigned,
ba9703b0 766 negative_impls,
48663c56
XL
767 never,
768 never_type,
60c5eb7d 769 never_type_fallback,
dc9dc135 770 new,
3dfed10e 771 new_unchecked,
48663c56 772 next,
48663c56 773 nll,
3dfed10e 774 no,
48663c56
XL
775 no_builtins,
776 no_core,
777 no_crate_inject,
778 no_debug,
779 no_default_passes,
780 no_implicit_prelude,
781 no_inline,
782 no_link,
783 no_main,
784 no_mangle,
3dfed10e
XL
785 no_niche,
786 no_sanitize,
787 no_stack_check,
788 no_start,
789 no_std,
f9f354fc 790 nomem,
48663c56 791 non_ascii_idents,
48663c56
XL
792 non_exhaustive,
793 non_modrs_mods,
3dfed10e 794 none_error,
f035d41b 795 nontemporal_store,
3dfed10e 796 nontrapping_dash_fptoint: "nontrapping-fptoint",
6a06907d
XL
797 noop_method_borrow,
798 noop_method_clone,
799 noop_method_deref,
f9f354fc 800 noreturn,
f9f354fc 801 nostack,
48663c56
XL
802 not,
803 note,
e74abb32 804 object_safe_for_dispatch,
3dfed10e 805 of,
f9f354fc 806 offset,
48663c56
XL
807 omit_gdb_pretty_printer_section,
808 on,
809 on_unimplemented,
810 oom,
3dfed10e 811 opaque,
48663c56 812 ops,
3dfed10e 813 opt_out_copy,
48663c56
XL
814 optimize,
815 optimize_attribute,
816 optin_builtin_traits,
817 option,
416331ca 818 option_env,
3dfed10e 819 option_type,
f9f354fc 820 options,
dc9dc135 821 or,
e1599b0c 822 or_patterns,
3dfed10e 823 other,
f9f354fc 824 out,
48663c56 825 overlapping_marker_traits,
3dfed10e 826 owned_box,
48663c56 827 packed,
dc9dc135 828 panic,
5869c6ff
XL
829 panic_2015,
830 panic_2021,
3dfed10e
XL
831 panic_abort,
832 panic_bounds_check,
48663c56
XL
833 panic_handler,
834 panic_impl,
835 panic_implementation,
3dfed10e
XL
836 panic_info,
837 panic_location,
48663c56 838 panic_runtime,
29967ef6 839 panic_str,
3dfed10e 840 panic_unwind,
fc512014 841 panicking,
3dfed10e 842 param_attrs,
dc9dc135
XL
843 parent_trait,
844 partial_cmp,
3dfed10e 845 partial_ord,
48663c56 846 passes,
dc9dc135 847 pat,
5869c6ff
XL
848 pat2018,
849 pat2021,
48663c56
XL
850 path,
851 pattern_parentheses,
3dfed10e 852 phantom_data,
48663c56 853 pin,
48663c56
XL
854 pinned,
855 platform_intrinsics,
856 plugin,
857 plugin_registrar,
858 plugins,
6a06907d 859 pointee_trait,
3dfed10e 860 pointer,
29967ef6
XL
861 pointer_trait,
862 pointer_trait_fmt,
ba9703b0 863 poll,
3dfed10e
XL
864 position,
865 post_dash_lto: "post-lto",
48663c56 866 powerpc_target_feature,
f035d41b
XL
867 powf32,
868 powf64,
869 powif32,
870 powif64,
3dfed10e 871 pre_dash_lto: "pre-lto",
48663c56 872 precise_pointer_size_matching,
3dfed10e 873 precision,
60c5eb7d 874 pref_align_of,
f035d41b
XL
875 prefetch_read_data,
876 prefetch_read_instruction,
877 prefetch_write_data,
878 prefetch_write_instruction,
48663c56
XL
879 prelude,
880 prelude_import,
f9f354fc 881 preserves_flags,
48663c56
XL
882 primitive,
883 proc_dash_macro: "proc-macro",
884 proc_macro,
885 proc_macro_attribute,
dc9dc135 886 proc_macro_def_site,
48663c56
XL
887 proc_macro_derive,
888 proc_macro_expr,
889 proc_macro_gen,
890 proc_macro_hygiene,
416331ca 891 proc_macro_internals,
48663c56
XL
892 proc_macro_mod,
893 proc_macro_non_items,
894 proc_macro_path_invoc,
f035d41b 895 profiler_builtins,
48663c56 896 profiler_runtime,
f035d41b
XL
897 ptr_guaranteed_eq,
898 ptr_guaranteed_ne,
60c5eb7d 899 ptr_offset_from,
6a06907d 900 pub_macro_rules,
48663c56 901 pub_restricted,
f9f354fc 902 pure,
48663c56 903 pushpop_unsafe,
fc512014
XL
904 qreg,
905 qreg_low4,
906 qreg_low8,
48663c56
XL
907 quad_precision_float,
908 question_mark,
909 quote,
3dfed10e 910 range_inclusive_new,
e74abb32 911 raw_dylib,
48663c56 912 raw_identifiers,
60c5eb7d 913 raw_ref_op,
3dfed10e
XL
914 re_rebalance_coherence,
915 read_enum,
916 read_enum_variant,
917 read_enum_variant_arg,
918 read_struct,
919 read_struct_field,
f9f354fc 920 readonly,
3dfed10e 921 realloc,
48663c56 922 reason,
3dfed10e 923 receiver,
48663c56
XL
924 recursion_limit,
925 reexport_test_harness_main,
3dfed10e 926 reference,
48663c56 927 reflect,
fc512014
XL
928 reg,
929 reg16,
930 reg32,
931 reg64,
932 reg_abcd,
933 reg_byte,
934 reg_thumb,
60c5eb7d
XL
935 register_attr,
936 register_tool,
48663c56 937 relaxed_adts,
5869c6ff 938 relaxed_struct_unsize,
3dfed10e
XL
939 rem,
940 rem_assign,
48663c56
XL
941 repr,
942 repr128,
943 repr_align,
944 repr_align_enum,
74b04a01 945 repr_no_niche,
48663c56
XL
946 repr_packed,
947 repr_simd,
948 repr_transparent,
48663c56 949 result,
3dfed10e 950 result_type,
dc9dc135 951 rhs,
f035d41b
XL
952 rintf32,
953 rintf64,
f9f354fc 954 riscv_target_feature,
48663c56 955 rlib,
60c5eb7d
XL
956 rotate_left,
957 rotate_right,
f035d41b
XL
958 roundf32,
959 roundf64,
dc9dc135 960 rt,
48663c56
XL
961 rtm_target_feature,
962 rust,
6a06907d 963 rust_2015,
48663c56 964 rust_2015_preview,
6a06907d 965 rust_2018,
48663c56 966 rust_2018_preview,
6a06907d 967 rust_2021,
5869c6ff 968 rust_2021_preview,
48663c56 969 rust_begin_unwind,
1b1a35ee 970 rust_eh_catch_typeinfo,
3dfed10e
XL
971 rust_eh_personality,
972 rust_eh_register_frames,
973 rust_eh_unregister_frames,
974 rust_oom,
dc9dc135
XL
975 rustc,
976 rustc_allocator,
48663c56 977 rustc_allocator_nounwind,
29967ef6 978 rustc_allow_const_fn_unstable,
48663c56
XL
979 rustc_args_required_const,
980 rustc_attrs,
416331ca 981 rustc_builtin_macro,
fc512014 982 rustc_capture_analysis,
48663c56 983 rustc_clean,
60c5eb7d 984 rustc_const_stable,
3dfed10e 985 rustc_const_unstable,
48663c56 986 rustc_conversion_suggestion,
48663c56
XL
987 rustc_def_path,
988 rustc_deprecated,
e1599b0c 989 rustc_diagnostic_item,
48663c56
XL
990 rustc_diagnostic_macros,
991 rustc_dirty,
dc9dc135 992 rustc_dummy,
48663c56
XL
993 rustc_dump_env_program_clauses,
994 rustc_dump_program_clauses,
995 rustc_dump_user_substs,
996 rustc_error,
997 rustc_expected_cgu_reuse,
998 rustc_if_this_changed,
999 rustc_inherit_overflow_checks,
1000 rustc_layout,
1001 rustc_layout_scalar_valid_range_end,
1002 rustc_layout_scalar_valid_range_start,
6a06907d 1003 rustc_legacy_const_generics,
416331ca 1004 rustc_macro_transparency,
48663c56 1005 rustc_mir,
dc9dc135 1006 rustc_nonnull_optimization_guaranteed,
48663c56
XL
1007 rustc_object_lifetime_default,
1008 rustc_on_unimplemented,
1009 rustc_outlives,
1010 rustc_paren_sugar,
1011 rustc_partition_codegened,
1012 rustc_partition_reused,
1013 rustc_peek,
1014 rustc_peek_definite_init,
3dfed10e 1015 rustc_peek_indirectly_mutable,
f9f354fc 1016 rustc_peek_liveness,
48663c56
XL
1017 rustc_peek_maybe_init,
1018 rustc_peek_maybe_uninit,
3dfed10e 1019 rustc_polymorphize_error,
48663c56
XL
1020 rustc_private,
1021 rustc_proc_macro_decls,
1022 rustc_promotable,
1023 rustc_regions,
3dfed10e
XL
1024 rustc_reservation_impl,
1025 rustc_serialize,
ba9703b0 1026 rustc_specialization_trait,
48663c56
XL
1027 rustc_stable,
1028 rustc_std_internal_symbol,
1029 rustc_symbol_name,
1030 rustc_synthetic,
1031 rustc_test_marker,
1032 rustc_then_this_would_need,
3dfed10e 1033 rustc_unsafe_specialization_marker,
48663c56 1034 rustc_variance,
6a06907d 1035 rustdoc,
416331ca 1036 rustfmt,
48663c56 1037 rvalue_static_promotion,
60c5eb7d 1038 sanitize,
48663c56 1039 sanitizer_runtime,
60c5eb7d
XL
1040 saturating_add,
1041 saturating_sub,
48663c56
XL
1042 self_in_typedefs,
1043 self_struct_ctor,
3dfed10e 1044 semitransparent,
60c5eb7d 1045 send_trait,
3dfed10e
XL
1046 shl,
1047 shl_assign,
48663c56 1048 should_panic,
3dfed10e
XL
1049 shr,
1050 shr_assign,
48663c56 1051 simd,
3dfed10e
XL
1052 simd_add,
1053 simd_and,
1054 simd_bitmask,
1055 simd_cast,
1056 simd_ceil,
1057 simd_div,
1058 simd_eq,
60c5eb7d 1059 simd_extract,
3dfed10e
XL
1060 simd_fabs,
1061 simd_fcos,
1062 simd_fexp,
1063 simd_fexp2,
48663c56 1064 simd_ffi,
3dfed10e
XL
1065 simd_flog,
1066 simd_flog10,
1067 simd_flog2,
1068 simd_floor,
1069 simd_fma,
1070 simd_fmax,
1071 simd_fmin,
1072 simd_fpow,
1073 simd_fpowi,
1074 simd_fsin,
1075 simd_fsqrt,
1076 simd_gather,
1077 simd_ge,
1078 simd_gt,
60c5eb7d 1079 simd_insert,
3dfed10e
XL
1080 simd_le,
1081 simd_lt,
1082 simd_mul,
1083 simd_ne,
6a06907d 1084 simd_neg,
3dfed10e
XL
1085 simd_or,
1086 simd_reduce_add_ordered,
1087 simd_reduce_add_unordered,
1088 simd_reduce_all,
1089 simd_reduce_and,
1090 simd_reduce_any,
1091 simd_reduce_max,
1092 simd_reduce_max_nanless,
1093 simd_reduce_min,
1094 simd_reduce_min_nanless,
1095 simd_reduce_mul_ordered,
1096 simd_reduce_mul_unordered,
1097 simd_reduce_or,
1098 simd_reduce_xor,
1099 simd_rem,
1100 simd_saturating_add,
1101 simd_saturating_sub,
1102 simd_scatter,
1103 simd_select,
1104 simd_select_bitmask,
1105 simd_shl,
1106 simd_shr,
1107 simd_sub,
1108 simd_xor,
48663c56 1109 since,
f035d41b
XL
1110 sinf32,
1111 sinf64,
48663c56 1112 size,
60c5eb7d 1113 size_of,
f035d41b 1114 size_of_val,
3dfed10e 1115 sized,
6a06907d 1116 skip,
3dfed10e
XL
1117 slice,
1118 slice_alloc,
48663c56 1119 slice_patterns,
3dfed10e
XL
1120 slice_u8,
1121 slice_u8_alloc,
48663c56 1122 slicing_syntax,
416331ca 1123 soft,
48663c56
XL
1124 specialization,
1125 speed,
3dfed10e 1126 spotlight,
f035d41b
XL
1127 sqrtf32,
1128 sqrtf64,
fc512014
XL
1129 sreg,
1130 sreg_low16,
48663c56
XL
1131 sse4a_target_feature,
1132 stable,
1133 staged_api,
1134 start,
3dfed10e 1135 state,
48663c56 1136 static_in_const,
48663c56
XL
1137 static_nobundle,
1138 static_recursion,
3dfed10e 1139 staticlib,
48663c56 1140 std,
416331ca 1141 std_inject,
5869c6ff
XL
1142 std_panic,
1143 std_panic_2015_macro,
fc512014 1144 std_panic_macro,
dc9dc135 1145 stmt,
48663c56
XL
1146 stmt_expr_attributes,
1147 stop_after_dataflow,
3dfed10e
XL
1148 str,
1149 str_alloc,
1150 string_type,
1151 stringify,
48663c56
XL
1152 struct_field_attributes,
1153 struct_inherit,
48663c56 1154 struct_variant,
3dfed10e
XL
1155 structural_match,
1156 structural_peq,
1157 structural_teq,
dc9dc135 1158 sty,
3dfed10e
XL
1159 sub,
1160 sub_assign,
60c5eb7d 1161 sub_with_overflow,
48663c56 1162 suggestion,
f9f354fc 1163 sym,
3dfed10e 1164 sync,
60c5eb7d 1165 sync_trait,
29967ef6 1166 t32,
3dfed10e
XL
1167 target_arch,
1168 target_endian,
1169 target_env,
1170 target_family,
48663c56 1171 target_feature,
f9f354fc 1172 target_feature_11,
48663c56 1173 target_has_atomic,
1b1a35ee 1174 target_has_atomic_equal_alignment,
e74abb32 1175 target_has_atomic_load_store,
3dfed10e
XL
1176 target_os,
1177 target_pointer_width,
1178 target_target_vendor,
48663c56 1179 target_thread_local,
3dfed10e 1180 target_vendor,
48663c56
XL
1181 task,
1182 tbm_target_feature,
3dfed10e 1183 termination,
48663c56
XL
1184 termination_trait,
1185 termination_trait_test,
1186 test,
1187 test_2018_feature,
1188 test_accepted_feature,
dc9dc135 1189 test_case,
48663c56
XL
1190 test_removed_feature,
1191 test_runner,
dc9dc135 1192 then_with,
74b04a01 1193 thread,
48663c56
XL
1194 thread_local,
1195 tool_attributes,
1196 tool_lints,
1197 trace_macros,
e74abb32 1198 track_caller,
48663c56
XL
1199 trait_alias,
1200 transmute,
1201 transparent,
dc9dc135
XL
1202 transparent_enums,
1203 transparent_unions,
48663c56 1204 trivial_bounds,
f035d41b
XL
1205 truncf32,
1206 truncf64,
48663c56 1207 try_blocks,
5869c6ff
XL
1208 try_from_trait,
1209 try_into_trait,
48663c56 1210 try_trait,
dc9dc135 1211 tt,
3dfed10e 1212 tuple,
29967ef6 1213 tuple_from_req,
48663c56 1214 tuple_indexing,
dfeec247 1215 two_phase,
48663c56
XL
1216 ty,
1217 type_alias_enum_variants,
3dfed10e 1218 type_alias_impl_trait,
48663c56 1219 type_ascription,
3dfed10e 1220 type_id,
48663c56
XL
1221 type_length_limit,
1222 type_macros,
3dfed10e 1223 type_name,
48663c56
XL
1224 u128,
1225 u16,
1226 u32,
1227 u64,
1228 u8,
f035d41b
XL
1229 unaligned_volatile_load,
1230 unaligned_volatile_store,
48663c56 1231 unboxed_closures,
74b04a01
XL
1232 unchecked_add,
1233 unchecked_div,
1234 unchecked_mul,
1235 unchecked_rem,
60c5eb7d
XL
1236 unchecked_shl,
1237 unchecked_shr,
74b04a01 1238 unchecked_sub,
48663c56
XL
1239 underscore_const_names,
1240 underscore_imports,
1241 underscore_lifetimes,
1242 uniform_paths,
3dfed10e 1243 unit,
48663c56 1244 universal_impl_trait,
3dfed10e 1245 unix,
f035d41b 1246 unlikely,
48663c56 1247 unmarked_api,
3dfed10e 1248 unpin,
f035d41b 1249 unreachable,
48663c56
XL
1250 unreachable_code,
1251 unrestricted_attribute_tokens,
f9f354fc 1252 unsafe_block_in_unsafe_fn,
3dfed10e 1253 unsafe_cell,
48663c56 1254 unsafe_no_drop_flag,
3dfed10e 1255 unsize,
29967ef6 1256 unsized_fn_params,
48663c56
XL
1257 unsized_locals,
1258 unsized_tuple_coercion,
1259 unstable,
1260 untagged_unions,
3dfed10e 1261 unused_qualifications,
48663c56
XL
1262 unwind,
1263 unwind_attributes,
29967ef6 1264 unwrap,
dc9dc135 1265 unwrap_or,
48663c56
XL
1266 use_extern_macros,
1267 use_nested_groups,
3dfed10e 1268 used,
48663c56
XL
1269 usize,
1270 v1,
f035d41b
XL
1271 va_arg,
1272 va_copy,
1273 va_end,
3dfed10e 1274 va_list,
f035d41b 1275 va_start,
3dfed10e
XL
1276 val,
1277 var,
1278 variant_count,
dc9dc135 1279 vec,
3dfed10e 1280 vec_type,
6a06907d 1281 vecdeque_type,
f9f354fc 1282 version,
48663c56
XL
1283 vis,
1284 visible_private_types,
1285 volatile,
f035d41b
XL
1286 volatile_copy_memory,
1287 volatile_copy_nonoverlapping_memory,
1288 volatile_load,
1289 volatile_set_memory,
1290 volatile_store,
fc512014
XL
1291 vreg,
1292 vreg_low16,
48663c56 1293 warn,
48663c56
XL
1294 wasm_import_module,
1295 wasm_target_feature,
1296 while_let,
3dfed10e 1297 width,
48663c56
XL
1298 windows,
1299 windows_subsystem,
60c5eb7d 1300 wrapping_add,
60c5eb7d 1301 wrapping_mul,
3dfed10e 1302 wrapping_sub,
f035d41b 1303 write_bytes,
fc512014
XL
1304 xmm_reg,
1305 ymm_reg,
1306 zmm_reg,
48663c56
XL
1307 }
1308}
1309
3dfed10e 1310#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
cc61c64b
XL
1311pub struct Ident {
1312 pub name: Symbol,
83c7162d 1313 pub span: Span,
cc61c64b
XL
1314}
1315
1316impl Ident {
83c7162d 1317 #[inline]
dc9dc135 1318 /// Constructs a new identifier from a symbol and a span.
83c7162d
XL
1319 pub const fn new(name: Symbol, span: Span) -> Ident {
1320 Ident { name, span }
1321 }
0731742a 1322
e1599b0c 1323 /// Constructs a new identifier with a dummy span.
83c7162d 1324 #[inline]
e1599b0c 1325 pub const fn with_dummy_span(name: Symbol) -> Ident {
83c7162d
XL
1326 Ident::new(name, DUMMY_SP)
1327 }
1328
dc9dc135
XL
1329 #[inline]
1330 pub fn invalid() -> Ident {
5869c6ff 1331 Ident::with_dummy_span(kw::Empty)
dc9dc135
XL
1332 }
1333
e1599b0c 1334 /// Maps a string to an identifier with a dummy span.
cc61c64b 1335 pub fn from_str(string: &str) -> Ident {
e1599b0c 1336 Ident::with_dummy_span(Symbol::intern(string))
cc61c64b
XL
1337 }
1338
dc9dc135
XL
1339 /// Maps a string and a span to an identifier.
1340 pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1341 Ident::new(Symbol::intern(string), span)
1342 }
1343
9fa01778 1344 /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
83c7162d
XL
1345 pub fn with_span_pos(self, span: Span) -> Ident {
1346 Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1347 }
1348
1349 pub fn without_first_quote(self) -> Ident {
0731742a 1350 Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
ff7c6d11
XL
1351 }
1352
8faf50e0 1353 /// "Normalize" ident for use in comparisons using "item hygiene".
ba9703b0 1354 /// Identifiers with same string value become same if they came from the same macro 2.0 macro
0731742a 1355 /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
ba9703b0 1356 /// different macro 2.0 macros.
8faf50e0 1357 /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
ba9703b0
XL
1358 pub fn normalize_to_macros_2_0(self) -> Ident {
1359 Ident::new(self.name, self.span.normalize_to_macros_2_0())
83c7162d
XL
1360 }
1361
8faf50e0
XL
1362 /// "Normalize" ident for use in comparisons using "local variable hygiene".
1363 /// Identifiers with same string value become same if they came from the same non-transparent
0731742a 1364 /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
8faf50e0
XL
1365 /// non-transparent macros.
1366 /// Technically, this operation strips all transparent marks from ident's syntactic context.
ba9703b0
XL
1367 pub fn normalize_to_macro_rules(self) -> Ident {
1368 Ident::new(self.name, self.span.normalize_to_macro_rules())
8faf50e0
XL
1369 }
1370
60c5eb7d
XL
1371 /// Convert the name to a `SymbolStr`. This is a slowish operation because
1372 /// it requires locking the symbol interner.
1373 pub fn as_str(self) -> SymbolStr {
94b46f34
XL
1374 self.name.as_str()
1375 }
83c7162d
XL
1376}
1377
1378impl PartialEq for Ident {
1379 fn eq(&self, rhs: &Self) -> bool {
1380 self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1381 }
1382}
1383
1384impl Hash for Ident {
1385 fn hash<H: Hasher>(&self, state: &mut H) {
1386 self.name.hash(state);
1387 self.span.ctxt().hash(state);
cc61c64b
XL
1388 }
1389}
1390
1391impl fmt::Debug for Ident {
9fa01778 1392 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74b04a01
XL
1393 fmt::Display::fmt(self, f)?;
1394 fmt::Debug::fmt(&self.span.ctxt(), f)
cc61c64b
XL
1395 }
1396}
1397
74b04a01
XL
1398/// This implementation is supposed to be used in error messages, so it's expected to be identical
1399/// to printing the original identifier token written in source code (`token_to_string`),
1400/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
cc61c64b 1401impl fmt::Display for Ident {
9fa01778 1402 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74b04a01 1403 fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
cc61c64b
XL
1404 }
1405}
1406
74b04a01
XL
1407/// This is the most general way to print identifiers.
1408/// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1409/// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1410/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1411/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1412/// hygiene data, most importantly name of the crate it refers to.
1413/// As a result we print `$crate` as `crate` if it refers to the local crate
1414/// and as `::other_crate_name` if it refers to some other crate.
1415/// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1416/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1417/// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1418/// done for a token stream or a single token.
1419pub struct IdentPrinter {
1420 symbol: Symbol,
1421 is_raw: bool,
1422 /// Span used for retrieving the crate name to which `$crate` refers to,
1423 /// if this field is `None` then the `$crate` conversion doesn't happen.
1424 convert_dollar_crate: Option<Span>,
1425}
1426
1427impl IdentPrinter {
1428 /// The most general `IdentPrinter` constructor. Do not use this.
1429 pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1430 IdentPrinter { symbol, is_raw, convert_dollar_crate }
1431 }
1432
1433 /// This implementation is supposed to be used when printing identifiers
1434 /// as a part of pretty-printing for larger AST pieces.
1435 /// Do not use this either.
1436 pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1437 IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1438 }
1439}
1440
1441impl fmt::Display for IdentPrinter {
1442 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1443 if self.is_raw {
1444 f.write_str("r#")?;
fc512014
XL
1445 } else if self.symbol == kw::DollarCrate {
1446 if let Some(span) = self.convert_dollar_crate {
1447 let converted = span.ctxt().dollar_crate_name();
1448 if !converted.is_path_segment_keyword() {
1449 f.write_str("::")?;
74b04a01 1450 }
fc512014 1451 return fmt::Display::fmt(&converted, f);
74b04a01
XL
1452 }
1453 }
1454 fmt::Display::fmt(&self.symbol, f)
1455 }
1456}
1457
ba9703b0
XL
1458/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1459/// construction.
1460// FIXME(matthewj, petrochenkov) Use this more often, add a similar
1461// `ModernIdent` struct and use that as well.
1462#[derive(Copy, Clone, Eq, PartialEq, Hash)]
1463pub struct MacroRulesNormalizedIdent(Ident);
1464
1465impl MacroRulesNormalizedIdent {
1466 pub fn new(ident: Ident) -> Self {
1467 Self(ident.normalize_to_macro_rules())
1468 }
1469}
1470
1471impl fmt::Debug for MacroRulesNormalizedIdent {
1472 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1473 fmt::Debug::fmt(&self.0, f)
1474 }
1475}
1476
1477impl fmt::Display for MacroRulesNormalizedIdent {
1478 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1479 fmt::Display::fmt(&self.0, f)
1480 }
1481}
1482
e74abb32 1483/// An interned string.
48663c56 1484///
e74abb32 1485/// Internally, a `Symbol` is implemented as an index, and all operations
48663c56 1486/// (including hashing, equality, and ordering) operate on that index. The use
e74abb32
XL
1487/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1488/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
0731742a 1489///
e74abb32 1490/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
dc9dc135 1491/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
476ff2be 1492#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
0731742a
XL
1493pub struct Symbol(SymbolIndex);
1494
e74abb32 1495rustc_index::newtype_index! {
0731742a
XL
1496 pub struct SymbolIndex { .. }
1497}
476ff2be 1498
476ff2be 1499impl Symbol {
0731742a 1500 const fn new(n: u32) -> Self {
ba9703b0 1501 Symbol(SymbolIndex::from_u32(n))
0731742a
XL
1502 }
1503
476ff2be
SL
1504 /// Maps a string to its interned representation.
1505 pub fn intern(string: &str) -> Self {
1506 with_interner(|interner| interner.intern(string))
1507 }
1508
60c5eb7d
XL
1509 /// Convert to a `SymbolStr`. This is a slowish operation because it
1510 /// requires locking the symbol interner.
1511 pub fn as_str(self) -> SymbolStr {
476ff2be 1512 with_interner(|interner| unsafe {
dfeec247 1513 SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
476ff2be
SL
1514 })
1515 }
1516
83c7162d 1517 pub fn as_u32(self) -> u32 {
0731742a 1518 self.0.as_u32()
ea8adc8c 1519 }
74b04a01 1520
fc512014 1521 pub fn is_empty(self) -> bool {
5869c6ff 1522 self == kw::Empty
fc512014
XL
1523 }
1524
74b04a01
XL
1525 /// This method is supposed to be used in error messages, so it's expected to be
1526 /// identical to printing the original identifier token written in source code
1527 /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1528 /// or edition, so we have to guess the rawness using the global edition.
1529 pub fn to_ident_string(self) -> String {
1530 Ident::with_dummy_span(self).to_string()
1531 }
ea8adc8c
XL
1532}
1533
476ff2be 1534impl fmt::Debug for Symbol {
9fa01778 1535 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5869c6ff 1536 fmt::Debug::fmt(&self.as_str(), f)
476ff2be
SL
1537 }
1538}
1539
1540impl fmt::Display for Symbol {
9fa01778 1541 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5869c6ff 1542 fmt::Display::fmt(&self.as_str(), f)
476ff2be
SL
1543 }
1544}
1545
3dfed10e
XL
1546impl<S: Encoder> Encodable<S> for Symbol {
1547 fn encode(&self, s: &mut S) -> Result<(), S::Error> {
5869c6ff 1548 s.emit_str(&self.as_str())
476ff2be
SL
1549 }
1550}
1551
3dfed10e 1552impl<D: Decoder> Decodable<D> for Symbol {
74b04a01 1553 #[inline]
3dfed10e 1554 fn decode(d: &mut D) -> Result<Symbol, D::Error> {
476ff2be
SL
1555 Ok(Symbol::intern(&d.read_str()?))
1556 }
1557}
1558
60c5eb7d
XL
1559impl<CTX> HashStable<CTX> for Symbol {
1560 #[inline]
1561 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1562 self.as_str().hash_stable(hcx, hasher);
1563 }
1564}
1565
1566impl<CTX> ToStableHashKey<CTX> for Symbol {
1567 type KeyType = SymbolStr;
1568
1569 #[inline]
1570 fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1571 self.as_str()
1572 }
1573}
1574
0731742a 1575// The `&'static str`s in this type actually point into the arena.
3dfed10e
XL
1576//
1577// The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1578// found that to regress performance up to 2% in some cases. This might be
1579// revisited after further improvements to `indexmap`.
0bf4aa26 1580#[derive(Default)]
476ff2be 1581pub struct Interner {
94b46f34
XL
1582 arena: DroplessArena,
1583 names: FxHashMap<&'static str, Symbol>,
1584 strings: Vec<&'static str>,
476ff2be
SL
1585}
1586
1587impl Interner {
dc9dc135
XL
1588 fn prefill(init: &[&'static str]) -> Self {
1589 Interner {
1590 strings: init.into(),
1591 names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1592 ..Default::default()
476ff2be 1593 }
476ff2be
SL
1594 }
1595
74b04a01 1596 #[inline]
476ff2be
SL
1597 pub fn intern(&mut self, string: &str) -> Symbol {
1598 if let Some(&name) = self.names.get(string) {
1599 return name;
1600 }
1601
0731742a 1602 let name = Symbol::new(self.strings.len() as u32);
94b46f34 1603
0731742a
XL
1604 // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1605 // UTF-8.
dfeec247
XL
1606 let string: &str =
1607 unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
0731742a
XL
1608 // It is safe to extend the arena allocation to `'static` because we only access
1609 // these while the arena is still alive.
dfeec247 1610 let string: &'static str = unsafe { &*(string as *const str) };
94b46f34 1611 self.strings.push(string);
476ff2be
SL
1612 self.names.insert(string, name);
1613 name
1614 }
60c5eb7d 1615
48663c56
XL
1616 // Get the symbol as a string. `Symbol::as_str()` should be used in
1617 // preference to this function.
7cac9316 1618 pub fn get(&self, symbol: Symbol) -> &str {
e74abb32 1619 self.strings[symbol.0.as_usize()]
476ff2be
SL
1620 }
1621}
1622
dc9dc135 1623// This module has a very short name because it's used a lot.
ba9703b0
XL
1624/// This module contains all the defined keyword `Symbol`s.
1625///
1626/// Given that `kw` is imported, use them like `kw::keyword_name`.
1627/// For example `kw::Loop` or `kw::Break`.
dc9dc135 1628pub mod kw {
fc512014 1629 pub use super::kw_generated::*;
48663c56
XL
1630}
1631
1632// This module has a very short name because it's used a lot.
ba9703b0
XL
1633/// This module contains all the defined non-keyword `Symbol`s.
1634///
1635/// Given that `sym` is imported, use them like `sym::symbol_name`.
1636/// For example `sym::rustfmt` or `sym::u8`.
48663c56
XL
1637pub mod sym {
1638 use super::Symbol;
dfeec247 1639 use std::convert::TryInto;
dc9dc135 1640
6a06907d 1641 #[doc(inline)]
fc512014 1642 pub use super::sym_generated::*;
74b04a01
XL
1643
1644 // Used from a macro in `librustc_feature/accepted.rs`
1645 pub use super::kw::MacroRules as macro_rules;
dc9dc135 1646
fc512014
XL
1647 /// Get the symbol for an integer.
1648 ///
1649 /// The first few non-negative integers each have a static symbol and therefore
1650 /// are fast.
dc9dc135
XL
1651 pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1652 if let Result::Ok(idx) = n.try_into() {
fc512014
XL
1653 if idx < 10 {
1654 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
dc9dc135
XL
1655 }
1656 }
1657 Symbol::intern(&n.to_string())
1658 }
94b46f34
XL
1659}
1660
1661impl Symbol {
fc512014
XL
1662 fn is_special(self) -> bool {
1663 self <= kw::Underscore
1664 }
1665
1666 fn is_used_keyword_always(self) -> bool {
1667 self >= kw::As && self <= kw::While
0731742a
XL
1668 }
1669
fc512014
XL
1670 fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1671 (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
dc9dc135
XL
1672 }
1673
fc512014
XL
1674 fn is_unused_keyword_always(self) -> bool {
1675 self >= kw::Abstract && self <= kw::Yield
1676 }
1677
1678 fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1679 self == kw::Try && edition() >= Edition::Edition2018
1680 }
1681
1682 pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1683 self.is_special()
1684 || self.is_used_keyword_always()
1685 || self.is_unused_keyword_always()
1686 || self.is_used_keyword_conditional(edition)
1687 || self.is_unused_keyword_conditional(edition)
dc9dc135
XL
1688 }
1689
1690 /// A keyword or reserved identifier that can be used as a path segment.
1691 pub fn is_path_segment_keyword(self) -> bool {
dfeec247
XL
1692 self == kw::Super
1693 || self == kw::SelfLower
1694 || self == kw::SelfUpper
1695 || self == kw::Crate
1696 || self == kw::PathRoot
1697 || self == kw::DollarCrate
dc9dc135
XL
1698 }
1699
e1599b0c
XL
1700 /// Returns `true` if the symbol is `true` or `false`.
1701 pub fn is_bool_lit(self) -> bool {
1702 self == kw::True || self == kw::False
1703 }
1704
fc512014 1705 /// Returns `true` if this symbol can be a raw identifier.
dc9dc135 1706 pub fn can_be_raw(self) -> bool {
5869c6ff 1707 self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
94b46f34
XL
1708 }
1709}
1710
1711impl Ident {
0731742a 1712 // Returns `true` for reserved identifiers used internally for elided lifetimes,
94b46f34
XL
1713 // unnamed method parameters, crate root module, error recovery etc.
1714 pub fn is_special(self) -> bool {
fc512014 1715 self.name.is_special()
94b46f34
XL
1716 }
1717
1718 /// Returns `true` if the token is a keyword used in the language.
1719 pub fn is_used_keyword(self) -> bool {
0731742a 1720 // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
fc512014
XL
1721 self.name.is_used_keyword_always()
1722 || self.name.is_used_keyword_conditional(|| self.span.edition())
94b46f34
XL
1723 }
1724
1725 /// Returns `true` if the token is a keyword reserved for possible future use.
1726 pub fn is_unused_keyword(self) -> bool {
1727 // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
fc512014
XL
1728 self.name.is_unused_keyword_always()
1729 || self.name.is_unused_keyword_conditional(|| self.span.edition())
94b46f34
XL
1730 }
1731
1732 /// Returns `true` if the token is either a special identifier or a keyword.
1733 pub fn is_reserved(self) -> bool {
fc512014
XL
1734 // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1735 self.name.is_reserved(|| self.span.edition())
94b46f34
XL
1736 }
1737
1738 /// A keyword or reserved identifier that can be used as a path segment.
1739 pub fn is_path_segment_keyword(self) -> bool {
dc9dc135 1740 self.name.is_path_segment_keyword()
532ac7d7
XL
1741 }
1742
1743 /// We see this identifier in a normal identifier position, like variable name or a type.
1744 /// How was it written originally? Did it use the raw form? Let's try to guess.
1745 pub fn is_raw_guess(self) -> bool {
dc9dc135 1746 self.name.can_be_raw() && self.is_reserved()
94b46f34 1747 }
476ff2be
SL
1748}
1749
0531ce1d 1750#[inline]
476ff2be 1751fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
f035d41b 1752 SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
476ff2be
SL
1753}
1754
fc512014 1755/// An alternative to [`Symbol`], useful when the chars within the symbol need to
e74abb32
XL
1756/// be accessed. It deliberately has limited functionality and should only be
1757/// used for temporary values.
48663c56
XL
1758///
1759/// Because the interner outlives any thread which uses this type, we can
1760/// safely treat `string` which points to interner data, as an immortal string,
1761/// as long as this type never crosses between threads.
1762//
60c5eb7d
XL
1763// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1764// by creating a new thread right after constructing the interner.
e74abb32 1765#[derive(Clone, Eq, PartialOrd, Ord)]
60c5eb7d 1766pub struct SymbolStr {
476ff2be
SL
1767 string: &'static str,
1768}
1769
60c5eb7d
XL
1770// This impl allows a `SymbolStr` to be directly equated with a `String` or
1771// `&str`.
1772impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
cc61c64b
XL
1773 fn eq(&self, other: &T) -> bool {
1774 self.string == other.deref()
1775 }
1776}
1777
60c5eb7d
XL
1778impl !Send for SymbolStr {}
1779impl !Sync for SymbolStr {}
476ff2be 1780
60c5eb7d
XL
1781/// This impl means that if `ss` is a `SymbolStr`:
1782/// - `*ss` is a `str`;
3dfed10e 1783/// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
60c5eb7d
XL
1784/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1785/// function expecting a `&str`.
1786impl std::ops::Deref for SymbolStr {
476ff2be 1787 type Target = str;
dc9dc135 1788 #[inline]
dfeec247
XL
1789 fn deref(&self) -> &str {
1790 self.string
1791 }
476ff2be
SL
1792}
1793
60c5eb7d 1794impl fmt::Debug for SymbolStr {
9fa01778 1795 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
476ff2be
SL
1796 fmt::Debug::fmt(self.string, f)
1797 }
1798}
1799
60c5eb7d 1800impl fmt::Display for SymbolStr {
9fa01778 1801 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
476ff2be
SL
1802 fmt::Display::fmt(self.string, f)
1803 }
1804}
60c5eb7d
XL
1805
1806impl<CTX> HashStable<CTX> for SymbolStr {
1807 #[inline]
1808 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1809 self.string.hash_stable(hcx, hasher)
1810 }
1811}
1812
1813impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1814 type KeyType = SymbolStr;
1815
1816 #[inline]
1817 fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1818 self.clone()
1819 }
1820}