Skip to main content

rustc_hir_typeck/
callee.rs

1use std::iter;
2
3use rustc_abi::{CanonAbi, ExternAbi};
4use rustc_ast::util::parser::ExprPrecedence;
5use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey, msg};
6use rustc_hir::def::{self, CtorKind, Namespace, Res};
7use rustc_hir::def_id::DefId;
8use rustc_hir::{self as hir, HirId, LangItem, find_attr};
9use rustc_hir_analysis::autoderef::Autoderef;
10use rustc_infer::infer::BoundRegionConversionTime;
11use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode};
12use rustc_middle::ty::adjustment::{
13    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
14};
15use rustc_middle::ty::{self, FnSig, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
16use rustc_middle::{bug, span_bug};
17use rustc_span::def_id::LocalDefId;
18use rustc_span::{Ident, Span, sym};
19use rustc_target::spec::{AbiMap, AbiMapping};
20use rustc_trait_selection::error_reporting::traits::DefIdOrName;
21use rustc_trait_selection::infer::InferCtxtExt as _;
22use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
23use tracing::{debug, instrument};
24
25use super::method::MethodCallee;
26use super::method::probe::ProbeScope;
27use super::{Expectation, FnCtxt, TupleArgumentsFlag};
28use crate::diagnostics;
29use crate::method::TreatNotYetDefinedOpaques;
30use crate::method::confirm::ConfirmContext;
31use crate::method::probe::{IsSuggestion, Mode};
32
33/// Checks that it is legal to call methods of the trait corresponding
34/// to `trait_id` (this only cares about the trait, not the specific
35/// method that is called).
36pub(crate) fn check_legal_trait_for_method_call(
37    tcx: TyCtxt<'_>,
38    span: Span,
39    receiver: Option<Span>,
40    expr_span: Span,
41    trait_id: DefId,
42    body_id: DefId,
43) -> Result<(), ErrorGuaranteed> {
44    if tcx.is_lang_item(trait_id, LangItem::Drop)
45        // Allow calling `Drop::pin_drop` in `Drop::drop`
46        && !tcx.is_lang_item(tcx.parent(body_id), LangItem::Drop)
47    {
48        let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
49            diagnostics::ExplicitDestructorCallSugg::Snippet {
50                lo: expr_span.shrink_to_lo().to(receiver.shrink_to_lo()),
51                hi: receiver.shrink_to_hi().to(expr_span.shrink_to_hi()),
52            }
53        } else {
54            diagnostics::ExplicitDestructorCallSugg::Empty(span)
55        };
56        return Err(tcx.dcx().emit_err(diagnostics::ExplicitDestructorCall { span, sugg }));
57    }
58    tcx.ensure_result().coherent_trait(trait_id)
59}
60
61/// State machine for typechecking a call, based on the callee type.
62#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for CallStep<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            CallStep::Builtin(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Builtin", &__self_0),
            CallStep::DeferredClosure(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "DeferredClosure", __self_0, &__self_1),
            CallStep::Overloaded(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Overloaded", &__self_0),
        }
    }
}Debug)]
63enum CallStep<'tcx> {
64    /// Typecheck a call to a function definition or pointer.
65    /// Includes functions with splatted arguments.
66    Builtin(Ty<'tcx>),
67    /// Deferred closure Fn* trait typechecking, when the callee is a closure.
68    DeferredClosure(LocalDefId, ty::FnSig<'tcx>),
69    /// Call overloading when callee implements one of the Fn* traits.
70    Overloaded(MethodCallee<'tcx>),
71}
72
73impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
74    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
                ::tracing::Level::INFO <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("check_expr_call",
                                    "rustc_hir_typeck::callee", ::tracing::Level::INFO,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/callee.rs"),
                                    ::tracing_core::__macro_support::Option::Some(74u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::callee"),
                                    ::tracing_core::field::FieldSet::new(&["call_expr",
                                                    "callee_expr", "arg_exprs", "expected"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::INFO <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::INFO <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&call_expr)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&callee_expr)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&arg_exprs)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expected)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Ty<'tcx> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let original_callee_ty =
                match &callee_expr.kind {
                    hir::ExprKind::Path(hir::QPath::Resolved(..) |
                        hir::QPath::TypeRelative(..)) =>
                        self.check_expr_with_expectation_and_args(callee_expr,
                            Expectation::NoExpectation, Some((call_expr, arg_exprs))),
                    _ => self.check_expr(callee_expr),
                };
            let expr_ty =
                self.resolve_vars_with_obligations(original_callee_ty);
            let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
            let mut result = None;
            while result.is_none() && autoderef.next().is_some() {
                result =
                    self.try_overloaded_call_step(call_expr, callee_expr,
                        arg_exprs, &autoderef);
            }
            match *autoderef.final_ty().kind() {
                ty::FnDef(def_id, _) => {
                    let abi =
                        self.tcx.fn_sig(def_id).skip_binder().skip_binder().abi();
                    self.check_call_abi(abi, call_expr.span);
                }
                ty::FnPtr(_, header) => {
                    self.check_call_abi(header.abi(), call_expr.span);
                }
                _ => {}
            }
            if self.is_scalable_vector_ctor(autoderef.final_ty()) {
                let mut err =
                    self.dcx().create_err(diagnostics::ScalableVectorCtor {
                            span: callee_expr.span,
                            ty: autoderef.final_ty(),
                        });
                err.span_label(callee_expr.span,
                    "you can create scalable vectors using intrinsics");
                Ty::new_error(self.tcx, err.emit());
            }
            self.register_predicates(autoderef.into_obligations());
            let output =
                match result {
                    None => {
                        for arg in arg_exprs { self.check_expr(arg); }
                        if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) =
                                    &callee_expr.kind && let [segment] = path.segments {
                            self.dcx().try_steal_modify_and_emit_err(segment.ident.span,
                                StashKey::CallIntoMethod,
                                |err|
                                    {
                                        self.suggest_call_as_method(err, segment, arg_exprs,
                                            call_expr, expected);
                                    });
                        }
                        let guar =
                            self.report_invalid_callee(call_expr, callee_expr, expr_ty,
                                arg_exprs);
                        Ty::new_error(self.tcx, guar)
                    }
                    Some(CallStep::Builtin(callee_ty)) => {
                        self.confirm_builtin_call(call_expr, callee_expr, callee_ty,
                            arg_exprs, expected)
                    }
                    Some(CallStep::DeferredClosure(def_id, fn_sig)) => {
                        self.confirm_deferred_closure_call(call_expr, arg_exprs,
                            expected, def_id, fn_sig)
                    }
                    Some(CallStep::Overloaded(method_callee)) => {
                        self.confirm_overloaded_call(call_expr, arg_exprs, expected,
                            method_callee)
                    }
                };
            self.register_wf_obligation(output.into(), call_expr.span,
                ObligationCauseCode::WellFormed(None));
            output
        }
    }
}#[tracing::instrument(skip(self))]
75    pub(crate) fn check_expr_call(
76        &self,
77        call_expr: &'tcx hir::Expr<'tcx>,
78        callee_expr: &'tcx hir::Expr<'tcx>,
79        arg_exprs: &'tcx [hir::Expr<'tcx>],
80        expected: Expectation<'tcx>,
81    ) -> Ty<'tcx> {
82        let original_callee_ty = match &callee_expr.kind {
83            hir::ExprKind::Path(hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)) => self
84                .check_expr_with_expectation_and_args(
85                    callee_expr,
86                    Expectation::NoExpectation,
87                    Some((call_expr, arg_exprs)),
88                ),
89            _ => self.check_expr(callee_expr),
90        };
91
92        let expr_ty = self.resolve_vars_with_obligations(original_callee_ty);
93
94        let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
95        let mut result = None;
96        while result.is_none() && autoderef.next().is_some() {
97            result = self.try_overloaded_call_step(call_expr, callee_expr, arg_exprs, &autoderef);
98        }
99
100        match *autoderef.final_ty().kind() {
101            ty::FnDef(def_id, _) => {
102                let abi = self.tcx.fn_sig(def_id).skip_binder().skip_binder().abi();
103                self.check_call_abi(abi, call_expr.span);
104            }
105            ty::FnPtr(_, header) => {
106                self.check_call_abi(header.abi(), call_expr.span);
107            }
108            _ => { /* cannot have a non-rust abi */ }
109        }
110
111        if self.is_scalable_vector_ctor(autoderef.final_ty()) {
112            let mut err = self.dcx().create_err(diagnostics::ScalableVectorCtor {
113                span: callee_expr.span,
114                ty: autoderef.final_ty(),
115            });
116            err.span_label(callee_expr.span, "you can create scalable vectors using intrinsics");
117            Ty::new_error(self.tcx, err.emit());
118        }
119
120        self.register_predicates(autoderef.into_obligations());
121
122        let output = match result {
123            None => {
124                // Check all of the arg expressions, but with no expectations
125                // since we don't have a signature to compare them to.
126                for arg in arg_exprs {
127                    self.check_expr(arg);
128                }
129
130                if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &callee_expr.kind
131                    && let [segment] = path.segments
132                {
133                    self.dcx().try_steal_modify_and_emit_err(
134                        segment.ident.span,
135                        StashKey::CallIntoMethod,
136                        |err| {
137                            // Try suggesting `foo(a)` -> `a.foo()` if possible.
138                            self.suggest_call_as_method(
139                                err, segment, arg_exprs, call_expr, expected,
140                            );
141                        },
142                    );
143                }
144
145                let guar = self.report_invalid_callee(call_expr, callee_expr, expr_ty, arg_exprs);
146                Ty::new_error(self.tcx, guar)
147            }
148
149            Some(CallStep::Builtin(callee_ty)) => {
150                self.confirm_builtin_call(call_expr, callee_expr, callee_ty, arg_exprs, expected)
151            }
152
153            Some(CallStep::DeferredClosure(def_id, fn_sig)) => {
154                self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, def_id, fn_sig)
155            }
156
157            Some(CallStep::Overloaded(method_callee)) => {
158                self.confirm_overloaded_call(call_expr, arg_exprs, expected, method_callee)
159            }
160        };
161
162        // we must check that return type of called functions is WF:
163        self.register_wf_obligation(
164            output.into(),
165            call_expr.span,
166            ObligationCauseCode::WellFormed(None),
167        );
168
169        output
170    }
171
172    /// Can a function with this ABI be called with a rust call expression?
173    ///
174    /// Some ABIs cannot be called from rust, either because rust does not know how to generate
175    /// code for the call, or because a call does not semantically make sense.
176    pub(crate) fn check_call_abi(&self, abi: ExternAbi, span: Span) {
177        let canon_abi = match AbiMap::from_target(&self.sess().target).canonize_abi(abi, false) {
178            AbiMapping::Direct(canon_abi) | AbiMapping::Deprecated(canon_abi) => canon_abi,
179            AbiMapping::Invalid => {
180                // This should be reported elsewhere, but we want to taint this body
181                // so that we don't try to evaluate calls to ABIs that are invalid.
182                let guar = self.dcx().span_delayed_bug(
183                    span,
184                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid abi for platform should have reported an error: {0}",
                abi))
    })format!("invalid abi for platform should have reported an error: {abi}"),
