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

M
Matthew Jasper 已提交
1260
#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1261 1262
pub struct Ident {
    pub name: Symbol,
1263
    pub span: Span,
1264 1265 1266
}

impl Ident {
1267
    #[inline]
N
Nicholas Nethercote 已提交
1268
    /// Constructs a new identifier from a symbol and a span.
1269 1270 1271
    pub const fn new(name: Symbol, span: Span) -> Ident {
        Ident { name, span }
    }
1272

1273
    /// Constructs a new identifier with a dummy span.
1274
    #[inline]
1275
    pub const fn with_dummy_span(name: Symbol) -> Ident {
1276
        Ident::new(name, DUMMY_SP)
1277 1278
    }

1279 1280
    #[inline]
    pub fn invalid() -> Ident {
J
Joshua Nelson 已提交
1281
        Ident::with_dummy_span(kw::Empty)
1282 1283
    }

M
Matthew Jasper 已提交
1284
    /// Maps a string to an identifier with a dummy span.
1285
    pub fn from_str(string: &str) -> Ident {
1286
        Ident::with_dummy_span(Symbol::intern(string))
1287 1288
    }

N
Nicholas Nethercote 已提交
1289 1290 1291 1292 1293
    /// 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 已提交
1294
    /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
V
Vadim Petrochenkov 已提交
1295 1296 1297 1298 1299
    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 已提交
1300
        Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1301 1302
    }

V
Vadim Petrochenkov 已提交
1303
    /// "Normalize" ident for use in comparisons using "item hygiene".
1304
    /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1305
    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1306
    /// different macro 2.0 macros.
V
Vadim Petrochenkov 已提交
1307
    /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1308 1309
    pub fn normalize_to_macros_2_0(self) -> Ident {
        Ident::new(self.name, self.span.normalize_to_macros_2_0())
1310
    }
1311

V
Vadim Petrochenkov 已提交
1312 1313
    /// "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
1314
    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
V
Vadim Petrochenkov 已提交
1315 1316
    /// non-transparent macros.
    /// Technically, this operation strips all transparent marks from ident's syntactic context.
1317 1318
    pub fn normalize_to_macro_rules(self) -> Ident {
        Ident::new(self.name, self.span.normalize_to_macro_rules())
1319 1320
    }

1321 1322 1323
    /// 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 已提交
1324 1325
        self.name.as_str()
    }
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
}

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);
1338 1339 1340 1341
    }
}

impl fmt::Debug for Ident {
T
Taiki Endo 已提交
1342
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1343 1344
        fmt::Display::fmt(self, f)?;
        fmt::Debug::fmt(&self.span.ctxt(), f)
1345 1346 1347
    }
}

1348 1349 1350
/// 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.
1351
impl fmt::Display for Ident {
T
Taiki Endo 已提交
1352
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1353
        fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1354 1355 1356
    }
}

1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
/// 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 已提交
1395 1396 1397 1398 1399
        } 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("::")?;
1400
                }
J
Joshua Nelson 已提交
1401
                return fmt::Display::fmt(&converted, f);
1402 1403 1404 1405 1406 1407
            }
        }
        fmt::Display::fmt(&self.symbol, f)
    }
}

1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432
/// 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 已提交
1433
/// An interned string.
N
Nicholas Nethercote 已提交
1434
///
M
Matthew Jasper 已提交
1435
/// Internally, a `Symbol` is implemented as an index, and all operations
N
Nicholas Nethercote 已提交
1436
/// (including hashing, equality, and ordering) operate on that index. The use
1437 1438
/// 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.
1439
///
1440
/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
N
Nicholas Nethercote 已提交
1441
/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1442
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1443 1444
pub struct Symbol(SymbolIndex);

1445
rustc_index::newtype_index! {
1446 1447
    pub struct SymbolIndex { .. }
}
1448 1449

impl Symbol {
1450
    const fn new(n: u32) -> Self {
1451
        Symbol(SymbolIndex::from_u32(n))
1452 1453
    }

1454 1455 1456 1457 1458
    /// Maps a string to its interned representation.
    pub fn intern(string: &str) -> Self {
        with_interner(|interner| interner.intern(string))
    }

1459 1460 1461
    /// 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 已提交
1462
        with_interner(|interner| unsafe {
M
Mark Rousskov 已提交
1463
            SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
J
Jeffrey Seyfried 已提交
1464
        })
1465 1466 1467
    }

    pub fn as_u32(self) -> u32 {
1468
        self.0.as_u32()
1469
    }
