symbol.rs 48.1 KB
Newer Older
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 4
//! type, and vice versa.

5
use rustc_arena::DroplessArena;
6
use rustc_data_structures::fx::FxHashMap;
M
Mark Rousskov 已提交
7
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
M
Matthew Jasper 已提交
8
use rustc_macros::HashStable_Generic;
9
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
10

M
Mark Rousskov 已提交
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 19 20
#[cfg(test)]
mod tests;

21
// The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
22 23 24 25 26 27
symbols! {
    // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
    // this should be rarely necessary though if the keywords are kept in alphabetic order.
    Keywords {
        // Special reserved identifiers used internally for elided lifetimes,
        // unnamed method parameters, crate root module, error recovery etc.
J
Joshua Nelson 已提交
28
        Empty:              "",
J
John Kåre Alsaker 已提交
29 30 31
        PathRoot:           "{{root}}",
        DollarCrate:        "$crate",
        Underscore:         "_",
32 33

        // Keywords that are used in stable Rust.
J
John Kåre Alsaker 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
        As:                 "as",
        Break:              "break",
        Const:              "const",
        Continue:           "continue",
        Crate:              "crate",
        Else:               "else",
        Enum:               "enum",
        Extern:             "extern",
        False:              "false",
        Fn:                 "fn",
        For:                "for",
        If:                 "if",
        Impl:               "impl",
        In:                 "in",
        Let:                "let",
        Loop:               "loop",
        Match:              "match",
        Mod:                "mod",
        Move:               "move",
        Mut:                "mut",
        Pub:                "pub",
        Ref:                "ref",
        Return:             "return",
        SelfLower:          "self",
        SelfUpper:          "Self",
        Static:             "static",
        Struct:             "struct",
        Super:              "super",
        Trait:              "trait",
        True:               "true",
        Type:               "type",
        Unsafe:             "unsafe",
        Use:                "use",
        Where:              "where",
        While:              "while",
69 70

        // Keywords that are used in unstable Rust or reserved for future use.
J
John Kåre Alsaker 已提交
71 72
        Abstract:           "abstract",
        Become:             "become",
73
        Box:                "box",
J
John Kåre Alsaker 已提交
74 75 76 77 78 79 80 81 82
        Do:                 "do",
        Final:              "final",
        Macro:              "macro",
        Override:           "override",
        Priv:               "priv",
        Typeof:             "typeof",
        Unsized:            "unsized",
        Virtual:            "virtual",
        Yield:              "yield",
83 84

        // Edition-specific keywords that are used in stable Rust.
85 86
        Async:              "async", // >= 2018 Edition only
        Await:              "await", // >= 2018 Edition only
J
John Kåre Alsaker 已提交
87
        Dyn:                "dyn", // >= 2018 Edition only
88 89

        // Edition-specific keywords that are used in unstable Rust or reserved for future use.
J
John Kåre Alsaker 已提交
90
        Try:                "try", // >= 2018 Edition only
91 92

        // Special lifetime names
J
John Kåre Alsaker 已提交
93 94
        UnderscoreLifetime: "'_",
        StaticLifetime:     "'static",
95 96

        // Weak keywords, have special meaning only in specific contexts.
J
John Kåre Alsaker 已提交
97 98 99
        Auto:               "auto",
        Catch:              "catch",
        Default:            "default",
100
        MacroRules:         "macro_rules",
101
        Raw:                "raw",
J
John Kåre Alsaker 已提交
102
        Union:              "union",
103 104
    }

105 106 107 108 109 110 111
    // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
    //
    // The symbol is the stringified identifier unless otherwise specified, in
    // which case the name should mention the non-identifier punctuation.
    // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
    // called `sym::proc_macro` because then it's easy to mistakenly think it
    // represents "proc_macro".
112
    //
Y
yuk1ty 已提交
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 117 118 119 120 121 122
    // The proc macro will abort if symbols are not in alphabetical order (as
    // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
    // users can sort the list by selecting it and executing the command
    // `:'<,'>!LC_ALL=C sort`.
    //
    // There is currently no checking that all symbols are used; that would be
    // nice to have.
123
    Symbols {
124
        Alignment,
125
        Arc,
126
        Argument,
127 128
        ArgumentV1,
        Arguments,
C
Cameron Steffen 已提交
129 130 131
        BTreeMap,
        BTreeSet,
        BinaryHeap,
R
Ryan Levick 已提交
132
        Borrow,
133
        Break,
134
        C,
M
Mateusz Gacek 已提交
135
        CStr,
N
Nathan Whitaker 已提交
136
        CString,
137
        Center,
138
        Clone,
139
        Continue,
140
        Copy,
141
        Count,
142
        Debug,
143 144
        DebugStruct,
        DebugTuple,
145
        Decodable,
146
        Decoder,
147
        Default,
R
Ryan Levick 已提交
148
        Deref,
149
        Encodable,
150
        Encoder,
151 152 153
        Eq,
        Equal,
        Err,
154 155 156
        Error,
        FormatSpec,
        Formatter,
157 158 159 160 161 162 163 164
        From,
        Future,
        FxHashMap,
        FxHashSet,
        GlobalAlloc,
        Hash,
        HashMap,
        HashSet,
165 166
        Hasher,
        Implied,
167 168
        Input,
        IntoIterator,
169
        Is,
170
        ItemContext,
171 172
        Iterator,
        Layout,
173
        Left,
C
Cameron Steffen 已提交
174
        LinkedList,
175 176 177 178 179 180
        LintPass,
        None,
        Ok,
        Option,
        Ord,
        Ordering,
A
Andrea Nall 已提交
181
        OsStr,
A
Andrea Nall 已提交
182
        OsString,
183
        Output,
184
        Param,
185 186
        PartialEq,
        PartialOrd,
A
Andrea Nall 已提交
187
        Path,
A
Andrea Nall 已提交
188
        PathBuf,
189 190 191
        Pending,
        Pin,
        Poll,
192
        ProcMacro,
193 194 195 196 197 198 199 200 201 202
        ProcMacroHack,
        ProceduralMasqueradeDummyType,
        Range,
        RangeFrom,
        RangeFull,
        RangeInclusive,
        RangeTo,
        RangeToInclusive,
        Rc,
        Ready,
203
        Receiver,
204 205
        Result,
        Return,
206
        Right,
207 208 209 210
        RustcDecodable,
        RustcEncodable,
        Send,
        Some,
211 212
        StructuralEq,
        StructuralPartialEq,
213 214
        Sync,
        Target,
A
Andrea Nall 已提交
215
        ToOwned,
A
Andrea Nall 已提交
216
        ToString,
217 218 219 220
        Try,
        Ty,
        TyCtxt,
        TyKind,
221
        Unknown,
222 223
        Vec,
        Yield,
224
        _DECLS,
225
        _Self,
226 227 228
        __D,
        __H,
        __S,
229
        __next,
230 231 232
        __try_var,
        _d,
        _e,
233
        _task_context,
X
xd009642 已提交
234
        a32,
235 236 237
        aarch64_target_feature,
        abi,
        abi_amdgpu_kernel,
238
        abi_avr_interrupt,
239
        abi_c_cmse_nonsecure_call,
R
roblabla 已提交
240
        abi_efiapi,
241 242 243 244 245 246 247
        abi_msp430_interrupt,
        abi_ptx,
        abi_sysv64,
        abi_thiscall,
        abi_unadjusted,
        abi_vectorcall,
        abi_x86_interrupt,
248
        abort,
249
        aborts,
250 251
        add,
        add_assign,
252
        add_with_overflow,
253
        address,
254 255
        advanced_slice_patterns,
        adx_target_feature,
256 257
        alias,
        align,
258
        align_offset,
259 260
        alignstack,
        all,
261
        alloc,
262
        alloc_error_handler,
263 264
        alloc_layout,
        alloc_zeroed,
265 266
        allocator,
        allocator_internals,
267 268 269 270
        allow,
        allow_fail,
        allow_internal_unsafe,
        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,
X
xd009642 已提交
279
        arm,
280
        arm_target_feature,
281
        array,
282
        arrays,
N
Nathan Whitaker 已提交
283
        as_ptr,
284
        as_str,
285
        asm,
286
        assert,
287
        assert_inhabited,
288
        assert_macro,
289
        assert_receiver_is_total_eq,
290 291
        assert_uninit_valid,
        assert_zero_valid,
292
        associated_consts,
A
Alexander Regueiro 已提交
293
        associated_type_bounds,
294 295
        associated_type_defaults,
        associated_types,
296
        assume,
297
        assume_init,
298
        async_await,
299
        async_closure,
300
        atomics,
301
        att_syntax,
302 303
        attr,
        attr_literals,
304
        attributes,
305
        augmented_assignments,
306
        auto_traits,
307
        automatically_derived,
308 309
        avx512_target_feature,
        await_macro,
310
        bang,
311
        begin_panic,
312
        bench,
313 314
        bin,
        bind_by_move_pattern_guards,
315
        bindings_after_at,
316 317 318 319
        bitand,
        bitand_assign,
        bitor,
        bitor_assign,
320
        bitreverse,
321 322
        bitxor,
        bitxor_assign,
323
        block,
324
        bool,
325
        borrowck_graphviz_format,
326 327
        borrowck_graphviz_postflow,
        borrowck_graphviz_preflow,
328
        box_free,
329 330
        box_patterns,
        box_syntax,
331
        bpf_target_feature,
332
        braced_empty_structs,
333
        branch,
334
        breakpoint,
335
        bridge,
336
        bswap,
N
Nathan Whitaker 已提交
337
        c_str,
338
        c_unwind,
339
        c_variadic,
340 341 342
        call,
        call_mut,
        call_once,
343
        caller_location,
A
Aman Arora 已提交
344
        capture_disjoint_fields,
345
        cdylib,
346 347
        ceilf32,
        ceilf64,
348
        cfg,
349
        cfg_accessible,
350
        cfg_attr,
351
        cfg_attr_multi,
352
        cfg_doctest,
353
        cfg_eval,
D
David Hewitt 已提交
354
        cfg_panic,
355
        cfg_sanitize,
356 357 358 359
        cfg_target_feature,
        cfg_target_has_atomic,
        cfg_target_thread_local,
        cfg_target_vendor,
360
        cfg_version,
361
        char,
362
        client,
F
flip1995 已提交
363
        clippy,
364 365 366
        clone,
        clone_closures,
        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 379 380
        concat_idents,
        conservative_impl_trait,
        console,
V
Vishnunarayan K I 已提交
381
        const_allocate,
382
        const_async_blocks,
383
        const_compare_raw_pointers,
384
        const_constructor,
385
        const_eval_limit,
386
        const_evaluatable_checked,
A
Aaron Hill 已提交
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,
D
Dylan MacKenzie 已提交
399
        const_impl_trait,
D
David Wood 已提交
400
        const_in_array_repeat_expressions,
401
        const_indexing,
402
        const_let,
403
        const_loop,
C
Christian Poveda 已提交
404
        const_mut_refs,
405
        const_panic,
406
        const_precise_live_drops,
407
        const_ptr,
408 409
        const_raw_ptr_deref,
        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 416
        constant,
        constructor,
417
        contents,
O
Oliver Scherer 已提交
418
        context,
419
        convert,
420
        copy,
421
        copy_closures,
422 423 424
        copy_nonoverlapping,
        copysignf32,
        copysignf64,
425 426
        core,
        core_intrinsics,
427 428
        core_panic,
        core_panic_2015_macro,
429
        core_panic_macro,
430 431
        cosf32,
        cosf64,
432
        crate_id,
433
        crate_in_paths,
434
        crate_local,
435 436
        crate_name,
        crate_type,
437
        crate_visibility_modifier,
438
        crt_dash_static: "crt-static",
N
Nathan Whitaker 已提交
439
        cstring_type,
440 441
        ctlz,
        ctlz_nonzero,
442 443 444
        ctpop,
        cttz,
        cttz_nonzero,
445 446 447 448
        custom_attribute,
        custom_derive,
        custom_inner_attributes,
        custom_test_frameworks,
449
        d,
450 451
        dead_code,
        dealloc,
452
        debug,
453
        debug_assert_macro,
454
        debug_assertions,
455
        debug_struct,
O
Oliver Scherer 已提交
456
        debug_trait,
457 458
        debug_trait_builder,
        debug_tuple,
459
        decl_macro,
460
        declare_lint_pass,
461
        decode,
462
        default_alloc_error_handler,
463
        default_lib_allocator,
464 465
        default_type_parameter_fallback,
        default_type_params,
466
        delay_span_bug_from_inside_query,
467 468
        deny,
        deprecated,
469
        deref,
470
        deref_method,
471
        deref_mut,
472
        deref_target,
473
        derive,
474
        destructuring_assignment,
O
Oliver Scherer 已提交
475
        diagnostic,
476
        direct,
477
        discriminant_kind,
478
        discriminant_type,
B
Bastian Kauschke 已提交
479
        discriminant_value,
480 481 482
        dispatch_from_dyn,
        div,
        div_assign,
483
        doc,
484 485 486 487
        doc_alias,
        doc_cfg,
        doc_keyword,
        doc_masked,
488
        doc_notable_trait,
489
        doc_spotlight,
490
        doctest,
491 492
        document_private_items,
        dotdot_in_tuple_patterns,
493
        dotdoteq_in_patterns,
494 495 496
        dreg,
        dreg_low16,
        dreg_low8,
497
        drop,
498
        drop_in_place,
499
        drop_types_in_const,
500 501
        dropck_eyepatch,
        dropck_parametricity,
502
        dylib,
503
        dyn_metadata,
504
        dyn_trait,
M
mark 已提交
505
        edition_macro_pats,
506
        eh_catch_typeinfo,
507
        eh_personality,
508 509 510 511 512
        emit_enum,
        emit_enum_variant,
        emit_enum_variant_arg,
        emit_struct,
        emit_struct_field,
513
        enable,
514
        enclosing_scope,
515
        encode,
516
        env,
517
        eq,
518
        ermsb_target_feature,
519
        exact_div,
520
        except,
521
        exchange_malloc,
522 523 524 525
        exclusive_range_pattern,
        exhaustive_integer_patterns,
        exhaustive_patterns,
        existential_type,
526 527
        exp2f32,
        exp2f64,
N
Nathan Whitaker 已提交
528
        expect,
529
        expected,
530 531
        expf32,
        expf64,
532
        export_name,
533
        expr,
534
        extended_key_value_attributes,
535 536 537 538 539 540
        extern_absolute_paths,
        extern_crate_item_prelude,
        extern_crate_self,
        extern_in_paths,
        extern_prelude,
        extern_types,
541
        external_doc,
542
        f,
543
        f16c_target_feature,
V
Vadim Petrochenkov 已提交
544
        f32,
545
        f32_runtime,
V
Vadim Petrochenkov 已提交
546
        f64,
547
        f64_runtime,
548 549
        fabsf32,
        fabsf64,
550
        fadd_fast,
551
        fdiv_fast,
552
        feature,
N
Nathan Whitaker 已提交
553
        ffi,
554 555
        ffi_const,
        ffi_pure,
556
        ffi_returns_twice,
557
        field,
558 559
        field_init_shorthand,
        file,
560 561 562
        fill,
        finish,
        flags,
563 564
        float_to_int_unchecked,
        floorf32,
565
        floorf64,
566 567
        fmaf32,
        fmaf64,
568
        fmt,
569
        fmt_internals,
570
        fmul_fast,
571
        fn_align,
572
        fn_must_use,
573 574 575
        fn_mut,
        fn_once,
        fn_once_output,
576
        forbid,
577
        forget,
578
        format,
579
        format_args,
D
David Hewitt 已提交
580
        format_args_capture,
581
        format_args_nl,
582
        format_macro,
583
        freeze,
584
        freg,
585
        frem_fast,
586
        from,
587
        from_desugaring,
588
        from_generator,
589
        from_method,
590 591
        from_output,
        from_residual,
592
        from_size_align_unchecked,
593
        from_trait,
594
        from_usize,
595
        fsub_fast,
596
        fundamental,
597
        future,
598 599
        future_trait,
        ge,
600 601
        gen_future,
        gen_kill,
602 603
        generator,
        generator_state,
604
        generators,
605 606
        generic_associated_types,
        generic_param_attrs,
S
Steven Fackler 已提交
607
        get_context,
608
        global_allocator,
609 610
        global_asm,
        globs,
611
        gt,
612
        half_open_range_patterns,
613
        hash,
614 615
        hashmap_type,
        hashset_type,
616 617 618 619 620 621 622 623
        hexagon_target_feature,
        hidden,
        homogeneous_aggregate,
        html_favicon_url,
        html_logo_url,
        html_no_source,
        html_playground_url,
        html_root_url,
T
Tri Vo 已提交
624
        hwaddress,
625
        i,
626 627 628 629 630 631 632 633
        i128,
        i128_type,
        i16,
        i32,
        i64,
        i8,
        ident,
        if_let,
L
Lzu Tao 已提交
634
        if_let_guard,
635
        if_while_or_patterns,
636
        ignore,
637
        impl_header_lifetime_elision,
638
        impl_lint_pass,
639
        impl_macros,
640 641
        impl_trait_in_bindings,
        import_shadowing,
642
        imported_main,
643
        in_band_lifetimes,
644
        include,
645 646
        include_bytes,
        include_str,
647
        inclusive_range_syntax,
648 649
        index,
        index_mut,
650 651
        infer_outlives_requirements,
        infer_static_outlives_requirements,
652
        inherent_associated_types,
653
        inlateout,
654
        inline,
S
Santiago Pastorino 已提交
655
        inline_const,
656
        inout,
X
xd009642 已提交
657
        instruction_set,
658 659
        intel,
        into_iter,
660
        into_trait,
661
        intra_doc_pointers,
662 663
        intrinsics,
        irrefutable_let_patterns,
X
xd009642 已提交
664
        isa_attribute,
665 666 667 668
        isize,
        issue,
        issue_5723_bootstrap,
        issue_tracker_base_url,
669
        item,
670 671
        item_like_imports,
        iter,
672
        keyword,
673
        kind,
674
        kreg,
675 676
        label,
        label_break_value,
677
        lang,
678
        lang_items,
679
        large_assignments,
680
        lateout,
681
        lazy_normalization_consts,
682
        le,
683
        let_chains,
684
        lhs,
685
        lib,
686
        libc,
687
        lifetime,
G
Gary Guo 已提交
688
        likely,
689
        line,
690 691
        link,
        link_args,
692 693
        link_cfg,
        link_llvm_intrinsics,
694
        link_name,
crlf0710's avatar
crlf0710 已提交
695
        link_ordinal,
696
        link_section,
697
        linkage,
698
        lint_reasons,
699
        literal,
A
Amanieu d'Antras 已提交
700
        llvm_asm,
701
        local,
702
        local_inner_macros,
703 704 705 706
        log10f32,
        log10f64,
        log2f32,
        log2f64,
707
        log_syntax,
708 709
        logf32,
        logf64,
710
        loop_break_value,
711
        lt,
712
        macro_at_most_once_rep,
713
        macro_attributes_in_derive_output,
714 715
        macro_escape,
        macro_export,
716 717 718
        macro_lifetime_matcher,
        macro_literal_matcher,
        macro_reexport,
719
        macro_use,
720
        macro_vis_matcher,
721
        macros_in_extern,
722
        main,
723
        managed_boxes,
724
        manually_drop,
725
        map,
726
        marker,
727
        marker_trait_attr,
728
        masked,
729 730
        match_beginning_vert,
        match_default_bindings,
731 732
        maxnumf32,
        maxnumf64,
733
        may_dangle,
734
        maybe_uninit,
735 736
        maybe_uninit_uninit,
        maybe_uninit_zeroed,
737 738
        mem_uninitialized,
        mem_zeroed,
739 740
        member_constraints,
        memory,
741
        message,
742
        meta,
743
        metadata_type,
744
        min_align_of,
745
        min_align_of_val,
746
        min_const_fn,
747
        min_const_generics,
748
        min_const_unsafe_fn,
749
        min_specialization,
750
        min_type_alias_impl_trait,
751 752
        minnumf32,
        minnumf64,
753
        mips_target_feature,
754
        misc,
755
        modifiers,
756
        module,
757
        module_path,
758
        more_qualified_paths,
759
        more_struct_aliases,
760
        movbe_target_feature,
761
        move_ref_pattern,
762
        move_size_limit,
763 764
        mul,
        mul_assign,
765
        mul_with_overflow,
766
        must_use,
767 768
        mut_ptr,
        mut_slice_ptr,
769
        naked,
770 771
        naked_functions,
        name,
772 773 774 775 776
        native_link_modifiers,
        native_link_modifiers_as_needed,
        native_link_modifiers_bundle,
        native_link_modifiers_verbatim,
        native_link_modifiers_whole_archive,
777
        ne,
778 779
        nearbyintf32,
        nearbyintf64,
780
        needs_allocator,
781
        needs_drop,
782
        needs_panic_runtime,
783
        neg,
784
        negate_unsigned,
785
        negative_impls,
786 787
        never,
        never_type,
788
        never_type_fallback,
789
        new,
790
        new_unchecked,
791
        next,
792
        nll,
793
        no,
794 795
        no_builtins,
        no_core,
796
        no_coverage,
797
        no_crate_inject,
798
        no_debug,
799
        no_default_passes,
800
        no_implicit_prelude,
801
        no_inline,
802 803 804
        no_link,
        no_main,
        no_mangle,
805 806 807 808 809
        no_niche,
        no_sanitize,
        no_stack_check,
        no_start,
        no_std,
810
        nomem,
811 812 813
        non_ascii_idents,
        non_exhaustive,
        non_modrs_mods,
814
        none_error,
815
        nontemporal_store,
R
Ryan Levick 已提交
816
        noop_method_borrow,
817
        noop_method_clone,
R
Ryan Levick 已提交
818
        noop_method_deref,
819 820
        noreturn,
        nostack,
821
        not,
822
        notable_trait,
823
        note,
824
        object_safe_for_dispatch,
825
        of,
826
        offset,
827
        omit_gdb_pretty_printer_section,
828 829 830
        on,
        on_unimplemented,
        oom,
831
        opaque,
832
        ops,
833
        opt_out_copy,
834
        optimize,
835 836 837
        optimize_attribute,
        optin_builtin_traits,
        option,
838
        option_env,
839
        option_type,
840
        options,
841
        or,
842
        or_patterns,
843
        other,
844
        out,
845
        overlapping_marker_traits,
846
        owned_box,
847
        packed,
848
        panic,
849 850
        panic_2015,
        panic_2021,
851 852
        panic_abort,
        panic_bounds_check,
853
        panic_handler,
854 855
        panic_impl,
        panic_implementation,
856 857
        panic_info,
        panic_location,
858
        panic_runtime,
859
        panic_str,
860
        panic_unwind,
861
        panicking,
862
        param_attrs,
863
        parent_trait,
864
        partial_cmp,
865
        partial_ord,
866
        passes,
867
        pat,
M
mark 已提交
868
        pat_param,
869
        path,
870
        pattern_parentheses,
871
        phantom_data,
872
        pin,
873
        pinned,
874
        platform_intrinsics,
875 876
        plugin,
        plugin_registrar,
877
        plugins,
878
        pointee_trait,
879
        pointer,
880 881
        pointer_trait,
        pointer_trait_fmt,
882
        poll,
883
        position,
884
        post_dash_lto: "post-lto",
885
        powerpc_target_feature,
886 887 888 889
        powf32,
        powf64,
        powif32,
        powif64,
890
        pre_dash_lto: "pre-lto",
891
        precise_pointer_size_matching,
892
        precision,
893
        pref_align_of,
894 895 896 897
        prefetch_read_data,
        prefetch_read_instruction,
        prefetch_write_data,
        prefetch_write_instruction,
898
        prelude,
899
        prelude_import,
900
        preserves_flags,
901 902
        primitive,
        proc_dash_macro: "proc-macro",
903 904
        proc_macro,
        proc_macro_attribute,
905
        proc_macro_def_site,
906
        proc_macro_derive,
907 908 909
        proc_macro_expr,
        proc_macro_gen,
        proc_macro_hygiene,
910
        proc_macro_internals,
911 912 913
        proc_macro_mod,
        proc_macro_non_items,
        proc_macro_path_invoc,
914
        profiler_builtins,
915
        profiler_runtime,
916 917
        ptr_guaranteed_eq,
        ptr_guaranteed_ne,
A
Aliénore Bouttefeux 已提交
918 919
        ptr_null,
        ptr_null_mut,
920
        ptr_offset_from,
921
        pub_macro_rules,
922
        pub_restricted,
923
        pure,
924
        pushpop_unsafe,
925 926 927
        qreg,
        qreg_low4,
        qreg_low8,
928 929 930
        quad_precision_float,
        question_mark,
        quote,
931
        range_inclusive_new,
crlf0710's avatar
crlf0710 已提交
932
        raw_dylib,
933
        raw_identifiers,
934
        raw_ref_op,
935
        re_rebalance_coherence,
936 937 938 939 940
        read_enum,
        read_enum_variant,
        read_enum_variant_arg,
        read_struct,
        read_struct_field,
941
        readonly,
942
        realloc,
943
        reason,
944
        receiver,
945 946
        recursion_limit,
        reexport_test_harness_main,
947
        ref_unwind_safe,
948
        reference,
949
        reflect,
950 951 952 953 954 955
        reg,
        reg16,
        reg32,
        reg64,
        reg_abcd,
        reg_byte,
956
        reg_nonzero,
957
        reg_thumb,
958 959
        register_attr,
        register_tool,
960
        relaxed_adts,
961
        relaxed_struct_unsize,
962 963
        rem,
        rem_assign,
964
        repr,
965 966 967
        repr128,
        repr_align,
        repr_align_enum,
F
Felix S. Klock II 已提交
968
        repr_no_niche,
969 970 971
        repr_packed,
        repr_simd,
        repr_transparent,
972
        residual,
973
        result,
974
        result_type,
975
        rhs,
976 977
        rintf32,
        rintf64,
A
Amanieu d'Antras 已提交
978
        riscv_target_feature,
979
        rlib,
980 981
        rotate_left,
        rotate_right,
982 983
        roundf32,
        roundf64,
984
        rt,
985 986
        rtm_target_feature,
        rust,
987
        rust_2015,
988
        rust_2015_preview,
989
        rust_2018,
990
        rust_2018_preview,
991
        rust_2021,
M
Mara Bos 已提交
992
        rust_2021_preview,
993
        rust_begin_unwind,
994
        rust_eh_catch_typeinfo,
995 996 997 998
        rust_eh_personality,
        rust_eh_register_frames,
        rust_eh_unregister_frames,
        rust_oom,
O
Oliver Scherer 已提交
999
        rustc,
1000
        rustc_allocator,
1001
        rustc_allocator_nounwind,
1002
        rustc_allow_const_fn_unstable,
1003
        rustc_attrs,
1004
        rustc_builtin_macro,
A
Aman Arora 已提交
1005
        rustc_capture_analysis,
1006
        rustc_clean,
1007
        rustc_const_stable,
1008
        rustc_const_unstable,
1009 1010 1011
        rustc_conversion_suggestion,
        rustc_def_path,
        rustc_deprecated,
O
Oliver Scherer 已提交
1012
        rustc_diagnostic_item,
1013
        rustc_diagnostic_macros,
1014
        rustc_dirty,
1015
        rustc_dummy,
1016
        rustc_dump_env_program_clauses,
1017 1018 1019
        rustc_dump_program_clauses,
        rustc_dump_user_substs,
        rustc_error,
1020
        rustc_evaluate_where_clauses,
1021 1022 1023
        rustc_expected_cgu_reuse,
        rustc_if_this_changed,
        rustc_inherit_overflow_checks,
1024
        rustc_insignificant_dtor,
1025 1026 1027
        rustc_layout,
        rustc_layout_scalar_valid_range_end,
        rustc_layout_scalar_valid_range_start,
1028
        rustc_legacy_const_generics,
1029
        rustc_macro_transparency,
crlf0710's avatar
crlf0710 已提交
1030
        rustc_main,
1031
        rustc_mir,
1032
        rustc_nonnull_optimization_guaranteed,
1033
        rustc_object_lifetime_default,
1034 1035 1036 1037 1038
        rustc_on_unimplemented,
        rustc_outlives,
        rustc_paren_sugar,
        rustc_partition_codegened,
        rustc_partition_reused,
1039 1040
        rustc_peek,
        rustc_peek_definite_init,
1041
        rustc_peek_indirectly_mutable,
1042
        rustc_peek_liveness,
1043 1044
        rustc_peek_maybe_init,
        rustc_peek_maybe_uninit,
1045
        rustc_polymorphize_error,
1046
        rustc_private,
1047
        rustc_proc_macro_decls,
1048
        rustc_promotable,
1049
        rustc_regions,
1050
        rustc_reservation_impl,
1051
        rustc_serialize,
1052
        rustc_skip_array_during_method_dispatch,
1053
        rustc_specialization_trait,
1054
        rustc_stable,
1055 1056 1057 1058 1059
        rustc_std_internal_symbol,
        rustc_symbol_name,
        rustc_synthetic,
        rustc_test_marker,
        rustc_then_this_would_need,
1060
        rustc_unsafe_specialization_marker,
1061
        rustc_variance,
1062
        rustdoc,
1063
        rustfmt,
1064
        rvalue_static_promotion,
1065
        sanitize,
1066
        sanitizer_runtime,
1067 1068
        saturating_add,
        saturating_sub,
1069 1070
        self_in_typedefs,
        self_struct_ctor,
1071
        semitransparent,
1072
        send,
1073
        send_trait,
1074 1075
        shl,
        shl_assign,
1076
        should_panic,
1077 1078
        shr,
        shr_assign,
1079
        simd,
1080 1081 1082 1083 1084 1085 1086
        simd_add,
        simd_and,
        simd_bitmask,
        simd_cast,
        simd_ceil,
        simd_div,
        simd_eq,
1087
        simd_extract,
1088 1089 1090 1091
        simd_fabs,
        simd_fcos,
        simd_fexp,
        simd_fexp2,
1092
        simd_ffi,
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
        simd_flog,
        simd_flog10,
        simd_flog2,
        simd_floor,
        simd_fma,
        simd_fmax,
        simd_fmin,
        simd_fpow,
        simd_fpowi,
        simd_fsin,
        simd_fsqrt,
        simd_gather,
        simd_ge,
        simd_gt,
1107
        simd_insert,
1108 1109 1110 1111
        simd_le,
        simd_lt,
        simd_mul,
        simd_ne,
S
SparrowLii 已提交
1112
        simd_neg,
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
        simd_or,
        simd_reduce_add_ordered,
        simd_reduce_add_unordered,
        simd_reduce_all,
        simd_reduce_and,
        simd_reduce_any,
        simd_reduce_max,
        simd_reduce_max_nanless,
        simd_reduce_min,
        simd_reduce_min_nanless,
        simd_reduce_mul_ordered,
        simd_reduce_mul_unordered,
        simd_reduce_or,
        simd_reduce_xor,
        simd_rem,
J
Jubilee Young 已提交
1128
        simd_round,
1129 1130 1131 1132 1133 1134 1135 1136
        simd_saturating_add,
        simd_saturating_sub,
        simd_scatter,
        simd_select,
        simd_select_bitmask,
        simd_shl,
        simd_shr,
        simd_sub,
J
Jubilee Young 已提交
1137
        simd_trunc,
1138
        simd_xor,
1139
        since,
1140 1141
        sinf32,
        sinf64,
1142
        size,
1143
        size_of,
1144
        size_of_val,
1145
        sized,
1146
        skip,
1147 1148
        slice,
        slice_alloc,
1149
        slice_patterns,
1150 1151
        slice_u8,
        slice_u8_alloc,
1152
        slicing_syntax,
1153
        soft,
1154 1155
        specialization,
        speed,
1156
        spotlight,
1157 1158
        sqrtf32,
        sqrtf64,
1159 1160
        sreg,
        sreg_low16,
1161
        sse4a_target_feature,
1162
        stable,
1163
        staged_api,
1164
        start,
1165
        state,
1166 1167 1168
        static_in_const,
        static_nobundle,
        static_recursion,
1169
        staticlib,
1170
        std,
1171
        std_inject,
1172 1173
        std_panic,
        std_panic_2015_macro,
1174
        std_panic_macro,
1175
        stmt,
1176 1177
        stmt_expr_attributes,
        stop_after_dataflow,
1178
        str,
1179
        str_alloc,
1180
        string_type,
1181
        stringify,
1182 1183
        struct_field_attributes,
        struct_inherit,
1184
        struct_variant,
1185
        structural_match,
1186 1187
        structural_peq,
        structural_teq,
O
Oliver Scherer 已提交
1188
        sty,
1189 1190
        sub,
        sub_assign,
1191
        sub_with_overflow,
1192
        suggestion,
1193
        sym,
1194
        sync,
1195
        sync_trait,
X
xd009642 已提交
1196
        t32,
1197 1198 1199 1200
        target_arch,
        target_endian,
        target_env,
        target_family,
1201
        target_feature,
1202
        target_feature_11,
1203
        target_has_atomic,
1204
        target_has_atomic_equal_alignment,
1205
        target_has_atomic_load_store,
1206 1207 1208
        target_os,
        target_pointer_width,
        target_target_vendor,
1209
        target_thread_local,
1210
        target_vendor,
1211 1212
        task,
        tbm_target_feature,
1213
        termination,
1214 1215 1216 1217 1218
        termination_trait,
        termination_trait_test,
        test,
        test_2018_feature,
        test_accepted_feature,
1219
        test_case,
1220
        test_removed_feature,
1221
        test_runner,
1222
        then_with,
1223
        thread,
1224
        thread_local,
1225 1226 1227
        tool_attributes,
        tool_lints,
        trace_macros,
A
Ayose 已提交
1228
        track_caller,
1229 1230 1231
        trait_alias,
        transmute,
        transparent,
1232 1233
        transparent_enums,
        transparent_unions,
1234
        trivial_bounds,
1235 1236
        truncf32,
        truncf64,
1237
        try_blocks,
1238 1239
        try_from_trait,
        try_into_trait,
1240
        try_trait_v2,
1241
        tt,
1242
        tuple,
1243
        tuple_from_req,
1244
        tuple_indexing,
1245
        two_phase,
1246 1247
        ty,
        type_alias_enum_variants,
1248
        type_alias_impl_trait,
1249
        type_ascription,
1250
        type_id,
1251
        type_length_limit,
1252
        type_macros,
1253
        type_name,
1254 1255 1256 1257 1258
        u128,
        u16,
        u32,
        u64,
        u8,
1259 1260
        unaligned_volatile_load,
        unaligned_volatile_store,
1261
        unboxed_closures,
1262 1263 1264 1265
        unchecked_add,
        unchecked_div,
        unchecked_mul,
        unchecked_rem,
1266 1267
        unchecked_shl,
        unchecked_shr,
1268
        unchecked_sub,
1269 1270 1271 1272
        underscore_const_names,
        underscore_imports,
        underscore_lifetimes,
        uniform_paths,
1273
        unit,
1274
        universal_impl_trait,
1275
        unix,
G
Gary Guo 已提交
1276
        unlikely,
1277
        unmarked_api,
1278
        unnamed_fields,
1279
        unpin,
1280
        unreachable,
1281
        unreachable_code,
1282
        unrestricted_attribute_tokens,
L
LeSeulArtichaut 已提交
1283
        unsafe_block_in_unsafe_fn,
1284
        unsafe_cell,
1285
        unsafe_no_drop_flag,
1286
        unsize,
S
Santiago Pastorino 已提交
1287
        unsized_fn_params,
1288 1289
        unsized_locals,
        unsized_tuple_coercion,
1290
        unstable,
1291
        untagged_unions,
1292
        unused_qualifications,
1293
        unwind,
1294
        unwind_attributes,
1295
        unwind_safe,
N
Nathan Whitaker 已提交
1296
        unwrap,
1297
        unwrap_or,
1298 1299
        use_extern_macros,
        use_nested_groups,
1300
        used,
1301 1302
        usize,
        v1,
1303 1304 1305
        va_arg,
        va_copy,
        va_end,
1306
        va_list,
1307 1308
        va_start,
        val,
1309 1310
        var,
        variant_count,
1311
        vec,
1312
        vec_type,
C
Cameron Steffen 已提交
1313
        vecdeque_type,
1314
        version,
1315 1316 1317
        vis,
        visible_private_types,
        volatile,
1318 1319 1320 1321 1322
        volatile_copy_memory,
        volatile_copy_nonoverlapping_memory,
        volatile_load,
        volatile_set_memory,
        volatile_store,
1323 1324
        vreg,
        vreg_low16,
1325
        warn,
A
Alex Crichton 已提交
1326
        wasm_abi,
1327 1328 1329
        wasm_import_module,
        wasm_target_feature,
        while_let,
1330
        width,
1331
        windows,
1332
        windows_subsystem,
1333 1334
        wrapping_add,
        wrapping_mul,
1335
        wrapping_sub,
1336
        wreg,
1337
        write_bytes,
1338 1339 1340
        xmm_reg,
        ymm_reg,
        zmm_reg,
1341 1342 1343
    }
}