185                );
186                self.set_tainted_by_errors(guar);
187                return;
188            }
189        };
190
191        match canon_abi {
192            // Rust doesn't know how to call functions with this ABI.
193            CanonAbi::Custom
194            // The interrupt ABIs should only be called by the CPU. They have complex
195            // pre- and postconditions, and can use non-standard instructions like `iret` on x86.
196            | CanonAbi::Interrupt(_) => {
197                let err = crate::diagnostics::AbiCannotBeCalled { span, abi };
198                self.tcx.dcx().emit_err(err);
199            }
200
201            // This is an entry point for the host, and cannot be called directly.
202            CanonAbi::GpuKernel => {
203                let err = crate::diagnostics::GpuKernelAbiCannotBeCalled { span };
204                self.tcx.dcx().emit_err(err);
205            }
206
207            CanonAbi::C
208            | CanonAbi::Rust
209            | CanonAbi::RustCold
210            | CanonAbi::RustPreserveNone
211            | CanonAbi::RustTail
212            | CanonAbi::Swift
213            | CanonAbi::Arm(_)
214            | CanonAbi::X86(_) => {}
215        }
216    }
217
218    x;#[instrument(level = "debug", skip(self, call_expr, callee_expr, arg_exprs, autoderef), ret)]
219    fn try_overloaded_call_step(
220        &self,
221        call_expr: &'tcx hir::Expr<'tcx>,
222        callee_expr: &'tcx hir::Expr<'tcx>,
223        arg_exprs: &'tcx [hir::Expr<'tcx>],
224        autoderef: &Autoderef<'a, 'tcx>,
225    ) -> Option<CallStep<'tcx>> {
226        let adjusted_ty = self.resolve_vars_with_obligations(autoderef.final_ty());
227
228        // If the callee is a function pointer or a closure, then we're all set.
229        match *adjusted_ty.kind() {
230            ty::FnDef(..) | ty::FnPtr(..) => {
231                let adjustments = self.adjust_steps(autoderef);
232                self.apply_adjustments(callee_expr, adjustments);
233                return Some(CallStep::Builtin(adjusted_ty));
234            }
235
236            // Check whether this is a call to a closure where we
237            // haven't yet decided on whether the closure is fn vs
238            // fnmut vs fnonce. If so, we have to defer further processing.
239            ty::Closure(def_id, args) if self.closure_kind(adjusted_ty).is_none() => {
240                let def_id = def_id.expect_local();
241                let closure_sig = args.as_closure().sig();
242                let closure_sig = self.instantiate_binder_with_fresh_vars(
243                    call_expr.span,
244                    BoundRegionConversionTime::FnCall,
245                    closure_sig,
246                );
247                let adjustments = self.adjust_steps(autoderef);
248                self.record_deferred_call_resolution(
249                    def_id,
250                    DeferredCallResolution {
251                        call_expr,
252                        callee_expr,
253                        closure_ty: adjusted_ty,
254                        adjustments,
255                        fn_sig: closure_sig,
256                    },
257                );
258                return Some(CallStep::DeferredClosure(def_id, closure_sig));
259            }
260
261            // When calling a `CoroutineClosure` that is local to the body, we will
262            // not know what its `closure_kind` is yet. Instead, just fill in the
263            // signature with an infer var for the `tupled_upvars_ty` of the coroutine,
264            // and record a deferred call resolution which will constrain that var
265            // as part of `AsyncFn*` trait confirmation.
266            ty::CoroutineClosure(def_id, args) if self.closure_kind(adjusted_ty).is_none() => {
267                let def_id = def_id.expect_local();
268                let closure_args = args.as_coroutine_closure();
269                let coroutine_closure_sig = self.instantiate_binder_with_fresh_vars(
270                    call_expr.span,
271                    BoundRegionConversionTime::FnCall,
272                    closure_args.coroutine_closure_sig(),
273                );
274                let tupled_upvars_ty = self.next_ty_var(callee_expr.span);
275                // We may actually receive a coroutine back whose kind is different
276                // from the closure that this dispatched from. This is because when
277                // we have no captures, we automatically implement `FnOnce`. This
278                // impl forces the closure kind to `FnOnce` i.e. `u8`.
279                let kind_ty = self.next_ty_var(callee_expr.span);
280                let call_sig = self.tcx.mk_fn_sig(
281                    [coroutine_closure_sig.tupled_inputs_ty],
282                    coroutine_closure_sig.to_coroutine(
283                        self.tcx,
284                        closure_args.parent_args(),
285                        kind_ty,
286                        self.tcx.coroutine_for_closure(def_id),
287                        tupled_upvars_ty,
288                    ),
289                    coroutine_closure_sig.fn_sig_kind,
290                );
291                let adjustments = self.adjust_steps(autoderef);
292                self.record_deferred_call_resolution(
293                    def_id,
294                    DeferredCallResolution {
295                        call_expr,
296                        callee_expr,
297                        closure_ty: adjusted_ty,
298                        adjustments,
299                        fn_sig: call_sig,
300                    },
301                );
302                return Some(CallStep::DeferredClosure(def_id, call_sig));
303            }
304
305            // Hack: we know that there are traits implementing Fn for &F
306            // where F:Fn and so forth. In the particular case of types
307            // like `f: &mut FnMut()`, if there is a call `f()`, we would
308            // normally translate to `FnMut::call_mut(&mut f, ())`, but
309            // that winds up potentially requiring the user to mark their
310            // variable as `mut` which feels unnecessary and unexpected.
311            //
312            //     fn foo(f: &mut impl FnMut()) { f() }
313            //            ^ without this hack `f` would have to be declared as mutable
314            //
315            // The simplest fix by far is to just ignore this case and deref again,
316            // so we wind up with `FnMut::call_mut(&mut *f, ())`.
317            ty::Ref(..) if autoderef.step_count() == 0 => {
318                return None;
319            }
320
321            ty::Infer(ty::TyVar(vid)) => {
322                // If we end up with an inference variable which is not the hidden type of
323                // an opaque, emit an error.
324                if !self.has_opaques_with_sub_unified_hidden_type(vid) {
325                    self.type_must_be_known_at_this_point(autoderef.span(), adjusted_ty);
326                    return None;
327                }
328            }
329
330            ty::Error(_) => {
331                return None;
332            }
333
334            _ => {}
335        }
336
337        // Now, we look for the implementation of a Fn trait on the object's type.
338        // We first do it with the explicit instruction to look for an impl of
339        // `Fn<Tuple>`, with the tuple `Tuple` having an arity corresponding
340        // to the number of call parameters.
341        // If that fails (or_else branch), we try again without specifying the
342        // shape of the tuple (hence the None). This allows to detect an Fn trait
343        // is implemented, and use this information for diagnostic.
344        self.try_overloaded_call_traits(call_expr, adjusted_ty, Some(arg_exprs))
345            .or_else(|| self.try_overloaded_call_traits(call_expr, adjusted_ty, None))
346            .map(|(autoref, method)| {
347                let mut adjustments = self.adjust_steps(autoderef);
348                adjustments.extend(autoref);
349                self.apply_adjustments(callee_expr, adjustments);
350                CallStep::Overloaded(method)
351            })
352    }
353
354    fn try_overloaded_call_traits(
355        &self,
356        call_expr: &hir::Expr<'_>,
357        adjusted_ty: Ty<'tcx>,
358        opt_arg_exprs: Option<&'tcx [hir::Expr<'tcx>]>,
359    ) -> Option<(Option<Adjustment<'tcx>>, MethodCallee<'tcx>)> {
360        // HACK(async_closures): For async closures, prefer `AsyncFn*`
361        // over `Fn*`, since all async closures implement `FnOnce`, but
362        // choosing that over `AsyncFn`/`AsyncFnMut` would be more restrictive.
363        // For other callables, just prefer `Fn*` for perf reasons.
364        //
365        // The order of trait choices here is not that big of a deal,
366        // since it just guides inference (and our choice of autoref).
367        // Though in the future, I'd like typeck to choose:
368        // `Fn > AsyncFn > FnMut > AsyncFnMut > FnOnce > AsyncFnOnce`
369        // ...or *ideally*, we just have `LendingFn`/`LendingFnMut`, which
370        // would naturally unify these two trait hierarchies in the most
371        // general way.
372        let call_trait_choices = if self.shallow_resolve(adjusted_ty).is_coroutine_closure() {
373            [
374                (self.tcx.lang_items().async_fn_trait(), sym::async_call, true),
375                (self.tcx.lang_items().async_fn_mut_trait(), sym::async_call_mut, true),
376                (self.tcx.lang_items().async_fn_once_trait(), sym::async_call_once, false),
377                (self.tcx.lang_items().fn_trait(), sym::call, true),
378                (self.tcx.lang_items().fn_mut_trait(), sym::call_mut, true),
379                (self.tcx.lang_items().fn_once_trait(), sym::call_once, false),
380            ]
381        } else {
382            [
383                (self.tcx.lang_items().fn_trait(), sym::call, true),
384                (self.tcx.lang_items().fn_mut_trait(), sym::call_mut, true),
385                (self.tcx.lang_items().fn_once_trait(), sym::call_once, false),
386                (self.tcx.lang_items().async_fn_trait(), sym::async_call, true),
387                (self.tcx.lang_items().async_fn_mut_trait(), sym::async_call_mut, true),
388                (self.tcx.lang_items().async_fn_once_trait(), sym::async_call_once, false),
389            ]
390        };
391
392        // Try the options that are least restrictive on the caller first.
393        for (opt_trait_def_id, method_name, borrow) in call_trait_choices {
394            let Some(trait_def_id) = opt_trait_def_id else { continue };
395
396            let opt_input_type = opt_arg_exprs.map(|arg_exprs| {
397                Ty::new_tup_from_iter(self.tcx, arg_exprs.iter().map(|e| self.next_ty_var(e.span)))
398            });
399
400            // We use `TreatNotYetDefinedOpaques::AsRigid` here so that if the `adjusted_ty`
401            // is `Box<impl FnOnce()>` we choose  `FnOnce` instead of `Fn`.
402            //
403            // We try all the different call traits in order and choose the first
404            // one which may apply. So if we treat opaques as inference variables
405            // `Box<impl FnOnce()>: Fn` is considered ambiguous and chosen.
406            if let Some(ok) = self.lookup_method_for_operator(
407                self.misc(call_expr.span),
408                method_name,
409                trait_def_id,
410                adjusted_ty,
411                opt_input_type,
412                TreatNotYetDefinedOpaques::AsRigid,
413            ) {
414                let method = self.register_infer_ok_obligations(ok);
415                let mut autoref = None;
416                if borrow {
417                    // Check for &self vs &mut self in the method signature. Since this is either
418                    // the Fn or FnMut trait, it should be one of those.
419                    let ty::Ref(_, _, mutbl) = *method.sig.inputs()[0].kind() else {
420                        ::rustc_middle::util::bug::bug_fmt(format_args!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut"))bug!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut")
421                    };
422
423                    // For initial two-phase borrow
424                    // deployment, conservatively omit
425                    // overloaded function call ops.
426                    let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::No);
427
428                    autoref = Some(Adjustment {
429                        kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
430                        target: method.sig.inputs()[0],
431                    });
432                }
433
434                return Some((autoref, method));
435            }
436        }
437
438        None
439    }
440
441    fn is_scalable_vector_ctor(&self, callee_ty: Ty<'_>) -> bool {
442        if let ty::FnDef(def_id, _) = *callee_ty.kind()
443            && let def::DefKind::Ctor(def::CtorOf::Struct, _) = self.tcx.def_kind(def_id)
444        {
445            self.tcx
446                .opt_parent(def_id)
447                .and_then(|id| self.tcx.adt_def(id).repr().scalable)
448                .is_some()
449        } else {
450            false
451        }
452    }
453
454    /// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the
455    /// likely intention is to call the closure, suggest `(||{})()`. (#55851)
456    fn identify_bad_closure_def_and_call(
457        &self,
458        err: &mut Diag<'_>,
459        hir_id: hir::HirId,
460        callee_node: &hir::ExprKind<'_>,
461        callee_span: Span,
462    ) {
463        let hir::ExprKind::Block(..) = callee_node else {
464            // Only calls on blocks suggested here.
465            return;
466        };
467
468        let fn_decl_span = if let hir::Node::Expr(&hir::Expr {
469            kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
470            ..
471        }) = self.tcx.parent_hir_node(hir_id)
472        {
473            fn_decl_span
474        } else if let Some((
475            _,
476            hir::Node::Expr(&hir::Expr {
477                hir_id: parent_hir_id,
478                kind:
479                    hir::ExprKind::Closure(&hir::Closure {
480                        kind:
481                            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
482                                hir::CoroutineDesugaring::Async,
483                                hir::CoroutineSource::Closure,
484                            )),
485                        ..
486                    }),
487                ..
488            }),
489        )) = self.tcx.hir_parent_iter(hir_id).nth(3)
490        {
491            // Actually need to unwrap one more layer of HIR to get to
492            // the _real_ closure...
493            let hir::Node::Expr(&hir::Expr {
494                kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
495                ..
496            }) = self.tcx.parent_hir_node(parent_hir_id)
497            else {
498                return;
499            };
500            fn_decl_span
501        } else {
502            return;
503        };
504
505        let start = fn_decl_span.shrink_to_lo();
506        let end = callee_span.shrink_to_hi();
507        err.multipart_suggestion(
508            "if you meant to create this closure and immediately call it, surround the \
509                closure with parentheses",
510            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(start, "(".to_string()), (end, ")".to_string())]))vec![(start, "(".to_string()), (end, ")".to_string())],
511            Applicability::MaybeIncorrect,
512        );
513    }
514
515    /// Give appropriate suggestion when encountering `[("a", 0) ("b", 1)]`, where the
516    /// likely intention is to create an array containing tuples.
517    fn maybe_suggest_bad_array_definition(
518        &self,
519        err: &mut Diag<'_>,
520        call_expr: &'tcx hir::Expr<'tcx>,
521        callee_expr: &'tcx hir::Expr<'tcx>,
522    ) -> bool {
523        let parent_node = self.tcx.parent_hir_node(call_expr.hir_id);
524        if let (
525            hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }),
526            hir::ExprKind::Tup(exp),
527            hir::ExprKind::Call(_, args),
528        ) = (parent_node, &callee_expr.kind, &call_expr.kind)
529            && args.len() == exp.len()
530        {
531            let start = callee_expr.span.shrink_to_hi();
532            err.span_suggestion(
533                start,
534                "consider separating array elements with a comma",
535                ",",
536                Applicability::MaybeIncorrect,
537            );
538            return true;
539        }
540        false
541    }
542
543    fn confirm_builtin_call(
544        &self,
545        call_expr: &'tcx hir::Expr<'tcx>,
546        callee_expr: &'tcx hir::Expr<'tcx>,
547        callee_ty: Ty<'tcx>,
548        arg_exprs: &'tcx [hir::Expr<'tcx>],
549        expected: Expectation<'tcx>,
550    ) -> Ty<'tcx> {
551        let (fn_sig, def_id, callee_generic_args) = match *callee_ty.kind() {
552            ty::FnDef(def_id, args) => {
553                self.enforce_context_effects(Some(call_expr.hir_id), call_expr.span, def_id, args);
554                let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args).skip_norm_wip();
555
556                // Unit testing: function items annotated with
557                // `#[rustc_evaluate_where_clauses]` trigger special output
558                // to let us test the trait evaluation system.
559                if self.has_rustc_attrs && {
        {
            'done:
                {
                for i in
                    ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self.tcx) {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(RustcEvaluateWhereClauses) => {
                            break 'done Some(());
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }.is_some()find_attr!(self.tcx, def_id, RustcEvaluateWhereClauses) {
560                    let predicates = self.tcx.predicates_of(def_id);
561                    let predicates = predicates.instantiate(self.tcx, args);
562                    for (predicate, predicate_span) in predicates {
563                        let predicate = predicate.skip_norm_wip();
564                        let obligation = Obligation::new(
565                            self.tcx,
566                            ObligationCause::dummy_with_span(callee_expr.span),
567                            self.param_env,
568                            predicate,
569                        );
570                        let result = self.evaluate_obligation(&obligation);
571                        self.dcx()
572                            .struct_span_err(
573                                callee_expr.span,
574                                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("evaluate({0:?}) = {1:?}",
                predicate, result))
    })format!("evaluate({predicate:?}) = {result:?}"),
575                            )
576                            .with_span_label(predicate_span, "predicate")
577                            .emit();
578                    }
579                }
580                (fn_sig, Some(def_id), Some(args))
581            }
582
583            // FIXME(const_trait_impl): these arms should error because we can't enforce them
584            ty::FnPtr(sig_tys, hdr) => (sig_tys.with(hdr), None, None),
585
586            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
587        };
588
589        // Replace any late-bound regions that appear in the function
590        // signature with region variables. We also have to
591        // renormalize the associated types at this point, since they
592        // previously appeared within a `Binder<>` and hence would not
593        // have been normalized before.
594        let fn_sig = self.instantiate_binder_with_fresh_vars(
595            call_expr.span,
596            BoundRegionConversionTime::FnCall,
597            fn_sig,
598        );
599        let fn_sig = self.normalize(call_expr.span, Unnormalized::new_wip(fn_sig));
600
601        self.check_argument_types_maybe_method_like(
602            &fn_sig,
603            call_expr,
604            arg_exprs,
605            expected,
606            TupleArgumentsFlag::with_fn_sig_kind(fn_sig.fn_sig_kind, false),
607            def_id,
608            callee_generic_args,
609        );
610
611        // Splatting is currently incompatible with RustCall.
612        if fn_sig.abi() == rustc_abi::ExternAbi::RustCall {
613            let sp = arg_exprs.last().map_or(call_expr.span, |expr| expr.span);
614            if let Some(ty) = fn_sig.inputs().last().copied()
615                && fn_sig.splatted().is_none()
616            {
617                self.register_bound(
618                    ty,
619                    self.tcx.require_lang_item(hir::LangItem::Tuple, sp),
620                    self.cause(sp, ObligationCauseCode::RustCall),
621                );
622                self.require_type_is_sized(ty, sp, ObligationCauseCode::RustCall);
623            } else {
624                self.dcx().emit_err(diagnostics::RustCallIncorrectArgs { span: sp });
625            }
626        }
627
628        fn_sig.output()
629    }
630
631    /// Performs arguments check with an additional routine of adjusting the first argument,
632    /// so it corresponds to the first parameter of the function. We reuse adjustments
633    /// that are obtained from `probe_for_name`, where the first argument pretends to be
634    /// a receiver like in a method call. At this point this routine is used for delegations,
635    /// as from this moment we always generate a call (earlier method calls were generated),
636    /// so we can both propagate parent generics and get benefits from adjustments from method call.
637    fn check_argument_types_maybe_method_like(
638        &self,
639        fn_sig: &FnSig<'tcx>,
640        call_expr: &'tcx hir::Expr<'tcx>,
641        arg_exprs: &'tcx [hir::Expr<'tcx>],
642        expected: Expectation<'tcx>,
643        tuple_arguments_flag: TupleArgumentsFlag,
644        def_id: Option<DefId>,
645        callee_generic_args: Option<GenericArgsRef<'tcx>>,
646    ) {
647        let do_check = || {
648            self.check_argument_types(
649                call_expr.span,
650                call_expr,
651                fn_sig.inputs(),
652                fn_sig.output(),
653                expected,
654                arg_exprs,
655                fn_sig.c_variadic(),
656                tuple_arguments_flag,
657                def_id,
658                callee_generic_args,
659            );
660        };
661
662        let Some(scope) = self.get_scope_for_method_call_adjustments(call_expr, arg_exprs) else {
663            return do_check();
664        };
665
666        let first_expr = &arg_exprs[0];
667        let first_arg_type = self.check_expr(first_expr);
668
669        // Reuse method probing that is used during method call, as all this code pretends that
670        // we generated method call.
671        let pick = self.probe_for_name(
672            Mode::MethodCall,
673            Ident::dummy(),
674            None,
675            IsSuggestion(false),
676            first_arg_type,
677            call_expr.hir_id,
678            scope,
679        );
680
681        let Ok(ref pick) = pick else { return do_check() };
682
683        // Fool typechecker by placing an adjusted type of the first arg to avoid errors.
684        // We already wrote type of `first_expr` during `self.check_expr(first_expr)` above.
685        let first_arg_type = self
686            .typeck_results
687            .borrow_mut()
688            .node_types_mut()
689            .insert(first_expr.hir_id, pick.self_ty)
690            .expect("must be set");
691
692        do_check();
693
694        let mut results = self.typeck_results.borrow_mut();
695
696        // Remove any added adjustments for `first_expr` during `do_check` and replace them with ours.
697        let mut adjustments = results.adjustments_mut();
698        let adjustments = adjustments.entry(first_expr.hir_id).or_default();
699
700        let mut ctx = ConfirmContext::new(self, first_expr.span, first_expr, first_expr);
701        *adjustments = ctx.create_ty_adjustments_from_pick(first_arg_type, pick).1;
702
703        // Restore original first provided arg type.
704        results.node_types_mut().insert(first_expr.hir_id, first_arg_type);
705    }
706
707    /// Gets scope for method-call like adjustments for the first argument of the call.
708    /// Now only delegations are processed this way.
709    fn get_scope_for_method_call_adjustments(
710        &self,
711        call_expr: &'tcx hir::Expr<'tcx>,
712        arg_exprs: &'tcx [hir::Expr<'tcx>],
713    ) -> Option<ProbeScope> {
714        // Check that we are inside delegation and processing its call. First, we check that
715        // the parent of call expr. is delegation and then make sure that it is compiler-generated
716        // by comparing their hir ids (otherwise we will encounter errors in nested delegations,
717        // see tests\ui\delegation\impl-reuse-pass.rs:237).
718        let parent_def = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id;
719        let Some(info) = self.tcx.hir_opt_delegation_info(parent_def) else {
720            return None;
721        };
722
723        if call_expr.hir_id != info.call_expr_id {
724            return None;
725        };
726
727        let Some(path_res_id) = info.call_path_res else { return None };
728
729        // Check that delegation has first provided arg and that the call path
730        // resolves to a trait method (inherent methods are not yet supported).
731        if arg_exprs.is_empty()
732            || !self.tcx.opt_associated_item(path_res_id).is_some_and(|i| i.is_method())
733        {
734            return None;
735        }
736
737        Some(ProbeScope::Single(path_res_id))
738    }
739
740    /// Attempts to reinterpret `method(rcvr, args...)` as `rcvr.method(args...)`
741    /// and suggesting the fix if the method probe is successful.
742    fn suggest_call_as_method(
743        &self,
744        diag: &mut Diag<'_>,
745        segment: &'tcx hir::PathSegment<'tcx>,
746        arg_exprs: &'tcx [hir::Expr<'tcx>],
747        call_expr: &'tcx hir::Expr<'tcx>,
748        expected: Expectation<'tcx>,
749    ) {
750        if let [callee_expr, rest @ ..] = arg_exprs {
751            let Some(callee_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr)
752            else {
753                return;
754            };
755
756            // First, do a probe with `IsSuggestion(true)` to avoid emitting
757            // any strange errors. If it's successful, then we'll do a true
758            // method lookup.
759            let Ok(pick) = self.lookup_probe_for_diagnostic(
760                segment.ident,
761                callee_ty,
762                call_expr,
763                // We didn't record the in scope traits during late resolution
764                // so we need to probe AllTraits unfortunately
765                ProbeScope::AllTraits,
766                expected.only_has_type(self),
767            ) else {
768                return;
769            };
770
771            let pick = self.confirm_method_for_diagnostic(
772                call_expr.span,
773                callee_expr,
774                call_expr,
775                callee_ty,
776                &pick,
777                segment,
778            );
779            if pick.illegal_sized_bound.is_some() {
780                return;
781            }
782
783            let Some(callee_expr_span) = callee_expr.span.find_ancestor_inside(call_expr.span)
784            else {
785                return;
786            };
787            let up_to_rcvr_span = segment.ident.span.until(callee_expr_span);
788            let rest_span = callee_expr_span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
789            let rest_snippet = if let Some(first) = rest.first() {
790                self.tcx
791                    .sess
792                    .source_map()
793                    .span_to_snippet(first.span.to(call_expr.span.shrink_to_hi()))
794            } else {
795                Ok(")".to_string())
796            };
797
798            if let Ok(rest_snippet) = rest_snippet {
799                let sugg = if self.precedence(callee_expr) >= ExprPrecedence::Unambiguous {
800                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(up_to_rcvr_span, "".to_string()),
                (rest_span,
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(".{0}({1}", segment.ident,
                                    rest_snippet))
                        }))]))vec![
801                        (up_to_rcvr_span, "".to_string()),
802                        (rest_span, format!(".{}({rest_snippet}", segment.ident)),
803                    ]
804                } else {
805                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(up_to_rcvr_span, "(".to_string()),
                (rest_span,
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(").{0}({1}",
                                    segment.ident, rest_snippet))
                        }))]))vec![
806                        (up_to_rcvr_span, "(".to_string()),
807                        (rest_span, format!(").{}({rest_snippet}", segment.ident)),
808                    ]
809                };
810                let self_ty = self.resolve_vars_if_possible(pick.callee.sig.inputs()[0]);
811                diag.multipart_suggestion(
812                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("use the `.` operator to call the method `{0}{1}` on `{2}`",
                self.tcx.associated_item(pick.callee.def_id).trait_container(self.tcx).map_or_else(||
                        String::new(),
                    |trait_def_id| self.tcx.def_path_str(trait_def_id) + "::"),
                segment.ident, self_ty))
    })format!(
813                        "use the `.` operator to call the method `{}{}` on `{self_ty}`",
814                        self.tcx
815                            .associated_item(pick.callee.def_id)
816                            .trait_container(self.tcx)
817                            .map_or_else(
818                                || String::new(),
819                                |trait_def_id| self.tcx.def_path_str(trait_def_id) + "::"
820                            ),
821                        segment.ident
822                    ),
823                    sugg,
824                    Applicability::MaybeIncorrect,
825                );
826            }
827        }
828    }
829
830    fn report_invalid_callee(
831        &self,
832        call_expr: &'tcx hir::Expr<'tcx>,
833        callee_expr: &'tcx hir::Expr<'tcx>,
834        callee_ty: Ty<'tcx>,
835        arg_exprs: &'tcx [hir::Expr<'tcx>],
836    ) -> ErrorGuaranteed {
837        // Callee probe fails when APIT references errors, so suppress those
838        // errors here.
839        if let Some((_, _, args)) = self.extract_callable_info(callee_ty)
840            && let Err(err) = args.error_reported()
841        {
842            return err;
843        }
844
845        let mut unit_variant = None;
846        if let hir::ExprKind::Path(qpath) = &callee_expr.kind
847            && let Res::Def(def::DefKind::Ctor(kind, CtorKind::Const), _)
848                = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
849            // Only suggest removing parens if there are no arguments
850            && arg_exprs.is_empty()
851            && call_expr.span.contains(callee_expr.span)
852        {
853            let descr = match kind {
854                def::CtorOf::Struct => "struct",
855                def::CtorOf::Variant => "enum variant",
856            };
857            let removal_span = callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
858            unit_variant =
859                Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(&self.tcx, qpath)));
860        }
861
862        let callee_ty = self.resolve_vars_if_possible(callee_ty);
863        let mut path = None;
864        let mut err = self.dcx().create_err(diagnostics::InvalidCallee {
865            span: callee_expr.span,
866            found: match &unit_variant {
867                Some((_, kind, path)) => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} `{1}`", kind, path))
    })format!("{kind} `{path}`"),
