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