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