868                None => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}`",
                self.tcx.short_string(callee_ty, &mut path)))
    })format!("`{}`", self.tcx.short_string(callee_ty, &mut path)),
869            },
870        });
871        *err.long_ty_path() = path;
872        if callee_ty.references_error() {
873            err.downgrade_to_delayed_bug();
874        }
875
876        self.identify_bad_closure_def_and_call(
877            &mut err,
878            call_expr.hir_id,
879            &callee_expr.kind,
880            callee_expr.span,
881        );
882
883        if let Some((removal_span, kind, path)) = &unit_variant {
884            err.span_suggestion_verbose(
885                *removal_span,
886                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` is a unit {1}, and does not take parentheses to be constructed",
                path, kind))
    })format!(
887                    "`{path}` is a unit {kind}, and does not take parentheses to be constructed",
888                ),
889                "",
890                Applicability::MachineApplicable,
891            );
892        }
893
894        if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = callee_expr.kind
895            && let Res::Local(_) = path.res
896            && let [segment] = &path.segments
897        {
898            for id in self.tcx.hir_free_items() {
899                if let Some(node) = self.tcx.hir_get_if_local(id.owner_id.into())
900                    && let hir::Node::Item(item) = node
901                    && let hir::ItemKind::Fn { ident, .. } = item.kind
902                    && ident.name == segment.ident.name
903                {
904                    err.span_label(
905                        self.tcx.def_span(id.owner_id),
906                        "this function of the same name is available here, but it's shadowed by \
907                         the local binding",
908                    );
909                }
910            }
911        }
912
913        let mut inner_callee_path = None;
914        let def = match callee_expr.kind {
915            hir::ExprKind::Path(ref qpath) => {
916                self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
917            }
918            hir::ExprKind::Call(inner_callee, _) => {
919                if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind {
920                    inner_callee_path = Some(inner_qpath);
921                    self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id)
922                } else {
923                    Res::Err
924                }
925            }
926            _ => Res::Err,
927        };
928
929        if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
930            // If the call spans more than one line and the callee kind is
931            // itself another `ExprCall`, that's a clue that we might just be
932            // missing a semicolon (#51055, #106515).
933            let call_is_multiline = self
934                .tcx
935                .sess
936                .source_map()
937                .is_multiline(call_expr.span.with_lo(callee_expr.span.hi()))
938                && call_expr.span.eq_ctxt(callee_expr.span);
939            if call_is_multiline {
940                err.span_suggestion(
941                    callee_expr.span.shrink_to_hi(),
942                    "consider using a semicolon here to finish the statement",
943                    ";",
944                    Applicability::MaybeIncorrect,
945                );
946            }
947            if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_ty)
948                && !self.type_is_sized_modulo_regions(self.param_env, output_ty)
949            {
950                let descr = match maybe_def {
951                    DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id),
952                    DefIdOrName::Name(name) => name,
953                };
954                err.span_label(
955                    callee_expr.span,
956                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this {0} returns an unsized value `{1}`, so it cannot be called",
                descr, output_ty))
    })format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called")
