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