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