M
Matthew Jasper 已提交
1344
#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1345 1346
pub struct Ident {
    pub name: Symbol,
1347
    pub span: Span,
1348 1349 1350
}

impl Ident {
1351
    #[inline]
N
Nicholas Nethercote 已提交
1352
    /// Constructs a new identifier from a symbol and a span.
1353 1354 1355
    pub const fn new(name: Symbol, span: Span) -> Ident {
        Ident { name, span }
    }
1356

1357
    /// Constructs a new identifier with a dummy span.
1358
    #[inline]
1359
    pub const fn with_dummy_span(name: Symbol) -> Ident {
1360
        Ident::new(name, DUMMY_SP)
1361 1362
    }

1363 1364
    #[inline]
    pub fn invalid() -> Ident {
J
Joshua Nelson 已提交
1365
        Ident::with_dummy_span(kw::Empty)
1366 1367
    }

M
Matthew Jasper 已提交
1368
    /// Maps a string to an identifier with a dummy span.
1369
    pub fn from_str(string: &str) -> Ident {
1370
        Ident::with_dummy_span(Symbol::intern(string))
1371 1372
    }

N
Nicholas Nethercote 已提交
1373 1374 1375 1376 1377
    /// Maps a string and a span to an identifier.
    pub fn from_str_and_span(string: &str, span: Span) -> Ident {
        Ident::new(Symbol::intern(string), span)
    }

A
Alexander Regueiro 已提交
1378
    /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
V
Vadim Petrochenkov 已提交
1379 1380 1381 1382 1383
    pub fn with_span_pos(self, span: Span) -> Ident {
        Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
    }

