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