1470

J
Joshua Nelson 已提交
1471
    pub fn is_empty(self) -> bool {
J
Joshua Nelson 已提交
1472
        self == kw::Empty
J
Joshua Nelson 已提交
1473 1474
    }

1475 1476 1477 1478 1479 1480 1481
    /// 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()
    }
1482 1483 1484
}

impl fmt::Debug for Symbol {
T
Taiki Endo 已提交
1485
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1486
        fmt::Debug::fmt(&self.as_str(), f)
1487 1488 1489 1490
    }
}

impl fmt::Display for Symbol {
T
Taiki Endo 已提交
1491
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1492
        fmt::Display::fmt(&self.as_str(), f)
1493 1494 1495
    }
}

M
Matthew Jasper 已提交
1496 1497
impl<S: Encoder> Encodable<S> for Symbol {
    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1498
        s.emit_str(&self.as_str())
1499 1500 1501
    }
}

M
Matthew Jasper 已提交
1502
impl<D: Decoder> Decodable<D> for Symbol {
1503
    #[inline]
M
Matthew Jasper 已提交
1504
    fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1505 1506 1507 1508
        Ok(Symbol::intern(&d.read_str()?))
    }
}

1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
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()
    }
}

1525
// The `&'static str`s in this type actually point into the arena.
1526 1527 1528 1529
//
// 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`.
1530
#[derive(Default)]
1531
pub struct Interner {
1532 1533 1534
    arena: DroplessArena,
    names: FxHashMap<&'static str, Symbol>,
    strings: Vec<&'static str>,
1535 1536 1537
}

impl Interner {
1538 1539
    fn prefill(init: &[&'static str]) -> Self {
        Interner {
1540 1541
            strings: init.into(),
            names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1542
            ..Default::default()
1543 1544 1545
        }
    }

1546
    #[inline]
1547 1548 1549 1550 1551
    pub fn intern(&mut self, string: &str) -> Symbol {
        if let Some(&name) = self.names.get(string) {
            return name;
        }

1552
        let name = Symbol::new(self.strings.len() as u32);
1553

1554 1555
        // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
        // UTF-8.
M
Mark Rousskov 已提交
1556 1557
        let string: &str =
            unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1558 1559
        // It is safe to extend the arena allocation to `'static` because we only access
        // these while the arena is still alive.
M
Mark Rousskov 已提交
1560
        let string: &'static str = unsafe { &*(string as *const str) };
1561
        self.strings.push(string);
1562 1563 1564
        self.names.insert(string, name);
        name
    }
1565

N
Nicholas Nethercote 已提交
1566 1567
    // Get the symbol as a string. `Symbol::as_str()` should be used in
    // preference to this function.
J
Jeffrey Seyfried 已提交
1568
    pub fn get(&self, symbol: Symbol) -> &str {
M
Matthew Jasper 已提交
1569
        self.strings[symbol.0.as_usize()]
1570 1571 1572
    }
}

1573
// This module has a very short name because it's used a lot.
1574 1575 1576 1577
/// 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`.
1578
pub mod kw {
1579
    pub use super::kw_generated::*;
1580 1581
}

1582
// This module has a very short name because it's used a lot.
1583 1584 1585 1586
/// 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`.
1587
pub mod sym {
1588
    use super::Symbol;
M
Mark Rousskov 已提交
1589
    use std::convert::TryInto;
1590

1591
    pub use super::sym_generated::*;
1592 1593 1594

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

1596 1597 1598 1599
    /// Get the symbol for an integer.
    ///
    /// The first few non-negative integers each have a static symbol and therefore
    /// are fast.
1600 1601
    pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
        if let Result::Ok(idx) = n.try_into() {
1602 1603
            if idx < 10 {
                return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1604 1605 1606 1607
            }
        }
        Symbol::intern(&n.to_string())
    }
1608 1609
}

1610
impl Symbol {
1611 1612
    fn is_special(self) -> bool {
        self <= kw::Underscore
1613 1614
    }

1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
    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)
1637
    }
1638