    pub fn without_first_quote(self) -> Ident {
A
Alex Crichton 已提交
1384
        Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1385 1386
    }

V
Vadim Petrochenkov 已提交
1387
    /// "Normalize" ident for use in comparisons using "item hygiene".
1388
    /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1389
    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1390
    /// different macro 2.0 macros.
V
Vadim Petrochenkov 已提交
1391
    /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1392 1393
    pub fn normalize_to_macros_2_0(self) -> Ident {
        Ident::new(self.name, self.span.normalize_to_macros_2_0())
1394
    }
1395

V
Vadim Petrochenkov 已提交
1396 1397
    /// "Normalize" ident for use in comparisons using "local variable hygiene".
    /// Identifiers with same string value become same if they came from the same non-transparent
1398
    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
V
Vadim Petrochenkov 已提交
1399 1400
    /// non-transparent macros.
    /// Technically, this operation strips all transparent marks from ident's syntactic context.
1401 1402
    pub fn normalize_to_macro_rules(self) -> Ident {
        Ident::new(self.name, self.span.normalize_to_macro_rules())
1403 1404
    }

1405 1406 1407
    /// Convert the name to a `SymbolStr`. This is a slowish operation because
    /// it requires locking the symbol interner.
    pub fn as_str(self) -> SymbolStr {
V
Vadim Petrochenkov 已提交
1408 1409
        self.name.as_str()
    }
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421
}

