Files
cargo_fmt
coverage_test_macros
git_rustfmt
rustc_apfloat
rustc_arena
rustc_ast
rustc_ast_lowering
rustc_ast_passes
rustc_ast_pretty
rustc_attr
rustc_borrowck
rustc_builtin_macros
rustc_codegen_llvm
rustc_codegen_ssa
rustc_const_eval
rustc_data_structures
rustc_driver
rustc_error_codes
rustc_errors
rustc_expand
rustc_feature
rustc_fs_util
rustc_graphviz
rustc_hir
rustc_hir_pretty
rustc_incremental
rustc_index
rustc_infer
rustc_interface
rustc_lexer
rustc_lint
rustc_lint_defs
rustc_llvm
rustc_macros
rustc_metadata
rustc_middle
rustc_mir_build
rustc_mir_dataflow
rustc_mir_transform
rustc_monomorphize
rustc_parse
rustc_parse_format
rustc_passes
rustc_plugin_impl
rustc_privacy
rustc_query_impl
rustc_query_system
rustc_resolve
rustc_save_analysis
rustc_serialize
rustc_session
rustc_span
rustc_symbol_mangling
rustc_target
abi
asm
spec
aarch64_apple_darwin.rsaarch64_apple_ios.rsaarch64_apple_ios_macabi.rsaarch64_apple_ios_sim.rsaarch64_apple_tvos.rsaarch64_be_unknown_linux_gnu.rsaarch64_be_unknown_linux_gnu_ilp32.rsaarch64_fuchsia.rsaarch64_kmc_solid_asp3.rsaarch64_linux_android.rsaarch64_pc_windows_msvc.rsaarch64_unknown_freebsd.rsaarch64_unknown_hermit.rsaarch64_unknown_linux_gnu.rsaarch64_unknown_linux_gnu_ilp32.rsaarch64_unknown_linux_musl.rsaarch64_unknown_netbsd.rsaarch64_unknown_none.rsaarch64_unknown_none_softfloat.rsaarch64_unknown_openbsd.rsaarch64_unknown_redox.rsaarch64_unknown_uefi.rsaarch64_uwp_windows_msvc.rsaarch64_wrs_vxworks.rsabi.rsandroid_base.rsapple_base.rsapple_sdk_base.rsarm_linux_androideabi.rsarm_unknown_linux_gnueabi.rsarm_unknown_linux_gnueabihf.rsarm_unknown_linux_musleabi.rsarm_unknown_linux_musleabihf.rsarmebv7r_none_eabi.rsarmebv7r_none_eabihf.rsarmv4t_unknown_linux_gnueabi.rsarmv5te_unknown_linux_gnueabi.rsarmv5te_unknown_linux_musleabi.rsarmv5te_unknown_linux_uclibceabi.rsarmv6_unknown_freebsd.rsarmv6_unknown_netbsd_eabihf.rsarmv6k_nintendo_3ds.rsarmv7_apple_ios.rsarmv7_linux_androideabi.rsarmv7_unknown_freebsd.rsarmv7_unknown_linux_gnueabi.rsarmv7_unknown_linux_gnueabihf.rsarmv7_unknown_linux_musleabi.rsarmv7_unknown_linux_musleabihf.rsarmv7_unknown_linux_uclibceabihf.rsarmv7_unknown_netbsd_eabihf.rsarmv7_wrs_vxworks_eabihf.rsarmv7a_kmc_solid_asp3_eabi.rsarmv7a_kmc_solid_asp3_eabihf.rsarmv7a_none_eabi.rsarmv7a_none_eabihf.rsarmv7r_none_eabi.rsarmv7r_none_eabihf.rsarmv7s_apple_ios.rsasmjs_unknown_emscripten.rsavr_gnu_base.rsavr_unknown_gnu_atmega328.rsbpf_base.rsbpfeb_unknown_none.rsbpfel_unknown_none.rscrt_objects.rsdragonfly_base.rsfreebsd_base.rsfuchsia_base.rshaiku_base.rshermit_base.rshermit_kernel_base.rshexagon_unknown_linux_musl.rsi386_apple_ios.rsi586_pc_windows_msvc.rsi586_unknown_linux_gnu.rsi586_unknown_linux_musl.rsi686_apple_darwin.rsi686_linux_android.rsi686_pc_windows_gnu.rsi686_pc_windows_msvc.rsi686_unknown_freebsd.rsi686_unknown_haiku.rsi686_unknown_linux_gnu.rsi686_unknown_linux_musl.rsi686_unknown_netbsd.rsi686_unknown_openbsd.rsi686_unknown_uefi.rsi686_uwp_windows_gnu.rsi686_uwp_windows_msvc.rsi686_wrs_vxworks.rsillumos_base.rsl4re_base.rslinux_base.rslinux_gnu_base.rslinux_kernel_base.rslinux_musl_base.rslinux_uclibc_base.rsm68k_unknown_linux_gnu.rsmips64_unknown_linux_gnuabi64.rsmips64_unknown_linux_muslabi64.rsmips64el_unknown_linux_gnuabi64.rsmips64el_unknown_linux_muslabi64.rsmips_unknown_linux_gnu.rsmips_unknown_linux_musl.rsmips_unknown_linux_uclibc.rsmipsel_sony_psp.rsmipsel_unknown_linux_gnu.rsmipsel_unknown_linux_musl.rsmipsel_unknown_linux_uclibc.rsmipsel_unknown_none.rsmipsisa32r6_unknown_linux_gnu.rsmipsisa32r6el_unknown_linux_gnu.rsmipsisa64r6_unknown_linux_gnuabi64.rsmipsisa64r6el_unknown_linux_gnuabi64.rsmod.rsmsp430_none_elf.rsmsvc_base.rsnetbsd_base.rsnvptx64_nvidia_cuda.rsopenbsd_base.rspowerpc64_unknown_freebsd.rspowerpc64_unknown_linux_gnu.rspowerpc64_unknown_linux_musl.rspowerpc64_wrs_vxworks.rspowerpc64le_unknown_freebsd.rspowerpc64le_unknown_linux_gnu.rspowerpc64le_unknown_linux_musl.rspowerpc_unknown_freebsd.rspowerpc_unknown_linux_gnu.rspowerpc_unknown_linux_gnuspe.rspowerpc_unknown_linux_musl.rspowerpc_unknown_netbsd.rspowerpc_unknown_openbsd.rspowerpc_wrs_vxworks.rspowerpc_wrs_vxworks_spe.rsredox_base.rsriscv32gc_unknown_linux_gnu.rsriscv32gc_unknown_linux_musl.rsriscv32i_unknown_none_elf.rsriscv32imac_unknown_none_elf.rsriscv32imc_esp_espidf.rsriscv32imc_unknown_none_elf.rsriscv64gc_unknown_linux_gnu.rsriscv64gc_unknown_linux_musl.rsriscv64gc_unknown_none_elf.rsriscv64imac_unknown_none_elf.rss390x_unknown_linux_gnu.rss390x_unknown_linux_musl.rssolaris_base.rssolid_base.rssparc64_unknown_linux_gnu.rssparc64_unknown_netbsd.rssparc64_unknown_openbsd.rssparc_unknown_linux_gnu.rssparcv9_sun_solaris.rsthumb_base.rsthumbv4t_none_eabi.rsthumbv6m_none_eabi.rsthumbv7a_pc_windows_msvc.rsthumbv7a_uwp_windows_msvc.rsthumbv7em_none_eabi.rsthumbv7em_none_eabihf.rsthumbv7m_none_eabi.rsthumbv7neon_linux_androideabi.rsthumbv7neon_unknown_linux_gnueabihf.rsthumbv7neon_unknown_linux_musleabihf.rsthumbv8m_base_none_eabi.rsthumbv8m_main_none_eabi.rsthumbv8m_main_none_eabihf.rsuefi_msvc_base.rsvxworks_base.rswasm32_unknown_emscripten.rswasm32_unknown_unknown.rswasm32_wasi.rswasm64_unknown_unknown.rswasm_base.rswindows_gnu_base.rswindows_msvc_base.rswindows_uwp_gnu_base.rswindows_uwp_msvc_base.rsx86_64_apple_darwin.rsx86_64_apple_ios.rsx86_64_apple_ios_macabi.rsx86_64_apple_tvos.rsx86_64_fortanix_unknown_sgx.rsx86_64_fuchsia.rsx86_64_linux_android.rsx86_64_pc_solaris.rsx86_64_pc_windows_gnu.rsx86_64_pc_windows_msvc.rsx86_64_sun_solaris.rsx86_64_unknown_dragonfly.rsx86_64_unknown_freebsd.rsx86_64_unknown_haiku.rsx86_64_unknown_hermit.rsx86_64_unknown_illumos.rsx86_64_unknown_l4re_uclibc.rsx86_64_unknown_linux_gnu.rsx86_64_unknown_linux_gnux32.rsx86_64_unknown_linux_musl.rsx86_64_unknown_netbsd.rsx86_64_unknown_none_hermitkernel.rsx86_64_unknown_none_linuxkernel.rsx86_64_unknown_openbsd.rsx86_64_unknown_redox.rsx86_64_unknown_uefi.rsx86_64_uwp_windows_gnu.rsx86_64_uwp_windows_msvc.rsx86_64_wrs_vxworks.rs
rustc_trait_selection
rustc_traits
rustc_ty_utils
rustc_type_ir
rustc_typeck
rustdoc
rustdoc_json_types
rustfmt
rustfmt_format_diff
rustfmt_nightly
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 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
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
use crate::ty::subst::SubstsRef;
use crate::ty::{self, Ty, TyCtxt};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_macros::HashStable;
use rustc_span::Span;