957                );
958                if let DefIdOrName::DefId(def_id) = maybe_def
959                    && let Some(def_span) = self.tcx.hir_span_if_local(def_id)
960                {
961                    err.span_label(def_span, "the callable type is defined here");
962                }
963            } else {
964                err.span_label(call_expr.span, "call expression requires function");
965            }
966        }
967
968        if let Some(span) = self.tcx.hir_res_span(def) {
969            let label = match (unit_variant, inner_callee_path) {
970                (Some((_, kind, path)), _) => {
971                    err.arg("kind", kind);
972                    err.arg("path", path);
973                    Some(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$kind} `{$path}` defined here"))msg!("{$kind} `{$path}` defined here"))
974                }
975                (_, Some(hir::QPath::Resolved(_, path))) => {
976                    self.tcx.sess.source_map().span_to_snippet(path.span).ok().map(|p| {
977                        err.arg("func", p);
978                        err.arg("ty", callee_ty);
979                        rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$func}` defined here returns `{$ty}`"))msg!("`{$func}` defined here returns `{$ty}`")
980                    })
981                }
982                _ => {
983                    match def {
984                        // Emit a different diagnostic for local variables, as they are not
985                        // type definitions themselves, but rather variables *of* that type.
986                        Res::Local(hir_id) => {
987                            err.arg("local_name", self.tcx.hir_name(hir_id));
988                            err.arg("ty", callee_ty);
989                            Some(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$local_name}` has type `{$ty}`"))msg!("`{$local_name}` has type `{$ty}`"))
990                        }
991                        Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
992                            err.arg("path", self.tcx.def_path_str(def_id));
993                            Some(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$path}` defined here"))msg!("`{$path}` defined here"))
994                        }
995                        _ => {
996                            err.arg("path", callee_ty.to_string());
997                            Some(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$path}` defined here"))msg!("`{$path}` defined here"))
998                        }
999                    }
1000                }
1001            };
1002            if let Some(label) = label {
1003                err.span_label(span, label);
1004            }
1005        }
1006        err.emit()
1007    }
1008
1009    fn confirm_deferred_closure_call(
1010        &self,
1011        call_expr: &'tcx hir::Expr<'tcx>,
1012        arg_exprs: &'tcx [hir::Expr<'tcx>],
1013        expected: Expectation<'tcx>,
1014        closure_def_id: LocalDefId,
1015        fn_sig: ty::FnSig<'tcx>,
1016    ) -> Ty<'tcx> {
1017        // `fn_sig` is the *signature* of the closure being called. We
1018        // don't know the full details yet (`Fn` vs `FnMut` etc), but we
1019        // do know the types expected for each argument and the return
1020        // type.
1021        self.check_argument_types(
1022            call_expr.span,
1023            call_expr,
1024            fn_sig.inputs(),
1025            fn_sig.output(),
1026            expected,
1027            arg_exprs,
1028            fn_sig.fn_sig_kind.c_variadic(),
1029            TupleArgumentsFlag::rust_fn_trait_call(),
1030            Some(closure_def_id.to_def_id()),
1031            None,
1032        );
1033
1034        fn_sig.output()
1035    }
1036
1037    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("enforce_context_effects",
                                    "rustc_hir_typeck::callee", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/callee.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1037u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::callee"),
                                    ::tracing_core::field::FieldSet::new(&["call_hir_id",
                                                    "callee_did", "callee_args"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&call_hir_id)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&callee_did)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&callee_args)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let const_context = self.tcx.hir_body_const_context(self.body_id);
            if let hir::Constness::Const { always: true } =
                    self.tcx.constness(callee_did) {
                match const_context {
                    Some(hir::ConstContext::Const { .. } |
                        hir::ConstContext::Static(_)) => {}
                    Some(hir::ConstContext::ConstFn) | None => {
                        self.dcx().span_err(span,
                            "comptime fns can only be called at compile time");
                    }
                }
            }
            if !self.tcx.features().const_trait_impl() { return; }
            if self.has_rustc_attrs &&
                    {
                            {
                                'done:
                                    {
                                    for i in
                                        ::rustc_hir::attrs::HasAttrs::get_attrs(self.body_id,
                                            &self.tcx) {
                                        #[allow(unused_imports)]
                                        use rustc_hir::attrs::AttributeKind::*;
                                        let i: &rustc_hir::Attribute = i;
                                        match i {
                                            rustc_hir::Attribute::Parsed(RustcDoNotConstCheck) => {
                                                break 'done Some(());
                                            }
                                            rustc_hir::Attribute::Unparsed(..) =>
                                                {}
                                                #[deny(unreachable_patterns)]
                                                _ => {}
                                        }
                                    }
                                    None
                                }
                            }
                        }.is_some() {
                return;
            }
            let host =
                match const_context {
                    Some(hir::ConstContext::Const { .. } |
                        hir::ConstContext::Static(_)) => {
                        ty::BoundConstness::Const
                    }
                    Some(hir::ConstContext::ConstFn) =>
                        ty::BoundConstness::Maybe,
                    None => return,
                };
            if self.tcx.is_conditionally_const(callee_did) {
                let q = self.tcx.const_conditions(callee_did);
                for (idx, (cond, pred_span)) in
                    q.instantiate(self.tcx, callee_args).into_iter().enumerate()
                    {
                    let cause =
                        self.cause(span,
                            if let Some(hir_id) = call_hir_id {
                                ObligationCauseCode::HostEffectInExpr(callee_did, pred_span,
                                    hir_id, idx)
                            } else {
                                ObligationCauseCode::WhereClause(callee_did, pred_span)
                            });
                    self.register_predicate(Obligation::new(self.tcx, cause,
                            self.param_env,
                            cond.to_host_effect_clause(self.tcx,
                                    host).skip_norm_wip()));
                }
            } else {}
        }
    }
}#[tracing::instrument(level = "debug", skip(self, span))]
1038    pub(super) fn enforce_context_effects(
1039        &self,
1040        call_hir_id: Option<HirId>,
1041        span: Span,
1042        callee_did: DefId,
1043        callee_args: GenericArgsRef<'tcx>,
1044    ) {
1045        let const_context = self.tcx.hir_body_const_context(self.body_id);
1046
1047        if let hir::Constness::Const { always: true } = self.tcx.constness(callee_did) {
1048            match const_context {
1049                Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {}
1050                Some(hir::ConstContext::ConstFn) | None => {
1051                    self.dcx().span_err(span, "comptime fns can only be called at compile time");
1052                }
1053            }
1054        }
1055
1056        // FIXME(const_trait_impl): We should be enforcing these effects unconditionally.
1057        // This can be done as soon as we convert the standard library back to
1058        // using const traits, since if we were to enforce these conditions now,
1059        // we'd fail on basically every builtin trait call (i.e. `1 + 2`).
1060        if !self.tcx.features().const_trait_impl() {
1061            return;
1062        }
1063
1064        // If we have `rustc_do_not_const_check`, do not check `[const]` bounds.
1065        if self.has_rustc_attrs && find_attr!(self.tcx, self.body_id, RustcDoNotConstCheck) {
1066            return;
1067        }
1068
1069        let host = match const_context {
1070            Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {
1071                ty::BoundConstness::Const
1072            }
1073            Some(hir::ConstContext::ConstFn) => ty::BoundConstness::Maybe,
1074            None => return,
1075        };
1076
1077        // FIXME(const_trait_impl): Should this be `is_const_fn_raw`? It depends on if we move
1078        // const stability checking here too, I guess.
1079        if self.tcx.is_conditionally_const(callee_did) {
1080            let q = self.tcx.const_conditions(callee_did);
1081            for (idx, (cond, pred_span)) in
1082                q.instantiate(self.tcx, callee_args).into_iter().enumerate()
1083            {
1084                let cause = self.cause(
1085                    span,
1086                    if let Some(hir_id) = call_hir_id {
1087                        ObligationCauseCode::HostEffectInExpr(callee_did, pred_span, hir_id, idx)
1088                    } else {
1089                        ObligationCauseCode::WhereClause(callee_did, pred_span)
1090                    },
1091                );
1092                self.register_predicate(Obligation::new(
1093                    self.tcx,
1094                    cause,
1095                    self.param_env,
1096                    cond.to_host_effect_clause(self.tcx, host).skip_norm_wip(),
1097                ));
1098            }
1099        } else {
1100            // FIXME(const_trait_impl): This should eventually be caught here.
1101            // For now, though, we defer some const checking to MIR.
1102        }
1103    }
1104
1105    fn confirm_overloaded_call(
1106        &self,
1107        call_expr: &'tcx hir::Expr<'tcx>,
1108        arg_exprs: &'tcx [hir::Expr<'tcx>],
1109        expected: Expectation<'tcx>,
1110        method: MethodCallee<'tcx>,
1111    ) -> Ty<'tcx> {
1112        // FIXME(splat): if we ever support splatting here, decrement the splatted index, because
1113        // the receiver argument is removed below.
1114        {
    match (&method.sig.fn_sig_kind.splatted(), &None) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val,
                    ::core::option::Option::Some(format_args!("splatting is not supported on RustCall tuples")));
            }
        }
    }
};assert_eq!(
1115            method.sig.fn_sig_kind.splatted(),
1116            None,
1117            "splatting is not supported on RustCall tuples",
1118        );
1119        self.check_argument_types(
1120            call_expr.span,
1121            call_expr,
1122            &method.sig.inputs()[1..],
1123            method.sig.output(),
1124            expected,
1125            arg_exprs,
1126            method.sig.fn_sig_kind.c_variadic(),
1127            TupleArgumentsFlag::rust_fn_trait_call(),
1128            Some(method.def_id),
1129            None,
1130        );
1131
1132        self.write_method_call_and_enforce_effects(call_expr.hir_id, call_expr.span, method);
1133
1134        method.sig.output()
1135    }
1136}
1137
1138#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for DeferredCallResolution<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "DeferredCallResolution", "call_expr", &self.call_expr,
            "callee_expr", &self.callee_expr, "closure_ty", &self.closure_ty,
            "adjustments", &self.adjustments, "fn_sig", &&self.fn_sig)
    }
}Debug)]
1139pub(crate) struct DeferredCallResolution<'tcx> {
1140    call_expr: &'tcx hir::Expr<'tcx>,
1141    callee_expr: &'tcx hir::Expr<'tcx>,
1142    closure_ty: Ty<'tcx>,
1143    adjustments: Vec<Adjustment<'tcx>>,
1144    fn_sig: ty::FnSig<'tcx>,
1145}
1146
1147impl<'a, 'tcx> DeferredCallResolution<'tcx> {
1148    pub(crate) fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
1149        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/callee.rs:1149",
                        "rustc_hir_typeck::callee", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/callee.rs"),
                        ::tracing_core::__macro_support::Option::Some(1149u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::callee"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("DeferredCallResolution::resolve() {0:?}",
                                                    self) as &dyn Value))])
            });
    } else { ; }
};debug!("DeferredCallResolution::resolve() {:?}", self);
1150
1151        // we should not be invoked until the closure kind has been
1152        // determined by upvar inference
1153        if !fcx.closure_kind(self.closure_ty).is_some() {
    ::core::panicking::panic("assertion failed: fcx.closure_kind(self.closure_ty).is_some()")
};assert!(fcx.closure_kind(self.closure_ty).is_some());
1154
1155        // We may now know enough to figure out fn vs fnmut etc.
1156        match fcx.try_overloaded_call_traits(self.call_expr, self.closure_ty, None) {
1157            Some((autoref, method_callee)) => {
1158                // One problem is that when we get here, we are going
1159                // to have a newly instantiated function signature
1160                // from the call trait. This has to be reconciled with
1161                // the older function signature we had before. In
1162                // principle we *should* be able to fn_sigs(), but we
1163                // can't because of the annoying need for a TypeTrace.
1164                // (This always bites me, should find a way to
1165                // refactor it.)
1166                let method_sig = method_callee.sig;
1167
1168                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/callee.rs:1168",
                        "rustc_hir_typeck::callee", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/callee.rs"),
                        ::tracing_core::__macro_support::Option::Some(1168u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::callee"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("attempt_resolution: method_callee={0:?}",
                                                    method_callee) as &dyn Value))])
            });
    } else { ; }
};debug!("attempt_resolution: method_callee={:?}", method_callee);
1169
1170                for (method_arg_ty, self_arg_ty) in
1171                    iter::zip(method_sig.inputs().iter().skip(1), self.fn_sig.inputs())
1172                {
1173                    fcx.demand_eqtype(self.call_expr.span, *self_arg_ty, *method_arg_ty);
1174                }
1175
1176                fcx.demand_eqtype(self.call_expr.span, method_sig.output(), self.fn_sig.output());
1177
1178                let mut adjustments = self.adjustments;
1179                adjustments.extend(autoref);
1180                fcx.apply_adjustments(self.callee_expr, adjustments);
1181
1182                fcx.write_method_call_and_enforce_effects(
1183                    self.call_expr.hir_id,
1184                    self.call_expr.span,
1185                    method_callee,
1186                );
1187            }
1188            None => {
1189                ::rustc_middle::util::bug::span_bug_fmt(self.call_expr.span,
    format_args!("Expected to find a suitable `Fn`/`FnMut`/`FnOnce` implementation for `{0}`",
        self.closure_ty))span_bug!(
1190                    self.call_expr.span,
1191                    "Expected to find a suitable `Fn`/`FnMut`/`FnOnce` implementation for `{}`",
1192                    self.closure_ty
1193                )
1194            }
1195        }
1196    }
1197}