impl PartialEq for Ident {
    fn eq(&self, rhs: &Self) -> bool {
        self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
    }
}

impl Hash for Ident {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.name.hash(state);
        self.span.ctxt().hash(state);
1422 1423 1424 1425
    }
}

impl fmt::Debug for Ident {
T
Taiki Endo 已提交
1426
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1427 1428
        fmt::Display::fmt(self, f)?;
        fmt::Debug::fmt(&self.span.ctxt(), f)
1429 1430 1431
    }
}

1432 1433 1434
/// This implementation is supposed to be used in error messages, so it's expected to be identical
/// to printing the original identifier token written in source code (`token_to_string`),
/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1435
impl fmt::Display for Ident {
T
Taiki Endo 已提交
1436
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1437
        fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1438 1439 1440
    }
}

1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
/// This is the most general way to print identifiers.
/// AST pretty-printer is used as a fallback for turning AST structures into token streams for
/// proc macros. Additionally, proc macros may stringify their input and expect it survive the
/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
/// hygiene data, most importantly name of the crate it refers to.
/// As a result we print `$crate` as `crate` if it refers to the local crate
/// and as `::other_crate_name` if it refers to some other crate.
/// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
/// so we should not perform this lossy conversion if the top level call to the pretty-printer was
/// done for a token stream or a single token.
pub struct IdentPrinter {
    symbol: Symbol,
    is_raw: bool,
    /// Span used for retrieving the crate name to which `$crate` refers to,
    /// if this field is `None` then the `$crate` conversion doesn't happen.
    convert_dollar_crate: Option<Span>,
}