#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum PointerCast {
    /// Go from a fn-item type to a fn-pointer type.
    ReifyFnPointer,

    /// Go from a safe fn pointer to an unsafe fn pointer.
    UnsafeFnPointer,

    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
    /// It cannot convert a closure that requires unsafe.
    ClosureFnPointer(hir::Unsafety),

    /// Go from a mut raw pointer to a const raw pointer.
    MutToConstPointer,

    /// Go from `*const [T; N]` to `*const T`
    ArrayToPointer,

    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
    /// `&[T]`. Note that the source could be a thin or fat pointer.
    /// This will do things like convert thin pointers to fat
    /// pointers, or convert structs containing thin pointers to
    /// structs containing fat pointers, or convert between fat
    /// pointers. We don't store the details of how the transform is
    /// done (in fact, we don't know that, because it might depend on
    /// the precise type parameters). We just store the target
    /// type. Codegen backends and miri figure out what has to be done
    /// based on the precise source/target type at hand.
    Unsize,
}

/// Represents coercing a value to a different type of value.
///
/// We transform values by following a number of `Adjust` steps in order.
/// See the documentation on variants of `Adjust` for more details.
///
/// Here are some common scenarios:
///
/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
///    Here the pointer will be dereferenced N times (where a dereference can
///    happen to raw or borrowed pointers or any smart pointer which implements
///    `Deref`, including `Box<_>`). The types of dereferences is given by
///    `autoderefs`. It can then be auto-referenced zero or one times, indicated
///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
///    `false`.
///
/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
///    with a thin pointer, deref a number of times, unsize the underlying data,
///    then autoref. The 'unsize' phase may change a fixed length array to a
///    dynamically sized one, a concrete object to a trait object, or statically
///    sized struct to a dynamically sized one. E.g., `&[i32; 4]` -> `&[i32]` is
///    represented by:
///
///    ```
///    Deref(None) -> [i32; 4],
///    Borrow(AutoBorrow::Ref) -> &[i32; 4],
///    Unsize -> &[i32],
///    ```
///
///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.
///    E.g., `struct Foo<T> { x: T }` we can coerce `&Foo<[i32; 4]>` to `&Foo<[i32]>`
///    The autoderef and -ref are the same as in the above example, but the type
///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
///    the underlying conversions from `[i32; 4]` to `[i32]`.
///
/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
///    that case, we have the pointer we need coming in, so there are no
///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
///    At some point, of course, `Box` should move out of the compiler, in which
///    case this is analogous to transforming a struct. E.g., `Box<[i32; 4]>` ->
///    `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`.
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub struct Adjustment<'tcx> {
    pub kind: Adjust<'tcx>,
    pub target: Ty<'tcx>,
}

