]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Remove unused diagnostic items
[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_data_structures::sync::Lock;
9 use rustc_macros::HashStable_Generic;
10 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
11
12 use std::cmp::{Ord, PartialEq, PartialOrd};
13 use std::fmt;
14 use std::hash::{Hash, Hasher};
15 use std::str;
16
17 use crate::{with_session_globals, Edition, Span, DUMMY_SP};
18
19 #[cfg(test)]
20 mod tests;
21
22 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
23 symbols! {
24     // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
25     // this should be rarely necessary though if the keywords are kept in alphabetic order.
26     Keywords {
27         // Special reserved identifiers used internally for elided lifetimes,
28         // unnamed method parameters, crate root module, error recovery etc.
29         Empty:              "",
30         PathRoot:           "{{root}}",
31         DollarCrate:        "$crate",
32         Underscore:         "_",
33
34         // Keywords that are used in stable Rust.
35         As:                 "as",
36         Break:              "break",
37         Const:              "const",
38         Continue:           "continue",
39         Crate:              "crate",
40         Else:               "else",
41         Enum:               "enum",
42         Extern:             "extern",
43         False:              "false",
44         Fn:                 "fn",
45         For:                "for",
46         If:                 "if",
47         Impl:               "impl",
48         In:                 "in",
49         Let:                "let",
50         Loop:               "loop",
51         Match:              "match",
52         Mod:                "mod",
53         Move:               "move",
54         Mut:                "mut",
55         Pub:                "pub",
56         Ref:                "ref",
57         Return:             "return",
58         SelfLower:          "self",
59         SelfUpper:          "Self",
60         Static:             "static",
61         Struct:             "struct",
62         Super:              "super",
63         Trait:              "trait",
64         True:               "true",
65         Type:               "type",
66         Unsafe:             "unsafe",
67         Use:                "use",
68         Where:              "where",
69         While:              "while",
70
71         // Keywords that are used in unstable Rust or reserved for future use.
72         Abstract:           "abstract",
73         Become:             "become",
74         Box:                "box",
75         Do:                 "do",
76         Final:              "final",
77         Macro:              "macro",
78         Override:           "override",
79         Priv:               "priv",
80         Typeof:             "typeof",
81         Unsized:            "unsized",
82         Virtual:            "virtual",
83         Yield:              "yield",
84
85         // Edition-specific keywords that are used in stable Rust.
86         Async:              "async", // >= 2018 Edition only
87         Await:              "await", // >= 2018 Edition only
88         Dyn:                "dyn", // >= 2018 Edition only
89
90         // Edition-specific keywords that are used in unstable Rust or reserved for future use.
91         Try:                "try", // >= 2018 Edition only
92
93         // Special lifetime names
94         UnderscoreLifetime: "'_",
95         StaticLifetime:     "'static",
96
97         // Weak keywords, have special meaning only in specific contexts.
98         Auto:               "auto",
99         Catch:              "catch",
100         Default:            "default",
101         MacroRules:         "macro_rules",
102         Raw:                "raw",
103         Union:              "union",
104         Yeet:               "yeet",
105     }
106
107     // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
108     //
109     // The symbol is the stringified identifier unless otherwise specified, in
110     // which case the name should mention the non-identifier punctuation.
111     // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
112     // called `sym::proc_macro` because then it's easy to mistakenly think it
113     // represents "proc_macro".
114     //
115     // As well as the symbols listed, there are symbols for the strings
116     // "0", "1", ..., "9", which are accessible via `sym::integer`.
117     //
118     // The proc macro will abort if symbols are not in alphabetical order (as
119     // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
120     // users can sort the list by selecting it and executing the command
121     // `:'<,'>!LC_ALL=C sort`.
122     //
123     // There is currently no checking that all symbols are used; that would be
124     // nice to have.
125     Symbols {
126         AcqRel,
127         Acquire,
128         AddToDiagnostic,
129         Alignment,
130         Any,
131         Arc,
132         Argument,
133         ArgumentV1,
134         ArgumentV1Methods,
135         Arguments,
136         AsMut,
137         AsRef,
138         AssertParamIsClone,
139         AssertParamIsCopy,
140         AssertParamIsEq,
141         AtomicBool,
142         AtomicI128,
143         AtomicI16,
144         AtomicI32,
145         AtomicI64,
146         AtomicI8,
147         AtomicIsize,
148         AtomicPtr,
149         AtomicU128,
150         AtomicU16,
151         AtomicU32,
152         AtomicU64,
153         AtomicU8,
154         AtomicUsize,
155         BTreeEntry,
156         BTreeMap,
157         BTreeSet,
158         BinaryHeap,
159         Borrow,
160         BorrowMut,
161         Break,
162         C,
163         CStr,
164         CString,
165         Capture,
166         Center,
167         Clone,
168         Continue,
169         Copy,
170         Count,
171         Cow,
172         Debug,
173         DebugStruct,
174         DebugTuple,
175         Decodable,
176         Decoder,
177         DecorateLint,
178         Default,
179         Deref,
180         DiagnosticMessage,
181         DirBuilder,
182         Display,
183         DoubleEndedIterator,
184         Duration,
185         Encodable,
186         Encoder,
187         Eq,
188         Equal,
189         Err,
190         Error,
191         File,
192         FileType,
193         FormatSpec,
194         Formatter,
195         From,
196         FromIterator,
197         FromResidual,
198         Future,
199         FxHashMap,
200         FxHashSet,
201         GlobalAlloc,
202         Hash,
203         HashMap,
204         HashMapEntry,
205         HashSet,
206         Hasher,
207         Implied,
208         Input,
209         Into,
210         IntoDiagnostic,
211         IntoFuture,
212         IntoIterator,
213         IoRead,
214         IoWrite,
215         IpAddr,
216         IrTyKind,
217         Is,
218         ItemContext,
219         Iterator,
220         Layout,
221         Left,
222         LinkedList,
223         LintPass,
224         LocalKey,
225         Mutex,
226         MutexGuard,
227         N,
228         NonZeroI128,
229         NonZeroI16,
230         NonZeroI32,
231         NonZeroI64,
232         NonZeroI8,
233         NonZeroU128,
234         NonZeroU16,
235         NonZeroU32,
236         NonZeroU64,
237         NonZeroU8,
238         None,
239         Ok,
240         Option,
241         Ord,
242         Ordering,
243         OsStr,
244         OsString,
245         Output,
246         Param,
247         PartialEq,
248         PartialOrd,
249         Path,
250         PathBuf,
251         Pending,
252         Pin,
253         Pointer,
254         Poll,
255         ProcMacro,
256         ProcMacroHack,
257         ProceduralMasqueradeDummyType,
258         Range,
259         RangeFrom,
260         RangeFull,
261         RangeInclusive,
262         RangeTo,
263         RangeToInclusive,
264         Rc,
265         Ready,
266         Receiver,
267         RefCell,
268         Relaxed,
269         Release,
270         Result,
271         Return,
272         Right,
273         Rust,
274         RustcDecodable,
275         RustcEncodable,
276         RwLock,
277         RwLockReadGuard,
278         RwLockWriteGuard,
279         Send,
280         SeqCst,
281         SliceIndex,
282         Some,
283         String,
284         StructuralEq,
285         StructuralPartialEq,
286         SubdiagnosticMessage,
287         Sync,
288         T,
289         Target,
290         ToOwned,
291         ToString,
292         Try,
293         TryCaptureGeneric,
294         TryCapturePrintable,
295         TryFrom,
296         TryInto,
297         Ty,
298         TyCtxt,
299         TyKind,
300         Unknown,
301         UnsafeArg,
302         Vec,
303         VecDeque,
304         Wrapper,
305         Yield,
306         _DECLS,
307         _Self,
308         __D,
309         __H,
310         __S,
311         __awaitee,
312         __try_var,
313         _d,
314         _e,
315         _task_context,
316         a32,
317         aarch64_target_feature,
318         aarch64_ver_target_feature,
319         abi,
320         abi_amdgpu_kernel,
321         abi_avr_interrupt,
322         abi_c_cmse_nonsecure_call,
323         abi_efiapi,
324         abi_msp430_interrupt,
325         abi_ptx,
326         abi_sysv64,
327         abi_thiscall,
328         abi_unadjusted,
329         abi_vectorcall,
330         abi_x86_interrupt,
331         abort,
332         aborts,
333         add,
334         add_assign,
335         add_with_overflow,
336         address,
337         adt_const_params,
338         advanced_slice_patterns,
339         adx_target_feature,
340         alias,
341         align,
342         align_offset,
343         alignment,
344         alignstack,
345         all,
346         alloc,
347         alloc_error_handler,
348         alloc_layout,
349         alloc_zeroed,
350         allocator,
351         allocator_api,
352         allocator_internals,
353         allow,
354         allow_fail,
355         allow_internal_unsafe,
356         allow_internal_unstable,
357         allowed,
358         alu32,
359         always,
360         and,
361         and_then,
362         anonymous_lifetime_in_impl_trait,
363         any,
364         append_const_msg,
365         arbitrary_enum_discriminant,
366         arbitrary_self_types,
367         args,
368         arith_offset,
369         arm,
370         arm_target_feature,
371         array,
372         arrays,
373         as_ptr,
374         as_ref,
375         as_str,
376         asm,
377         asm_const,
378         asm_experimental_arch,
379         asm_sym,
380         asm_unwind,
381         assert,
382         assert_eq_macro,
383         assert_inhabited,
384         assert_macro,
385         assert_ne_macro,
386         assert_receiver_is_total_eq,
387         assert_uninit_valid,
388         assert_zero_valid,
389         asserting,
390         associated_const_equality,
391         associated_consts,
392         associated_type_bounds,
393         associated_type_defaults,
394         associated_types,
395         assume,
396         assume_init,
397         async_await,
398         async_closure,
399         async_fn_in_trait,
400         atomic,
401         atomic_mod,
402         atomics,
403         att_syntax,
404         attr,
405         attr_literals,
406         attributes,
407         augmented_assignments,
408         auto_traits,
409         automatically_derived,
410         avx,
411         avx512_target_feature,
412         avx512bw,
413         avx512f,
414         await_macro,
415         bang,
416         begin_panic,
417         bench,
418         bin,
419         bind_by_move_pattern_guards,
420         bindings_after_at,
421         bitand,
422         bitand_assign,
423         bitor,
424         bitor_assign,
425         bitreverse,
426         bitxor,
427         bitxor_assign,
428         black_box,
429         block,
430         bool,
431         borrowck_graphviz_format,
432         borrowck_graphviz_postflow,
433         borrowck_graphviz_preflow,
434         box_free,
435         box_patterns,
436         box_syntax,
437         bpf_target_feature,
438         braced_empty_structs,
439         branch,
440         breakpoint,
441         bridge,
442         bswap,
443         c_str,
444         c_unwind,
445         c_variadic,
446         call,
447         call_mut,
448         call_once,
449         caller_location,
450         capture_disjoint_fields,
451         cause,
452         cdylib,
453         ceilf32,
454         ceilf64,
455         cfg,
456         cfg_accessible,
457         cfg_attr,
458         cfg_attr_multi,
459         cfg_doctest,
460         cfg_eval,
461         cfg_hide,
462         cfg_panic,
463         cfg_sanitize,
464         cfg_target_abi,
465         cfg_target_compact,
466         cfg_target_feature,
467         cfg_target_has_atomic,
468         cfg_target_has_atomic_equal_alignment,
469         cfg_target_has_atomic_load_store,
470         cfg_target_thread_local,
471         cfg_target_vendor,
472         cfg_version,
473         cfi,
474         char,
475         client,
476         clippy,
477         clobber_abi,
478         clone,
479         clone_closures,
480         clone_from,
481         closure,
482         closure_lifetime_binder,
483         closure_to_fn_coercion,
484         closure_track_caller,
485         cmp,
486         cmp_max,
487         cmp_min,
488         cmpxchg16b_target_feature,
489         cmse_nonsecure_entry,
490         coerce_unsized,
491         cold,
492         collapse_debuginfo,
493         column,
494         compare_and_swap,
495         compare_exchange,
496         compare_exchange_weak,
497         compile_error,
498         compiler,
499         compiler_builtins,
500         compiler_fence,
501         concat,
502         concat_bytes,
503         concat_idents,
504         conservative_impl_trait,
505         console,
506         const_allocate,
507         const_async_blocks,
508         const_compare_raw_pointers,
509         const_constructor,
510         const_deallocate,
511         const_eval_limit,
512         const_eval_select,
513         const_evaluatable_checked,
514         const_extern_fn,
515         const_fn,
516         const_fn_floating_point_arithmetic,
517         const_fn_fn_ptr_basics,
518         const_fn_trait_bound,
519         const_fn_transmute,
520         const_fn_union,
521         const_fn_unsize,
522         const_for,
523         const_format_args,
524         const_generic_defaults,
525         const_generics,
526         const_generics_defaults,
527         const_if_match,
528         const_impl_trait,
529         const_in_array_repeat_expressions,
530         const_indexing,
531         const_let,
532         const_loop,
533         const_mut_refs,
534         const_panic,
535         const_panic_fmt,
536         const_precise_live_drops,
537         const_raw_ptr_deref,
538         const_raw_ptr_to_usize_cast,
539         const_refs_to_cell,
540         const_trait,
541         const_trait_bound_opt_out,
542         const_trait_impl,
543         const_transmute,
544         const_try,
545         constant,
546         constructor,
547         contents,
548         context,
549         convert,
550         copy,
551         copy_closures,
552         copy_nonoverlapping,
553         copysignf32,
554         copysignf64,
555         core,
556         core_intrinsics,
557         core_panic,
558         core_panic_2015_macro,
559         core_panic_macro,
560         cosf32,
561         cosf64,
562         count,
563         cr,
564         crate_id,
565         crate_in_paths,
566         crate_local,
567         crate_name,
568         crate_type,
569         crate_visibility_modifier,
570         crt_dash_static: "crt-static",
571         cstring_type,
572         ctlz,
573         ctlz_nonzero,
574         ctpop,
575         cttz,
576         cttz_nonzero,
577         custom_attribute,
578         custom_derive,
579         custom_inner_attributes,
580         custom_mir,
581         custom_test_frameworks,
582         d,
583         d32,
584         dbg_macro,
585         dead_code,
586         dealloc,
587         debug,
588         debug_assert_eq_macro,
589         debug_assert_macro,
590         debug_assert_ne_macro,
591         debug_assertions,
592         debug_struct,
593         debug_struct_fields_finish,
594         debug_trait_builder,
595         debug_tuple,
596         debug_tuple_fields_finish,
597         debugger_visualizer,
598         decl_macro,
599         declare_lint_pass,
600         decode,
601         default_alloc_error_handler,
602         default_lib_allocator,
603         default_method_body_is_const,
604         default_type_parameter_fallback,
605         default_type_params,
606         delay_span_bug_from_inside_query,
607         deny,
608         deprecated,
609         deprecated_safe,
610         deprecated_suggestion,
611         deref,
612         deref_method,
613         deref_mut,
614         deref_target,
615         derive,
616         derive_const,
617         derive_default_enum,
618         destruct,
619         destructuring_assignment,
620         diagnostic,
621         direct,
622         discriminant_kind,
623         discriminant_type,
624         discriminant_value,
625         dispatch_from_dyn,
626         display_trait,
627         div,
628         div_assign,
629         doc,
630         doc_alias,
631         doc_auto_cfg,
632         doc_cfg,
633         doc_cfg_hide,
634         doc_keyword,
635         doc_masked,
636         doc_notable_trait,
637         doc_primitive,
638         doc_spotlight,
639         doctest,
640         document_private_items,
641         dotdot: "..",
642         dotdot_in_tuple_patterns,
643         dotdoteq_in_patterns,
644         dreg,
645         dreg_low16,
646         dreg_low8,
647         drop,
648         drop_in_place,
649         drop_types_in_const,
650         dropck_eyepatch,
651         dropck_parametricity,
652         dylib,
653         dyn_metadata,
654         dyn_star,
655         dyn_trait,
656         e,
657         edition_macro_pats,
658         edition_panic,
659         eh_catch_typeinfo,
660         eh_personality,
661         emit_enum,
662         emit_enum_variant,
663         emit_enum_variant_arg,
664         emit_struct,
665         emit_struct_field,
666         enable,
667         encode,
668         end,
669         env,
670         env_macro,
671         eprint_macro,
672         eprintln_macro,
673         eq,
674         ermsb_target_feature,
675         exact_div,
676         except,
677         exchange_malloc,
678         exclusive_range_pattern,
679         exhaustive_integer_patterns,
680         exhaustive_patterns,
681         existential_type,
682         exp2f32,
683         exp2f64,
684         expect,
685         expected,
686         expf32,
687         expf64,
688         explicit_generic_args_with_impl_trait,
689         export_name,
690         expr,
691         extended_key_value_attributes,
692         extended_varargs_abi_support,
693         extern_absolute_paths,
694         extern_crate_item_prelude,
695         extern_crate_self,
696         extern_in_paths,
697         extern_prelude,
698         extern_types,
699         external_doc,
700         f,
701         f16c_target_feature,
702         f32,
703         f64,
704         fabsf32,
705         fabsf64,
706         fadd_fast,
707         fake_variadic,
708         fdiv_fast,
709         feature,
710         fence,
711         ferris: "🦀",
712         fetch_update,
713         ffi,
714         ffi_const,
715         ffi_pure,
716         ffi_returns_twice,
717         field,
718         field_init_shorthand,
719         file,
720         fill,
721         finish,
722         flags,
723         float,
724         float_to_int_unchecked,
725         floorf32,
726         floorf64,
727         fmaf32,
728         fmaf64,
729         fmt,
730         fmt_as_str,
731         fmt_internals,
732         fmul_fast,
733         fn_align,
734         fn_must_use,
735         fn_mut,
736         fn_once,
737         fn_once_output,
738         forbid,
739         forget,
740         format,
741         format_args,
742         format_args_capture,
743         format_args_macro,
744         format_args_nl,
745         format_macro,
746         fp,
747         freeze,
748         freg,
749         frem_fast,
750         from,
751         from_desugaring,
752         from_generator,
753         from_iter,
754         from_method,
755         from_output,
756         from_residual,
757         from_size_align_unchecked,
758         from_usize,
759         from_yeet,
760         fsub_fast,
761         fundamental,
762         future,
763         future_trait,
764         gdb_script_file,
765         ge,
766         gen_future,
767         gen_kill,
768         generator,
769         generator_clone,
770         generator_state,
771         generators,
772         generic_arg_infer,
773         generic_assert,
774         generic_associated_types,
775         generic_associated_types_extended,
776         generic_const_exprs,
777         generic_param_attrs,
778         get_context,
779         global_allocator,
780         global_asm,
781         globs,
782         gt,
783         half_open_range_patterns,
784         half_open_range_patterns_in_slices,
785         hash,
786         hexagon_target_feature,
787         hidden,
788         homogeneous_aggregate,
789         html_favicon_url,
790         html_logo_url,
791         html_no_source,
792         html_playground_url,
793         html_root_url,
794         hwaddress,
795         i,
796         i128,
797         i128_type,
798         i16,
799         i32,
800         i64,
801         i8,
802         ident,
803         if_let,
804         if_let_guard,
805         if_while_or_patterns,
806         ignore,
807         impl_header_lifetime_elision,
808         impl_lint_pass,
809         impl_macros,
810         impl_trait_in_bindings,
811         impl_trait_in_fn_trait_return,
812         implied_by,
813         import,
814         import_name_type,
815         import_shadowing,
816         imported_main,
817         in_band_lifetimes,
818         include,
819         include_bytes,
820         include_bytes_macro,
821         include_str,
822         include_str_macro,
823         inclusive_range_syntax,
824         index,
825         index_mut,
826         infer_outlives_requirements,
827         infer_static_outlives_requirements,
828         inherent_associated_types,
829         inherit,
830         inlateout,
831         inline,
832         inline_const,
833         inline_const_pat,
834         inout,
835         instruction_set,
836         integer_: "integer",
837         integral,
838         intel,
839         into_future,
840         into_iter,
841         intra_doc_pointers,
842         intrinsics,
843         irrefutable_let_patterns,
844         isa_attribute,
845         isize,
846         issue,
847         issue_5723_bootstrap,
848         issue_tracker_base_url,
849         item,
850         item_like_imports,
851         iter,
852         iter_repeat,
853         keyword,
854         kind,
855         kreg,
856         kreg0,
857         label,
858         label_break_value,
859         lang,
860         lang_items,
861         large_assignments,
862         lateout,
863         lazy_normalization_consts,
864         le,
865         len,
866         let_chains,
867         let_else,
868         lhs,
869         lib,
870         libc,
871         lifetime,
872         lifetimes,
873         likely,
874         line,
875         link,
876         link_args,
877         link_cfg,
878         link_llvm_intrinsics,
879         link_name,
880         link_ordinal,
881         link_section,
882         linkage,
883         linker,
884         lint_reasons,
885         literal,
886         load,
887         loaded_from_disk,
888         local,
889         local_inner_macros,
890         log10f32,
891         log10f64,
892         log2f32,
893         log2f64,
894         log_syntax,
895         logf32,
896         logf64,
897         loop_break_value,
898         lt,
899         macro_at_most_once_rep,
900         macro_attributes_in_derive_output,
901         macro_escape,
902         macro_export,
903         macro_lifetime_matcher,
904         macro_literal_matcher,
905         macro_metavar_expr,
906         macro_reexport,
907         macro_use,
908         macro_vis_matcher,
909         macros_in_extern,
910         main,
911         managed_boxes,
912         manually_drop,
913         map,
914         marker,
915         marker_trait_attr,
916         masked,
917         match_beginning_vert,
918         match_default_bindings,
919         maxnumf32,
920         maxnumf64,
921         may_dangle,
922         may_unwind,
923         maybe_uninit,
924         maybe_uninit_uninit,
925         maybe_uninit_zeroed,
926         mem_discriminant,
927         mem_drop,
928         mem_forget,
929         mem_replace,
930         mem_size_of,
931         mem_size_of_val,
932         mem_uninitialized,
933         mem_variant_count,
934         mem_zeroed,
935         member_constraints,
936         memory,
937         memtag,
938         message,
939         meta,
940         metadata_type,
941         min_align_of,
942         min_align_of_val,
943         min_const_fn,
944         min_const_generics,
945         min_const_unsafe_fn,
946         min_specialization,
947         min_type_alias_impl_trait,
948         minnumf32,
949         minnumf64,
950         mips_target_feature,
951         miri,
952         misc,
953         mmx_reg,
954         modifiers,
955         module,
956         module_path,
957         more_qualified_paths,
958         more_struct_aliases,
959         movbe_target_feature,
960         move_ref_pattern,
961         move_size_limit,
962         mul,
963         mul_assign,
964         mul_with_overflow,
965         must_not_suspend,
966         must_use,
967         naked,
968         naked_functions,
969         name,
970         names,
971         native_link_modifiers,
972         native_link_modifiers_as_needed,
973         native_link_modifiers_bundle,
974         native_link_modifiers_verbatim,
975         native_link_modifiers_whole_archive,
976         natvis_file,
977         ne,
978         nearbyintf32,
979         nearbyintf64,
980         needs_allocator,
981         needs_drop,
982         needs_panic_runtime,
983         neg,
984         negate_unsigned,
985         negative_impls,
986         neon,
987         never,
988         never_type,
989         never_type_fallback,
990         new,
991         new_binary,
992         new_debug,
993         new_display,
994         new_lower_exp,
995         new_lower_hex,
996         new_octal,
997         new_pointer,
998         new_unchecked,
999         new_upper_exp,
1000         new_upper_hex,
1001         new_v1,
1002         new_v1_formatted,
1003         next,
1004         nll,
1005         no,
1006         no_builtins,
1007         no_core,
1008         no_coverage,
1009         no_crate_inject,
1010         no_debug,
1011         no_default_passes,
1012         no_implicit_prelude,
1013         no_inline,
1014         no_link,
1015         no_main,
1016         no_mangle,
1017         no_sanitize,
1018         no_stack_check,
1019         no_start,
1020         no_std,
1021         nomem,
1022         non_ascii_idents,
1023         non_exhaustive,
1024         non_exhaustive_omitted_patterns_lint,
1025         non_modrs_mods,
1026         none_error,
1027         nontemporal_store,
1028         noop_method_borrow,
1029         noop_method_clone,
1030         noop_method_deref,
1031         noreturn,
1032         nostack,
1033         not,
1034         notable_trait,
1035         note,
1036         object_safe_for_dispatch,
1037         of,
1038         offset,
1039         omit_gdb_pretty_printer_section,
1040         on,
1041         on_unimplemented,
1042         oom,
1043         opaque,
1044         ops,
1045         opt_out_copy,
1046         optimize,
1047         optimize_attribute,
1048         optin_builtin_traits,
1049         option,
1050         option_env,
1051         option_env_macro,
1052         options,
1053         or,
1054         or_patterns,
1055         other,
1056         out,
1057         overlapping_marker_traits,
1058         owned_box,
1059         packed,
1060         panic,
1061         panic_2015,
1062         panic_2021,
1063         panic_abort,
1064         panic_bounds_check,
1065         panic_display,
1066         panic_fmt,
1067         panic_handler,
1068         panic_impl,
1069         panic_implementation,
1070         panic_info,
1071         panic_location,
1072         panic_no_unwind,
1073         panic_runtime,
1074         panic_str,
1075         panic_unwind,
1076         panicking,
1077         param_attrs,
1078         parent_label,
1079         partial_cmp,
1080         partial_ord,
1081         passes,
1082         pat,
1083         pat_param,
1084         path,
1085         pattern_parentheses,
1086         phantom_data,
1087         pin,
1088         platform_intrinsics,
1089         plugin,
1090         plugin_registrar,
1091         plugins,
1092         pointee_trait,
1093         pointer,
1094         poll,
1095         position,
1096         post_dash_lto: "post-lto",
1097         powerpc_target_feature,
1098         powf32,
1099         powf64,
1100         powif32,
1101         powif64,
1102         pre_dash_lto: "pre-lto",
1103         precise_pointer_size_matching,
1104         precision,
1105         pref_align_of,
1106         prefetch_read_data,
1107         prefetch_read_instruction,
1108         prefetch_write_data,
1109         prefetch_write_instruction,
1110         preg,
1111         prelude,
1112         prelude_import,
1113         preserves_flags,
1114         primitive,
1115         print_macro,
1116         println_macro,
1117         proc_dash_macro: "proc-macro",
1118         proc_macro,
1119         proc_macro_attribute,
1120         proc_macro_def_site,
1121         proc_macro_derive,
1122         proc_macro_expr,
1123         proc_macro_gen,
1124         proc_macro_hygiene,
1125         proc_macro_internals,
1126         proc_macro_mod,
1127         proc_macro_non_items,
1128         proc_macro_path_invoc,
1129         profiler_builtins,
1130         profiler_runtime,
1131         ptr,
1132         ptr_guaranteed_cmp,
1133         ptr_mask,
1134         ptr_null,
1135         ptr_null_mut,
1136         ptr_offset_from,
1137         ptr_offset_from_unsigned,
1138         pub_macro_rules,
1139         pub_restricted,
1140         public,
1141         pure,
1142         pushpop_unsafe,
1143         qreg,
1144         qreg_low4,
1145         qreg_low8,
1146         quad_precision_float,
1147         question_mark,
1148         quote,
1149         range_inclusive_new,
1150         raw_dylib,
1151         raw_eq,
1152         raw_identifiers,
1153         raw_ref_op,
1154         re_rebalance_coherence,
1155         read_enum,
1156         read_enum_variant,
1157         read_enum_variant_arg,
1158         read_struct,
1159         read_struct_field,
1160         readonly,
1161         realloc,
1162         reason,
1163         receiver,
1164         recursion_limit,
1165         reexport_test_harness_main,
1166         ref_unwind_safe_trait,
1167         reference,
1168         reflect,
1169         reg,
1170         reg16,
1171         reg32,
1172         reg64,
1173         reg_abcd,
1174         reg_byte,
1175         reg_iw,
1176         reg_nonzero,
1177         reg_pair,
1178         reg_ptr,
1179         reg_upper,
1180         register_attr,
1181         register_tool,
1182         relaxed_adts,
1183         relaxed_struct_unsize,
1184         rem,
1185         rem_assign,
1186         repr,
1187         repr128,
1188         repr_align,
1189         repr_align_enum,
1190         repr_packed,
1191         repr_simd,
1192         repr_transparent,
1193         require,
1194         residual,
1195         result,
1196         return_position_impl_trait_in_trait,
1197         rhs,
1198         rintf32,
1199         rintf64,
1200         riscv_target_feature,
1201         rlib,
1202         rotate_left,
1203         rotate_right,
1204         roundf32,
1205         roundf64,
1206         rt,
1207         rtm_target_feature,
1208         rust,
1209         rust_2015,
1210         rust_2015_preview,
1211         rust_2018,
1212         rust_2018_preview,
1213         rust_2021,
1214         rust_2021_preview,
1215         rust_2024,
1216         rust_2024_preview,
1217         rust_begin_unwind,
1218         rust_cold_cc,
1219         rust_eh_catch_typeinfo,
1220         rust_eh_personality,
1221         rust_eh_register_frames,
1222         rust_eh_unregister_frames,
1223         rust_oom,
1224         rustc,
1225         rustc_allocator,
1226         rustc_allocator_zeroed,
1227         rustc_allow_const_fn_unstable,
1228         rustc_allow_incoherent_impl,
1229         rustc_allowed_through_unstable_modules,
1230         rustc_attrs,
1231         rustc_box,
1232         rustc_builtin_macro,
1233         rustc_capture_analysis,
1234         rustc_clean,
1235         rustc_coherence_is_core,
1236         rustc_const_stable,
1237         rustc_const_unstable,
1238         rustc_conversion_suggestion,
1239         rustc_deallocator,
1240         rustc_def_path,
1241         rustc_default_body_unstable,
1242         rustc_diagnostic_item,
1243         rustc_diagnostic_macros,
1244         rustc_dirty,
1245         rustc_do_not_const_check,
1246         rustc_dummy,
1247         rustc_dump_env_program_clauses,
1248         rustc_dump_program_clauses,
1249         rustc_dump_user_substs,
1250         rustc_dump_vtable,
1251         rustc_effective_visibility,
1252         rustc_error,
1253         rustc_evaluate_where_clauses,
1254         rustc_expected_cgu_reuse,
1255         rustc_has_incoherent_inherent_impls,
1256         rustc_if_this_changed,
1257         rustc_inherit_overflow_checks,
1258         rustc_insignificant_dtor,
1259         rustc_layout,
1260         rustc_layout_scalar_valid_range_end,
1261         rustc_layout_scalar_valid_range_start,
1262         rustc_legacy_const_generics,
1263         rustc_lint_diagnostics,
1264         rustc_lint_opt_deny_field_access,
1265         rustc_lint_opt_ty,
1266         rustc_lint_query_instability,
1267         rustc_macro_transparency,
1268         rustc_main,
1269         rustc_mir,
1270         rustc_must_implement_one_of,
1271         rustc_nonnull_optimization_guaranteed,
1272         rustc_nounwind,
1273         rustc_object_lifetime_default,
1274         rustc_on_unimplemented,
1275         rustc_outlives,
1276         rustc_paren_sugar,
1277         rustc_partition_codegened,
1278         rustc_partition_reused,
1279         rustc_pass_by_value,
1280         rustc_peek,
1281         rustc_peek_definite_init,
1282         rustc_peek_liveness,
1283         rustc_peek_maybe_init,
1284         rustc_peek_maybe_uninit,
1285         rustc_polymorphize_error,
1286         rustc_private,
1287         rustc_proc_macro_decls,
1288         rustc_promotable,
1289         rustc_reallocator,
1290         rustc_regions,
1291         rustc_reservation_impl,
1292         rustc_safe_intrinsic,
1293         rustc_serialize,
1294         rustc_skip_array_during_method_dispatch,
1295         rustc_specialization_trait,
1296         rustc_stable,
1297         rustc_std_internal_symbol,
1298         rustc_strict_coherence,
1299         rustc_symbol_name,
1300         rustc_test_marker,
1301         rustc_then_this_would_need,
1302         rustc_trivial_field_reads,
1303         rustc_unsafe_specialization_marker,
1304         rustc_variance,
1305         rustdoc,
1306         rustdoc_internals,
1307         rustdoc_missing_doc_code_examples,
1308         rustfmt,
1309         rvalue_static_promotion,
1310         s,
1311         safety,
1312         sanitize,
1313         sanitizer_runtime,
1314         saturating_add,
1315         saturating_sub,
1316         self_in_typedefs,
1317         self_struct_ctor,
1318         semitransparent,
1319         shadow_call_stack,
1320         shl,
1321         shl_assign,
1322         should_panic,
1323         shr,
1324         shr_assign,
1325         sig_dfl,
1326         sig_ign,
1327         simd,
1328         simd_add,
1329         simd_and,
1330         simd_arith_offset,
1331         simd_as,
1332         simd_bitmask,
1333         simd_cast,
1334         simd_cast_ptr,
1335         simd_ceil,
1336         simd_div,
1337         simd_eq,
1338         simd_expose_addr,
1339         simd_extract,
1340         simd_fabs,
1341         simd_fcos,
1342         simd_fexp,
1343         simd_fexp2,
1344         simd_ffi,
1345         simd_flog,
1346         simd_flog10,
1347         simd_flog2,
1348         simd_floor,
1349         simd_fma,
1350         simd_fmax,
1351         simd_fmin,
1352         simd_fpow,
1353         simd_fpowi,
1354         simd_from_exposed_addr,
1355         simd_fsin,
1356         simd_fsqrt,
1357         simd_gather,
1358         simd_ge,
1359         simd_gt,
1360         simd_insert,
1361         simd_le,
1362         simd_lt,
1363         simd_mul,
1364         simd_ne,
1365         simd_neg,
1366         simd_or,
1367         simd_reduce_add_ordered,
1368         simd_reduce_add_unordered,
1369         simd_reduce_all,
1370         simd_reduce_and,
1371         simd_reduce_any,
1372         simd_reduce_max,
1373         simd_reduce_max_nanless,
1374         simd_reduce_min,
1375         simd_reduce_min_nanless,
1376         simd_reduce_mul_ordered,
1377         simd_reduce_mul_unordered,
1378         simd_reduce_or,
1379         simd_reduce_xor,
1380         simd_rem,
1381         simd_round,
1382         simd_saturating_add,
1383         simd_saturating_sub,
1384         simd_scatter,
1385         simd_select,
1386         simd_select_bitmask,
1387         simd_shl,
1388         simd_shr,
1389         simd_shuffle,
1390         simd_sub,
1391         simd_trunc,
1392         simd_xor,
1393         since,
1394         sinf32,
1395         sinf64,
1396         size,
1397         size_of,
1398         size_of_val,
1399         sized,
1400         skip,
1401         slice,
1402         slice_len_fn,
1403         slice_patterns,
1404         slicing_syntax,
1405         soft,
1406         specialization,
1407         speed,
1408         spotlight,
1409         sqrtf32,
1410         sqrtf64,
1411         sreg,
1412         sreg_low16,
1413         sse,
1414         sse4a_target_feature,
1415         stable,
1416         staged_api,
1417         start,
1418         state,
1419         static_in_const,
1420         static_nobundle,
1421         static_recursion,
1422         staticlib,
1423         std,
1424         std_inject,
1425         std_panic,
1426         std_panic_2015_macro,
1427         std_panic_macro,
1428         stmt,
1429         stmt_expr_attributes,
1430         stop_after_dataflow,
1431         store,
1432         str,
1433         str_split_whitespace,
1434         str_trim,
1435         str_trim_end,
1436         str_trim_start,
1437         strict_provenance,
1438         stringify,
1439         struct_field_attributes,
1440         struct_inherit,
1441         struct_variant,
1442         structural_match,
1443         structural_peq,
1444         structural_teq,
1445         sty,
1446         sub,
1447         sub_assign,
1448         sub_with_overflow,
1449         suggestion,
1450         sym,
1451         sync,
1452         t32,
1453         target,
1454         target_abi,
1455         target_arch,
1456         target_endian,
1457         target_env,
1458         target_family,
1459         target_feature,
1460         target_feature_11,
1461         target_has_atomic,
1462         target_has_atomic_equal_alignment,
1463         target_has_atomic_load_store,
1464         target_os,
1465         target_pointer_width,
1466         target_target_vendor,
1467         target_thread_local,
1468         target_vendor,
1469         task,
1470         tbm_target_feature,
1471         termination,
1472         termination_trait,
1473         termination_trait_test,
1474         test,
1475         test_2018_feature,
1476         test_accepted_feature,
1477         test_case,
1478         test_removed_feature,
1479         test_runner,
1480         test_unstable_lint,
1481         then_with,
1482         thread,
1483         thread_local,
1484         thread_local_macro,
1485         thumb2,
1486         thumb_mode: "thumb-mode",
1487         tmm_reg,
1488         to_string,
1489         to_vec,
1490         todo_macro,
1491         tool_attributes,
1492         tool_lints,
1493         trace_macros,
1494         track_caller,
1495         trait_alias,
1496         trait_upcasting,
1497         transmute,
1498         transmute_opts,
1499         transmute_trait,
1500         transparent,
1501         transparent_enums,
1502         transparent_unions,
1503         trivial_bounds,
1504         truncf32,
1505         truncf64,
1506         try_blocks,
1507         try_capture,
1508         try_from,
1509         try_into,
1510         try_trait_v2,
1511         tt,
1512         tuple,
1513         tuple_from_req,
1514         tuple_indexing,
1515         tuple_trait,
1516         two_phase,
1517         ty,
1518         type_alias_enum_variants,
1519         type_alias_impl_trait,
1520         type_ascription,
1521         type_changing_struct_update,
1522         type_id,
1523         type_length_limit,
1524         type_macros,
1525         type_name,
1526         u128,
1527         u16,
1528         u32,
1529         u64,
1530         u8,
1531         unaligned_volatile_load,
1532         unaligned_volatile_store,
1533         unboxed_closures,
1534         unchecked_add,
1535         unchecked_div,
1536         unchecked_mul,
1537         unchecked_rem,
1538         unchecked_shl,
1539         unchecked_shr,
1540         unchecked_sub,
1541         underscore_const_names,
1542         underscore_imports,
1543         underscore_lifetimes,
1544         uniform_paths,
1545         unimplemented_macro,
1546         unit,
1547         universal_impl_trait,
1548         unix,
1549         unix_sigpipe,
1550         unlikely,
1551         unmarked_api,
1552         unpin,
1553         unreachable,
1554         unreachable_2015,
1555         unreachable_2015_macro,
1556         unreachable_2021,
1557         unreachable_code,
1558         unreachable_display,
1559         unreachable_macro,
1560         unrestricted_attribute_tokens,
1561         unsafe_block_in_unsafe_fn,
1562         unsafe_cell,
1563         unsafe_no_drop_flag,
1564         unsafe_pin_internals,
1565         unsize,
1566         unsized_fn_params,
1567         unsized_locals,
1568         unsized_tuple_coercion,
1569         unstable,
1570         unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
1571                           unstable location; did you mean to load this crate \
1572                           from crates.io via `Cargo.toml` instead?",
1573         untagged_unions,
1574         unused_imports,
1575         unused_qualifications,
1576         unwind,
1577         unwind_attributes,
1578         unwind_safe_trait,
1579         unwrap,
1580         unwrap_or,
1581         use_extern_macros,
1582         use_nested_groups,
1583         used,
1584         used_with_arg,
1585         using,
1586         usize,
1587         v1,
1588         va_arg,
1589         va_copy,
1590         va_end,
1591         va_list,
1592         va_start,
1593         val,
1594         validity,
1595         values,
1596         var,
1597         variant_count,
1598         vec,
1599         vec_macro,
1600         version,
1601         vfp2,
1602         vis,
1603         visible_private_types,
1604         volatile,
1605         volatile_copy_memory,
1606         volatile_copy_nonoverlapping_memory,
1607         volatile_load,
1608         volatile_set_memory,
1609         volatile_store,
1610         vreg,
1611         vreg_low16,
1612         vtable_align,
1613         vtable_size,
1614         warn,
1615         wasm_abi,
1616         wasm_import_module,
1617         wasm_target_feature,
1618         while_let,
1619         width,
1620         windows,
1621         windows_subsystem,
1622         with_negative_coherence,
1623         wrapping_add,
1624         wrapping_mul,
1625         wrapping_sub,
1626         wreg,
1627         write_bytes,
1628         write_macro,
1629         write_str,
1630         writeln_macro,
1631         x87_reg,
1632         xer,
1633         xmm_reg,
1634         yeet_desugar_details,
1635         yeet_expr,
1636         ymm_reg,
1637         zmm_reg,
1638     }
1639 }
1640
1641 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1642 pub struct Ident {
1643     pub name: Symbol,
1644     pub span: Span,
1645 }
1646
1647 impl Ident {
1648     #[inline]
1649     /// Constructs a new identifier from a symbol and a span.
1650     pub const fn new(name: Symbol, span: Span) -> Ident {
1651         Ident { name, span }
1652     }
1653
1654     /// Constructs a new identifier with a dummy span.
1655     #[inline]
1656     pub const fn with_dummy_span(name: Symbol) -> Ident {
1657         Ident::new(name, DUMMY_SP)
1658     }
1659
1660     #[inline]
1661     pub fn empty() -> Ident {
1662         Ident::with_dummy_span(kw::Empty)
1663     }
1664
1665     /// Maps a string to an identifier with a dummy span.
1666     pub fn from_str(string: &str) -> Ident {
1667         Ident::with_dummy_span(Symbol::intern(string))
1668     }
1669
1670     /// Maps a string and a span to an identifier.
1671     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1672         Ident::new(Symbol::intern(string), span)
1673     }
1674
1675     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1676     pub fn with_span_pos(self, span: Span) -> Ident {
1677         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1678     }
1679
1680     pub fn without_first_quote(self) -> Ident {
1681         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1682     }
1683
1684     /// "Normalize" ident for use in comparisons using "item hygiene".
1685     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1686     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1687     /// different macro 2.0 macros.
1688     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1689     pub fn normalize_to_macros_2_0(self) -> Ident {
1690         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1691     }
1692
1693     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1694     /// Identifiers with same string value become same if they came from the same non-transparent
1695     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1696     /// non-transparent macros.
1697     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1698     #[inline]
1699     pub fn normalize_to_macro_rules(self) -> Ident {
1700         Ident::new(self.name, self.span.normalize_to_macro_rules())
1701     }
1702
1703     /// Access the underlying string. This is a slowish operation because it
1704     /// requires locking the symbol interner.
1705     ///
1706     /// Note that the lifetime of the return value is a lie. See
1707     /// `Symbol::as_str()` for details.
1708     pub fn as_str(&self) -> &str {
1709         self.name.as_str()
1710     }
1711 }
1712
1713 impl PartialEq for Ident {
1714     #[inline]
1715     fn eq(&self, rhs: &Self) -> bool {
1716         self.name == rhs.name && self.span.eq_ctxt(rhs.span)
1717     }
1718 }
1719
1720 impl Hash for Ident {
1721     fn hash<H: Hasher>(&self, state: &mut H) {
1722         self.name.hash(state);
1723         self.span.ctxt().hash(state);
1724     }
1725 }
1726
1727 impl fmt::Debug for Ident {
1728     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1729         fmt::Display::fmt(self, f)?;
1730         fmt::Debug::fmt(&self.span.ctxt(), f)
1731     }
1732 }
1733
1734 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1735 /// to printing the original identifier token written in source code (`token_to_string`),
1736 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1737 impl fmt::Display for Ident {
1738     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1739         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1740     }
1741 }
1742
1743 /// This is the most general way to print identifiers.
1744 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1745 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1746 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1747 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1748 /// hygiene data, most importantly name of the crate it refers to.
1749 /// As a result we print `$crate` as `crate` if it refers to the local crate
1750 /// and as `::other_crate_name` if it refers to some other crate.
1751 /// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
1752 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1753 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1754 /// done for a token stream or a single token.
1755 pub struct IdentPrinter {
1756     symbol: Symbol,
1757     is_raw: bool,
1758     /// Span used for retrieving the crate name to which `$crate` refers to,
1759     /// if this field is `None` then the `$crate` conversion doesn't happen.
1760     convert_dollar_crate: Option<Span>,
1761 }
1762
1763 impl IdentPrinter {
1764     /// The most general `IdentPrinter` constructor. Do not use this.
1765     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1766         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1767     }
1768
1769     /// This implementation is supposed to be used when printing identifiers
1770     /// as a part of pretty-printing for larger AST pieces.
1771     /// Do not use this either.
1772     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1773         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1774     }
1775 }
1776
1777 impl fmt::Display for IdentPrinter {
1778     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1779         if self.is_raw {
1780             f.write_str("r#")?;
1781         } else if self.symbol == kw::DollarCrate {
1782             if let Some(span) = self.convert_dollar_crate {
1783                 let converted = span.ctxt().dollar_crate_name();
1784                 if !converted.is_path_segment_keyword() {
1785                     f.write_str("::")?;
1786                 }
1787                 return fmt::Display::fmt(&converted, f);
1788             }
1789         }
1790         fmt::Display::fmt(&self.symbol, f)
1791     }
1792 }
1793
1794 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1795 /// construction.
1796 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1797 // `ModernIdent` struct and use that as well.
1798 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1799 pub struct MacroRulesNormalizedIdent(Ident);
1800
1801 impl MacroRulesNormalizedIdent {
1802     pub fn new(ident: Ident) -> Self {
1803         Self(ident.normalize_to_macro_rules())
1804     }
1805 }
1806
1807 impl fmt::Debug for MacroRulesNormalizedIdent {
1808     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1809         fmt::Debug::fmt(&self.0, f)
1810     }
1811 }
1812
1813 impl fmt::Display for MacroRulesNormalizedIdent {
1814     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1815         fmt::Display::fmt(&self.0, f)
1816     }
1817 }
1818
1819 /// An interned string.
1820 ///
1821 /// Internally, a `Symbol` is implemented as an index, and all operations
1822 /// (including hashing, equality, and ordering) operate on that index. The use
1823 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1824 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1825 ///
1826 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1827 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1828 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1829 pub struct Symbol(SymbolIndex);
1830
1831 rustc_index::newtype_index! {
1832     struct SymbolIndex { .. }
1833 }
1834
1835 impl Symbol {
1836     const fn new(n: u32) -> Self {
1837         Symbol(SymbolIndex::from_u32(n))
1838     }
1839
1840     /// for use in Decoder only
1841     pub fn new_from_decoded(n: u32) -> Self {
1842         Self::new(n)
1843     }
1844
1845     /// Maps a string to its interned representation.
1846     pub fn intern(string: &str) -> Self {
1847         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1848     }
1849
1850     /// Access the underlying string. This is a slowish operation because it
1851     /// requires locking the symbol interner.
1852     ///
1853     /// Note that the lifetime of the return value is a lie. It's not the same
1854     /// as `&self`, but actually tied to the lifetime of the underlying
1855     /// interner. Interners are long-lived, and there are very few of them, and
1856     /// this function is typically used for short-lived things, so in practice
1857     /// it works out ok.
1858     pub fn as_str(&self) -> &str {
1859         with_session_globals(|session_globals| unsafe {
1860             std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
1861         })
1862     }
1863
1864     pub fn as_u32(self) -> u32 {
1865         self.0.as_u32()
1866     }
1867
1868     pub fn is_empty(self) -> bool {
1869         self == kw::Empty
1870     }
1871
1872     /// This method is supposed to be used in error messages, so it's expected to be
1873     /// identical to printing the original identifier token written in source code
1874     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1875     /// or edition, so we have to guess the rawness using the global edition.
1876     pub fn to_ident_string(self) -> String {
1877         Ident::with_dummy_span(self).to_string()
1878     }
1879 }
1880
1881 impl fmt::Debug for Symbol {
1882     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1883         fmt::Debug::fmt(self.as_str(), f)
1884     }
1885 }
1886
1887 impl fmt::Display for Symbol {
1888     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1889         fmt::Display::fmt(self.as_str(), f)
1890     }
1891 }
1892
1893 // takes advantage of `str::to_string` specialization
1894 impl ToString for Symbol {
1895     fn to_string(&self) -> String {
1896         self.as_str().to_string()
1897     }
1898 }
1899
1900 impl<S: Encoder> Encodable<S> for Symbol {
1901     default fn encode(&self, s: &mut S) {
1902         s.emit_str(self.as_str());
1903     }
1904 }
1905
1906 impl<D: Decoder> Decodable<D> for Symbol {
1907     #[inline]
1908     default fn decode(d: &mut D) -> Symbol {
1909         Symbol::intern(&d.read_str())
1910     }
1911 }
1912
1913 impl<CTX> HashStable<CTX> for Symbol {
1914     #[inline]
1915     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1916         self.as_str().hash_stable(hcx, hasher);
1917     }
1918 }
1919
1920 impl<CTX> ToStableHashKey<CTX> for Symbol {
1921     type KeyType = String;
1922     #[inline]
1923     fn to_stable_hash_key(&self, _: &CTX) -> String {
1924         self.as_str().to_string()
1925     }
1926 }
1927
1928 #[derive(Default)]
1929 pub(crate) struct Interner(Lock<InternerInner>);
1930
1931 // The `&'static str`s in this type actually point into the arena.
1932 //
1933 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1934 // found that to regress performance up to 2% in some cases. This might be
1935 // revisited after further improvements to `indexmap`.
1936 //
1937 // This type is private to prevent accidentally constructing more than one
1938 // `Interner` on the same thread, which makes it easy to mix up `Symbol`s
1939 // between `Interner`s.
1940 #[derive(Default)]
1941 struct InternerInner {
1942     arena: DroplessArena,
1943     names: FxHashMap<&'static str, Symbol>,
1944     strings: Vec<&'static str>,
1945 }
1946
1947 impl Interner {
1948     fn prefill(init: &[&'static str]) -> Self {
1949         Interner(Lock::new(InternerInner {
1950             strings: init.into(),
1951             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1952             ..Default::default()
1953         }))
1954     }
1955
1956     #[inline]
1957     fn intern(&self, string: &str) -> Symbol {
1958         let mut inner = self.0.lock();
1959         if let Some(&name) = inner.names.get(string) {
1960             return name;
1961         }
1962
1963         let name = Symbol::new(inner.strings.len() as u32);
1964
1965         // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1966         // and immediately convert the clone back to `&[u8], all because there
1967         // is no `inner.arena.alloc_str()` method. This is clearly safe.
1968         let string: &str =
1969             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1970
1971         // SAFETY: we can extend the arena allocation to `'static` because we
1972         // only access these while the arena is still alive.
1973         let string: &'static str = unsafe { &*(string as *const str) };
1974         inner.strings.push(string);
1975
1976         // This second hash table lookup can be avoided by using `RawEntryMut`,
1977         // but this code path isn't hot enough for it to be worth it. See
1978         // #91445 for details.
1979         inner.names.insert(string, name);
1980         name
1981     }
1982
1983     // Get the symbol as a string. `Symbol::as_str()` should be used in
1984     // preference to this function.
1985     fn get(&self, symbol: Symbol) -> &str {
1986         self.0.lock().strings[symbol.0.as_usize()]
1987     }
1988 }
1989
1990 // This module has a very short name because it's used a lot.
1991 /// This module contains all the defined keyword `Symbol`s.
1992 ///
1993 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1994 /// For example `kw::Loop` or `kw::Break`.
1995 pub mod kw {
1996     pub use super::kw_generated::*;
1997 }
1998
1999 // This module has a very short name because it's used a lot.
2000 /// This module contains all the defined non-keyword `Symbol`s.
2001 ///
2002 /// Given that `sym` is imported, use them like `sym::symbol_name`.
2003 /// For example `sym::rustfmt` or `sym::u8`.
2004 pub mod sym {
2005     use super::Symbol;
2006     use std::convert::TryInto;
2007
2008     #[doc(inline)]
2009     pub use super::sym_generated::*;
2010
2011     // Used from a macro in `librustc_feature/accepted.rs`
2012     pub use super::kw::MacroRules as macro_rules;
2013
2014     /// Get the symbol for an integer.
2015     ///
2016     /// The first few non-negative integers each have a static symbol and therefore
2017     /// are fast.
2018     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
2019         if let Result::Ok(idx) = n.try_into() {
2020             if idx < 10 {
2021                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
2022             }
2023         }
2024         Symbol::intern(&n.to_string())
2025     }
2026 }
2027
2028 impl Symbol {
2029     fn is_special(self) -> bool {
2030         self <= kw::Underscore
2031     }
2032
2033     fn is_used_keyword_always(self) -> bool {
2034         self >= kw::As && self <= kw::While
2035     }
2036
2037     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
2038         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
2039     }
2040
2041     fn is_unused_keyword_always(self) -> bool {
2042         self >= kw::Abstract && self <= kw::Yield
2043     }
2044
2045     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
2046         self == kw::Try && edition() >= Edition::Edition2018
2047     }
2048
2049     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
2050         self.is_special()
2051             || self.is_used_keyword_always()
2052             || self.is_unused_keyword_always()
2053             || self.is_used_keyword_conditional(edition)
2054             || self.is_unused_keyword_conditional(edition)
2055     }
2056
2057     /// A keyword or reserved identifier that can be used as a path segment.
2058     pub fn is_path_segment_keyword(self) -> bool {
2059         self == kw::Super
2060             || self == kw::SelfLower
2061             || self == kw::SelfUpper
2062             || self == kw::Crate
2063             || self == kw::PathRoot
2064             || self == kw::DollarCrate
2065     }
2066
2067     /// Returns `true` if the symbol is `true` or `false`.
2068     pub fn is_bool_lit(self) -> bool {
2069         self == kw::True || self == kw::False
2070     }
2071
2072     /// Returns `true` if this symbol can be a raw identifier.
2073     pub fn can_be_raw(self) -> bool {
2074         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
2075     }
2076
2077     /// Is this symbol was interned in compiler's `symbols!` macro
2078     pub fn is_preinterned(self) -> bool {
2079         self.as_u32() < PREINTERNED_SYMBOLS_COUNT
2080     }
2081 }
2082
2083 impl Ident {
2084     // Returns `true` for reserved identifiers used internally for elided lifetimes,
2085     // unnamed method parameters, crate root module, error recovery etc.
2086     pub fn is_special(self) -> bool {
2087         self.name.is_special()
2088     }
2089
2090     /// Returns `true` if the token is a keyword used in the language.
2091     pub fn is_used_keyword(self) -> bool {
2092         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2093         self.name.is_used_keyword_always()
2094             || self.name.is_used_keyword_conditional(|| self.span.edition())
2095     }
2096
2097     /// Returns `true` if the token is a keyword reserved for possible future use.
2098     pub fn is_unused_keyword(self) -> bool {
2099         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2100         self.name.is_unused_keyword_always()
2101             || self.name.is_unused_keyword_conditional(|| self.span.edition())
2102     }
2103
2104     /// Returns `true` if the token is either a special identifier or a keyword.
2105     pub fn is_reserved(self) -> bool {
2106         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2107         self.name.is_reserved(|| self.span.edition())
2108     }
2109
2110     /// A keyword or reserved identifier that can be used as a path segment.
2111     pub fn is_path_segment_keyword(self) -> bool {
2112         self.name.is_path_segment_keyword()
2113     }
2114
2115     /// We see this identifier in a normal identifier position, like variable name or a type.
2116     /// How was it written originally? Did it use the raw form? Let's try to guess.
2117     pub fn is_raw_guess(self) -> bool {
2118         self.name.can_be_raw() && self.is_reserved()
2119     }
2120 }