impl IdentPrinter {
    /// The most general `IdentPrinter` constructor. Do not use this.
    pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
        IdentPrinter { symbol, is_raw, convert_dollar_crate }
    }

    /// This implementation is supposed to be used when printing identifiers
    /// as a part of pretty-printing for larger AST pieces.
    /// Do not use this either.
    pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
        IdentPrinter::new(ident.name, is_raw, Some(ident.span))
    }
}

impl fmt::Display for IdentPrinter {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.is_raw {
            f.write_str("r#")?;
J
Joshua Nelson 已提交
1479 1480 1481 1482 1483
        } else if self.symbol == kw::DollarCrate {
            if let Some(span) = self.convert_dollar_crate {
                let converted = span.ctxt().dollar_crate_name();
                if !converted.is_path_segment_keyword() {
                    f.write_str("::")?;
1484
                }
J
Joshua Nelson 已提交
1485
                return fmt::Display::fmt(&converted, f);
1486 1487 1488 1489 1490 1491
            }
        }
        fmt::Display::fmt(&self.symbol, f)
    }
}

1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
/// construction.
// FIXME(matthewj, petrochenkov) Use this more often, add a similar
// `ModernIdent` struct and use that as well.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct MacroRulesNormalizedIdent(Ident);

impl MacroRulesNormalizedIdent {
    pub fn new(ident: Ident) -> Self {
        Self(ident.normalize_to_macro_rules())
    }
}