impl Adjustment<'tcx> {
    pub fn is_region_borrow(&self) -> bool {
        matches!(self.kind, Adjust::Borrow(AutoBorrow::Ref(..)))
    }
}

#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub enum Adjust<'tcx> {
    /// Go from ! to any type.
    NeverToAny,

    /// Dereference once, producing a place.
    Deref(Option<OverloadedDeref<'tcx>>),

    /// Take the address and produce either a `&` or `*` pointer.
    Borrow(AutoBorrow<'tcx>),

    Pointer(PointerCast),
}

/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
/// The target type is `U` in both cases, with the region and mutability
/// being those shared by both the receiver and the returned reference.
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub struct OverloadedDeref<'tcx> {
    pub region: ty::Region<'tcx>,
    pub mutbl: hir::Mutability,
    /// The `Span` associated with the field access or method call
    /// that triggered this overloaded deref.
    pub span: Span,
}

impl<'tcx> OverloadedDeref<'tcx> {
    pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) {
        let trait_def_id = match self.mutbl {
            hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None),
            hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None),
        };
        let method_def_id = tcx
            .associated_items(trait_def_id)
            .in_definition_order()
            .find(|m| m.kind == ty::AssocKind::Fn)
            .unwrap()
            .def_id;
        (method_def_id, tcx.mk_substs_trait(source, &[]))
    }
}

