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
//! Some helper functions for `AutoDeref`
use super::method::MethodCallee;
use super::{FnCtxt, PlaceOp};

use rustc_infer::infer::InferOk;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
use rustc_trait_selection::autoderef::{Autoderef, AutoderefKind};

use std::iter;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> {
        Autoderef::new(self, self.param_env, self.body_id, span, base_ty, span)
    }

    /// Like `autoderef`, but provides a custom `Span` to use for calls to
    /// an overloaded `Deref` operator
    pub fn autoderef_overloaded_span(
        &'a self,
        span: Span,
        base_ty: Ty<'tcx>,
        overloaded_span: Span,
    ) -> Autoderef<'a, 'tcx> {
        Autoderef::new(self, self.param_env, self.body_id, span, base_ty, overloaded_span)
    }

    pub fn try_overloaded_deref(
        &self,
        span: Span,
        base_ty: Ty<'tcx>,
    ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        self.try_overloaded_place_op(span, base_ty, &[], PlaceOp::Deref)
    }

    /// Returns the adjustment steps.
    pub fn adjust_steps(&self, autoderef: &Autoderef<'a, 'tcx>) -> Vec<Adjustment<'tcx>> {
        self.register_infer_ok_obligations(self.adjust_steps_as_infer_ok(autoderef))
    }

    pub fn adjust_steps_as_infer_ok(
        &self,
        autoderef: &Autoderef<'a, 'tcx>,
    ) -> InferOk<'tcx, Vec<Adjustment<'tcx>>> {
        let mut obligations = vec![];
        let steps = autoderef.steps();
        let targets =
            steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(autoderef.final_ty(false)));
        let steps: Vec<_> = steps
            .iter()
            .map(|&(source, kind)| {
                if let AutoderefKind::Overloaded = kind {
                    self.try_overloaded_deref(autoderef.span(), source).and_then(
                        |InferOk { value: method, obligations: o }| {
                            obligations.extend(o);
                            if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
                                Some(OverloadedDeref {
                                    region,
                                    mutbl,
                                    span: autoderef.overloaded_span(),
                                })
                            } else {
                                None
                            }
                        },
                    )
                } else {
                    None
                }
            })
            .zip(targets)
            .map(|(autoderef, target)| Adjustment { kind: Adjust::Deref(autoderef), target })
            .collect();

        InferOk { obligations, value: steps }
    }
}