impl fmt::Debug for MacroRulesNormalizedIdent {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.0, f)
    }
}

impl fmt::Display for MacroRulesNormalizedIdent {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

M
Matthew Jasper 已提交
1517
/// An interned string.
N
Nicholas Nethercote 已提交
1518
///
M
Matthew Jasper 已提交
1519
/// Internally, a `Symbol` is implemented as an index, and all operations
N
Nicholas Nethercote 已提交
1520
/// (including hashing, equality, and ordering) operate on that index. The use
1521 1522
/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1523
///
1524
/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
N
Nicholas Nethercote 已提交
1525
/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1526
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1527 1528
pub struct Symbol(SymbolIndex);

1529
rustc_index::newtype_index! {
1530 1531
    pub struct SymbolIndex { .. }
}
1532 1533

impl Symbol {
1534
    const fn new(n: u32) -> Self {
1535
        Symbol(SymbolIndex::from_u32(n))
1536 1537
    }

1538 1539 1540 1541 1542
    /// Maps a string to its interned representation.
    pub fn intern(string: &str) -> Self {
        with_interner(|interner| interner.intern(string))
    }

1543 1544 1545
    /// Convert to a `SymbolStr`. This is a slowish operation because it
    /// requires locking the symbol interner.
    pub fn as_str(self) -> SymbolStr {
J
Jeffrey Seyfried 已提交
1546
        with_interner(|interner| unsafe {
M
Mark Rousskov 已提交
1547
            SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
J
Jeffrey Seyfried 已提交
1548
        })
1549 1550 1551
    }

