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