/// At least for initial deployment, we want to limit two-phase borrows to
/// only a few specific cases. Right now, those are mostly "things that desugar"
/// into method calls:
/// - using `x.some_method()` syntax, where some_method takes `&mut self`,
/// - using `Foo::some_method(&mut x, ...)` syntax,
/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).
/// Anything else should be rejected until generalized two-phase borrow support
/// is implemented. Right now, dataflow can't handle the general case where there
/// is more than one use of a mutable borrow, and we don't want to accept too much
/// new code via two-phase borrows, so we try to limit where we create two-phase
/// capable mutable borrows.
/// See #49434 for tracking.
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum AllowTwoPhase {
    Yes,
    No,
}

#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum AutoBorrowMutability {
    Mut { allow_two_phase_borrow: AllowTwoPhase },
    Not,
}

impl From<AutoBorrowMutability> for hir::Mutability {
    fn from(m: AutoBorrowMutability) -> Self {
        match m {
            AutoBorrowMutability::Mut { .. } => hir::Mutability::Mut,
            AutoBorrowMutability::Not => hir::Mutability::Not,
        }
    }
}

#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub enum AutoBorrow<'tcx> {
    /// Converts from T to &T.
    Ref(ty::Region<'tcx>, AutoBorrowMutability),

    /// Converts from T to *T.
    RawPtr(hir::Mutability),
}

/// Information for `CoerceUnsized` impls, storing information we
/// have computed about the coercion.
///
/// This struct can be obtained via the `coerce_impl_info` query.
/// Demanding this struct also has the side-effect of reporting errors
/// for inappropriate impls.
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
pub struct CoerceUnsizedInfo {
    /// If this is a "custom coerce" impl, then what kind of custom
    /// coercion is it? This applies to impls of `CoerceUnsized` for
    /// structs, primarily, where we store a bit of info about which
    /// fields need to be coerced.
    pub custom_kind: Option<CustomCoerceUnsized>,
}

#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum CustomCoerceUnsized {
    /// Records the index of the field being coerced.
    Struct(usize),
}