    pub fn as_u32(self) -> u32 {
1552
        self.0.as_u32()
1553
    }
1554

J
Joshua Nelson 已提交
1555
    pub fn is_empty(self) -> bool {
J
Joshua Nelson 已提交
1556
        self == kw::Empty
J
Joshua Nelson 已提交
1557 1558
    }

1559 1560 1561 1562 1563 1564 1565
    /// This method is supposed to be used in error messages, so it's expected to be
    /// identical to printing the original identifier token written in source code
    /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
    /// or edition, so we have to guess the rawness using the global edition.
    pub fn to_ident_string(self) -> String {
        Ident::with_dummy_span(self).to_string()
    }
1566 1567 1568
}

impl fmt::Debug for Symbol {
T
Taiki Endo 已提交
1569
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1570
        fmt::Debug::fmt(&self.as_str(), f)
1571 1572 1573 1574
    }
}

impl fmt::Display for Symbol {
T
Taiki Endo 已提交
1575
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1576
        fmt::Display::fmt(&self.as_str(), f)
1577 1578 1579
    }
}

M
Matthew Jasper 已提交
1580 1581
impl<S: Encoder> Encodable<S> for Symbol {
    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1582
        s.emit_str(&self.as_str())
1583 1584 1585
    }
}

M
Matthew Jasper 已提交
1586
impl<D: Decoder> Decodable<D> for Symbol {
1587
    #[inline]
M
Matthew Jasper 已提交
1588
    fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1589 1590 1591 1592
        Ok(Symbol::intern(&d.read_str()?))
    }
}

1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
impl<CTX> HashStable<CTX> for Symbol {
    #[inline]
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
        self.as_str().hash_stable(hcx, hasher);
    }
}

impl<CTX> ToStableHashKey<CTX> for Symbol {
    type KeyType = SymbolStr;

    #[inline]
    fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
        self.as_str()
    }
}

1609
// The `&'static str`s in this type actually point into the arena.
1610 1611 1612 1613
//
// The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
// found that to regress performance up to 2% in some cases. This might be
// revisited after further improvements to `indexmap`.
1614
#[derive(Default)]
1615
pub struct Interner {
1616 1617 1618
    arena: DroplessArena,
    names: FxHashMap<&'static str, Symbol>,
    strings: Vec<&'static str>,
1619 1620 1621
}

impl Interner {
1622 1623
    fn prefill(init: &[&'static str]) -> Self {
        Interner {
1624 1625
            strings: init.into(),
            names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1626
            ..Default::default()
1627 1628 1629
        }
    }

1630
    #[inline]
1631 1632 1633 1634 1635
    pub fn intern(&mut self, string: &str) -> Symbol {
        if let Some(&name) = self.names.get(string) {
            return name;
        }

1636
        let name = Symbol::new(self.strings.len() as u32);
1637

1638 1639
        // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
        // UTF-8.
M
Mark Rousskov 已提交
1640 1641
        let string: &str =
            unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1642 1643
        // It is safe to extend the arena allocation to `'static` because we only access
        // these while the arena is still alive.
M
Mark Rousskov 已提交
1644
        let string: &'static str = unsafe { &*(string as *const str) };
1645
        self.strings.push(string);
1646 1647 1648
        self.names.insert(string, name);
        name
    }
1649

N
Nicholas Nethercote 已提交
1650 1651
    // Get the symbol as a string. `Symbol::as_str()` should be used in
    // preference to this function.
J
Jeffrey Seyfried 已提交
1652
    pub fn get(&self, symbol: Symbol) -> &str {
M
Matthew Jasper 已提交
1653
        self.strings[symbol.0.as_usize()]
1654 1655 1656
    }
}

1657
// This module has a very short name because it's used a lot.
1658 1659 1660 1661
/// This module contains all the defined keyword `Symbol`s.
///
/// Given that `kw` is imported, use them like `kw::keyword_name`.
/// For example `kw::Loop` or `kw::Break`.
1662
pub mod kw {
1663
    pub use super::kw_generated::*;
1664 1665
}

1666
// This module has a very short name because it's used a lot.
1667 1668 1669 1670
/// This module contains all the defined non-keyword `Symbol`s.
///
/// Given that `sym` is imported, use them like `sym::symbol_name`.
/// For example `sym::rustfmt` or `sym::u8`.
1671
pub mod sym {
1672
    use super::Symbol;
M
Mark Rousskov 已提交
1673
    use std::convert::TryInto;
1674

L
LeSeulArtichaut 已提交
1675
    #[doc(inline)]
1676
    pub use super::sym_generated::*;
1677 1678 1679