1639 1640
    /// A keyword or reserved identifier that can be used as a path segment.
    pub fn is_path_segment_keyword(self) -> bool {
M
Mark Rousskov 已提交
1641 1642 1643 1644 1645 1646
        self == kw::Super
            || self == kw::SelfLower
            || self == kw::SelfUpper
            || self == kw::Crate
            || self == kw::PathRoot
            || self == kw::DollarCrate
1647 1648
    }

1649 1650 1651 1652 1653
    /// Returns `true` if the symbol is `true` or `false`.
    pub fn is_bool_lit(self) -> bool {
        self == kw::True || self == kw::False
    }

1654
    /// Returns `true` if this symbol can be a raw identifier.
1655
    pub fn can_be_raw(self) -> bool {
J
Joshua Nelson 已提交
1656
        self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1657
    }
1658 1659 1660
}

impl Ident {
1661
    // Returns `true` for reserved identifiers used internally for elided lifetimes,
1662 1663
    // unnamed method parameters, crate root module, error recovery etc.
    pub fn is_special(self) -> bool {
1664
        self.name.is_special()
1665 1666 1667 1668
    }

    /// Returns `true` if the token is a keyword used in the language.
    pub fn is_used_keyword(self) -> bool {
1669
        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1670 1671
        self.name.is_used_keyword_always()
            || self.name.is_used_keyword_conditional(|| self.span.edition())
1672 1673 1674 1675 1676
    }

    /// 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.
1677 1678
        self.name.is_unused_keyword_always()
            || self.name.is_unused_keyword_conditional(|| self.span.edition())
1679 1680 1681 1682
    }

    /// Returns `true` if the token is either a special identifier or a keyword.
    pub fn is_reserved(self) -> bool {
1683 1684
        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
        self.name.is_reserved(|| self.span.edition())
1685 1686 1687 1688
    }

    /// A keyword or reserved identifier that can be used as a path segment.
    pub fn is_path_segment_keyword(self) -> bool {
1689
        self.name.is_path_segment_keyword()
1690 1691 1692 1693 1694
    }

    /// 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 {
1695
        self.name.can_be_raw() && self.is_reserved()
1696 1697 1698
    }
}

1699
#[inline]
1700
fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1701
    SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
1702 1703
}

1704
/// An alternative to [`Symbol`], useful when the chars within the symbol need to
N
Nicholas Nethercote 已提交
1705 1706
/// be accessed. It deliberately has limited functionality and should only be
/// used for temporary values.
N
Nicholas Nethercote 已提交
1707 1708 1709 1710 1711
///
/// 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.
//
1712 1713
// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
// by creating a new thread right after constructing the interner.
N
Nicholas Nethercote 已提交
1714
#[derive(Clone, Eq, PartialOrd, Ord)]
1715
pub struct SymbolStr {
J
Jeffrey Seyfried 已提交
1716
    string: &'static str,
1717 1718
}

1719 1720
// This impl allows a `SymbolStr` to be directly equated with a `String` or
// `&str`.
1721
impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1722 1723 1724 1725 1726
    fn eq(&self, other: &T) -> bool {
        self.string == other.deref()
    }
}

1727 1728
impl !Send for SymbolStr {}
impl !Sync for SymbolStr {}
J
Jeffrey Seyfried 已提交
1729

1730 1731
/// This impl means that if `ss` is a `SymbolStr`:
/// - `*ss` is a `str`;
1732
/// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1733 1734
/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
///   function expecting a `&str`.
1735
impl std::ops::Deref for SymbolStr {
1736
    type Target = str;
1737
    #[inline]
M
Mark Rousskov 已提交
1738 1739 1740
    fn deref(&self) -> &str {
        self.string
    }
1741 1742
}

1743
impl fmt::Debug for SymbolStr {
T
Taiki Endo 已提交
1744
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
J
Jeffrey Seyfried 已提交
1745
        fmt::Debug::fmt(self.string, f)
1746 1747 1748
    }
}

1749
impl fmt::Display for SymbolStr {
T
Taiki Endo 已提交
1750
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
J
Jeffrey Seyfried 已提交
1751
        fmt::Display::fmt(self.string, f)
1752 1753
    }
}
1754 1755 1756 1757

impl<CTX> HashStable<CTX> for SymbolStr {
    #[inline]
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
C
Camille GILLOT 已提交
1758
        self.string.hash_stable(hcx, hasher)
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769
    }
}

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

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