    // Used from a macro in `librustc_feature/accepted.rs`
    pub use super::kw::MacroRules as macro_rules;
1680

1681 1682 1683 1684
    /// Get the symbol for an integer.
    ///
    /// The first few non-negative integers each have a static symbol and therefore
    /// are fast.
1685 1686
    pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
        if let Result::Ok(idx) = n.try_into() {
1687 1688
            if idx < 10 {
                return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1689 1690 1691 1692
            }
        }
        Symbol::intern(&n.to_string())
    }
1693 1694
}

1695
impl Symbol {
1696 1697
    fn is_special(self) -> bool {
        self <= kw::Underscore
1698 1699
    }

1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721
    fn is_used_keyword_always(self) -> bool {
        self >= kw::As && self <= kw::While
    }

    fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
        (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
    }

    fn is_unused_keyword_always(self) -> bool {
        self >= kw::Abstract && self <= kw::Yield
    }

    fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
        self == kw::Try && edition() >= Edition::Edition2018
    }

    pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
        self.is_special()
            || self.is_used_keyword_always()
            || self.is_unused_keyword_always()
            || self.is_used_keyword_conditional(edition)
            || self.is_unused_keyword_conditional(edition)
1722
    }
1723

1724 1725
    /// A keyword or reserved identifier that can be used as a path segment.
    pub fn is_path_segment_keyword(self) -> bool {
M
Mark Rousskov 已提交
1726 1727 1728 1729 1730 1731
        self == kw::Super
            || self == kw::SelfLower
            || self == kw::SelfUpper
            || self == kw::Crate
            || self == kw::PathRoot
            || self == kw::DollarCrate
1732 1733
    }

1734 1735 1736 1737 1738
    /// Returns `true` if the symbol is `true` or `false`.
    pub fn is_bool_lit(self) -> bool {
        self == kw::True || self == kw::False
    }

1739
    /// Returns `true` if this symbol can be a raw identifier.
1740
    pub fn can_be_raw(self) -> bool {
J
Joshua Nelson 已提交
1741
        self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1742
    }
1743 1744 1745
}

impl Ident {
1746
    // Returns `true` for reserved identifiers used internally for elided lifetimes,
1747 1748
    // unnamed method parameters, crate root module, error recovery etc.
    pub fn is_special(self) -> bool {
1749
        self.name.is_special()
1750 1751 1752 1753
    }

    /// Returns `true` if the token is a keyword used in the language.
    pub fn is_used_keyword(self) -> bool {
1754
        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1755 1756
        self.name.is_used_keyword_always()
            || self.name.is_used_keyword_conditional(|| self.span.edition())
1757 1758 1759 1760 1761
    }

    /// Returns `true` if the token is a keyword reserved for possible future use.
    pub fn is_unused_keyword(self) -> bool {
        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1762 1763
        self.name.is_unused_keyword_always()
            || self.name.is_unused_keyword_conditional(|| self.span.edition())
1764 1765 1766 1767
    }

    /// Returns `true` if the token is either a special identifier or a keyword.
    pub fn is_reserved(self) -> bool {
1768 1769
        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
        self.name.is_reserved(|| self.span.edition())
1770 1771 1772 1773
    }

    /// A keyword or reserved identifier that can be used as a path segment.
    pub fn is_path_segment_keyword(self) -> bool {
1774
        self.name.is_path_segment_keyword()
1775 1776 1777 1778 1779
    }

    /// We see this identifier in a normal identifier position, like variable name or a type.
    /// How was it written originally? Did it use the raw form? Let's try to guess.
    pub fn is_raw_guess(self) -> bool {
1780
        self.name.can_be_raw() && self.is_reserved()
1781 1782 1783
    }
}

1784
#[inline]
1785
fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1786
    SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
1787 1788
}

1789
/// An alternative to [`Symbol`], useful when the chars within the symbol need to
N
Nicholas Nethercote 已提交
1790 1791
/// be accessed. It deliberately has limited functionality and should only be
/// used for temporary values.
N
Nicholas Nethercote 已提交
1792 1793 1794 1795 1796
///
/// Because the interner outlives any thread which uses this type, we can
/// safely treat `string` which points to interner data, as an immortal string,
/// as long as this type never crosses between threads.
//
1797 1798
// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
// by creating a new thread right after constructing the interner.
N
Nicholas Nethercote 已提交
1799
#[derive(Clone, Eq, PartialOrd, Ord)]
1800
pub struct SymbolStr {
J
Jeffrey Seyfried 已提交
1801
    string: &'static str,
1802 1803
}

1804 1805
// This impl allows a `SymbolStr` to be directly equated with a `String` or
// `&str`.
1806
impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1807 1808 1809 1810 1811
    fn eq(&self, other: &T) -> bool {
        self.string == other.deref()
    }
}

1812 1813
impl !Send for SymbolStr {}
impl !Sync for SymbolStr {}
J
Jeffrey Seyfried 已提交
1814

1815 1816
/// This impl means that if `ss` is a `SymbolStr`:
/// - `*ss` is a `str`;
1817
/// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1818 1819
/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
///   function expecting a `&str`.
1820
impl std::ops::Deref for SymbolStr {
1821
    type Target = str;
1822
    #[inline]
M
Mark Rousskov 已提交
1823 1824 1825
    fn deref(&self) -> &str {
        self.string
    }
1826 1827
}

1828
impl fmt::Debug for SymbolStr {
T
Taiki Endo 已提交
1829
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
J
Jeffrey Seyfried 已提交
1830
        fmt::Debug::fmt(self.string, f)
1831 1832 1833
    }
}

1834
impl fmt::Display for SymbolStr {
T
Taiki Endo 已提交
1835
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
J
Jeffrey Seyfried 已提交
1836
        fmt::Display::fmt(self.string, f)
1837 1838
    }
}
1839 1840 1841 1842

impl<CTX> HashStable<CTX> for SymbolStr {
    #[inline]
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
C
Camille GILLOT 已提交
1843
        self.string.hash_stable(hcx, hasher)
1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854
    }
}

impl<CTX> ToStableHashKey<CTX> for SymbolStr {
    type KeyType = SymbolStr;

    #[inline]
    fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
        self.clone()
    }
}