rustc_hir_typeck/method/
confirm.rs

1use std::ops::Deref;
2
3use rustc_hir as hir;
4use rustc_hir::GenericArg;
5use rustc_hir::def_id::DefId;
6use rustc_hir_analysis::hir_ty_lowering::generics::{
7    check_generic_arg_count_for_call, lower_generic_args,
8};
9use rustc_hir_analysis::hir_ty_lowering::{
10    FeedConstTy, GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
11};
12use rustc_infer::infer::{
13    BoundRegionConversionTime, DefineOpaqueTypes, InferOk, RegionVariableOrigin,
14};
15use rustc_lint::builtin::SUPERTRAIT_ITEM_SHADOWING_USAGE;
16use rustc_middle::traits::ObligationCauseCode;
17use rustc_middle::ty::adjustment::{
18    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
19};
20use rustc_middle::ty::{
21    self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
22    TypeVisitableExt, UserArgs,
23};
24use rustc_middle::{bug, span_bug};
25use rustc_span::{DUMMY_SP, Span};
26use rustc_trait_selection::traits;
27use tracing::debug;
28
29use super::{MethodCallee, probe};
30use crate::errors::{SupertraitItemShadowee, SupertraitItemShadower, SupertraitItemShadowing};
31use crate::{FnCtxt, callee};
32
33struct ConfirmContext<'a, 'tcx> {
34    fcx: &'a FnCtxt<'a, 'tcx>,
35    span: Span,
36    self_expr: &'tcx hir::Expr<'tcx>,
37    call_expr: &'tcx hir::Expr<'tcx>,
38    skip_record_for_diagnostics: bool,
39}
40
41impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
42    type Target = FnCtxt<'a, 'tcx>;
43    fn deref(&self) -> &Self::Target {
44        self.fcx
45    }
46}
47
48#[derive(Debug)]
49pub(crate) struct ConfirmResult<'tcx> {
50    pub callee: MethodCallee<'tcx>,
51    pub illegal_sized_bound: Option<Span>,
52}
53
54impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
55    pub(crate) fn confirm_method(
56        &self,
57        span: Span,
58        self_expr: &'tcx hir::Expr<'tcx>,
59        call_expr: &'tcx hir::Expr<'tcx>,
60        unadjusted_self_ty: Ty<'tcx>,
61        pick: &probe::Pick<'tcx>,
62        segment: &'tcx hir::PathSegment<'tcx>,
63    ) -> ConfirmResult<'tcx> {
64        debug!(
65            "confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})",
66            unadjusted_self_ty, pick, segment.args,
67        );
68
69        let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
70        confirm_cx.confirm(unadjusted_self_ty, pick, segment)
71    }
72
73    pub(crate) fn confirm_method_for_diagnostic(
74        &self,
75        span: Span,
76        self_expr: &'tcx hir::Expr<'tcx>,
77        call_expr: &'tcx hir::Expr<'tcx>,
78        unadjusted_self_ty: Ty<'tcx>,
79        pick: &probe::Pick<'tcx>,
80        segment: &hir::PathSegment<'tcx>,
81    ) -> ConfirmResult<'tcx> {
82        let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
83        confirm_cx.skip_record_for_diagnostics = true;
84        confirm_cx.confirm(unadjusted_self_ty, pick, segment)
85    }
86}
87
88impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
89    fn new(
90        fcx: &'a FnCtxt<'a, 'tcx>,
91        span: Span,
92        self_expr: &'tcx hir::Expr<'tcx>,
93        call_expr: &'tcx hir::Expr<'tcx>,
94    ) -> ConfirmContext<'a, 'tcx> {
95        ConfirmContext { fcx, span, self_expr, call_expr, skip_record_for_diagnostics: false }
96    }
97
98    fn confirm(
99        &mut self,
100        unadjusted_self_ty: Ty<'tcx>,
101        pick: &probe::Pick<'tcx>,
102        segment: &hir::PathSegment<'tcx>,
103    ) -> ConfirmResult<'tcx> {
104        // Adjust the self expression the user provided and obtain the adjusted type.
105        let self_ty = self.adjust_self_ty(unadjusted_self_ty, pick);
106
107        // Create generic args for the method's type parameters.
108        let rcvr_args = self.fresh_receiver_args(self_ty, pick);
109        let all_args = self.instantiate_method_args(pick, segment, rcvr_args);
110
111        debug!("rcvr_args={rcvr_args:?}, all_args={all_args:?}");
112
113        // Create the final signature for the method, replacing late-bound regions.
114        let (method_sig, method_predicates) = self.instantiate_method_sig(pick, all_args);
115
116        // If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
117        // something which derefs to `Self` actually implements the trait and the caller
118        // wanted to make a static dispatch on it but forgot to import the trait.
119        // See test `tests/ui/issues/issue-35976.rs`.
120        //
121        // In that case, we'll error anyway, but we'll also re-run the search with all traits
122        // in scope, and if we find another method which can be used, we'll output an
123        // appropriate hint suggesting to import the trait.
124        let filler_args = rcvr_args
125            .extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def));
126        let illegal_sized_bound = self.predicates_require_illegal_sized_bound(
127            self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_args),
128        );
129
130        // Unify the (adjusted) self type with what the method expects.
131        //
132        // SUBTLE: if we want good error messages, because of "guessing" while matching
133        // traits, no trait system method can be called before this point because they
134        // could alter our Self-type, except for normalizing the receiver from the
135        // signature (which is also done during probing).
136        let method_sig_rcvr = self.normalize(self.span, method_sig.inputs()[0]);
137        debug!(
138            "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}",
139            self_ty, method_sig_rcvr, method_sig, method_predicates
140        );
141        self.unify_receivers(self_ty, method_sig_rcvr, pick);
142
143        let (method_sig, method_predicates) =
144            self.normalize(self.span, (method_sig, method_predicates));
145
146        // Make sure nobody calls `drop()` explicitly.
147        self.check_for_illegal_method_calls(pick);
148
149        // Lint when an item is shadowing a supertrait item.
150        self.lint_shadowed_supertrait_items(pick, segment);
151
152        // Add any trait/regions obligations specified on the method's type parameters.
153        // We won't add these if we encountered an illegal sized bound, so that we can use
154        // a custom error in that case.
155        if illegal_sized_bound.is_none() {
156            self.add_obligations(method_sig, all_args, method_predicates, pick.item.def_id);
157        }
158
159        // Create the final `MethodCallee`.
160        let callee = MethodCallee { def_id: pick.item.def_id, args: all_args, sig: method_sig };
161        ConfirmResult { callee, illegal_sized_bound }
162    }
163
164    ///////////////////////////////////////////////////////////////////////////
165    // ADJUSTMENTS
166
167    fn adjust_self_ty(
168        &mut self,
169        unadjusted_self_ty: Ty<'tcx>,
170        pick: &probe::Pick<'tcx>,
171    ) -> Ty<'tcx> {
172        // Commit the autoderefs by calling `autoderef` again, but this
173        // time writing the results into the various typeck results.
174        let mut autoderef = self.autoderef(self.call_expr.span, unadjusted_self_ty);
175        let Some((mut target, n)) = autoderef.nth(pick.autoderefs) else {
176            return Ty::new_error_with_message(
177                self.tcx,
178                DUMMY_SP,
179                format!("failed autoderef {}", pick.autoderefs),
180            );
181        };
182        assert_eq!(n, pick.autoderefs);
183
184        let mut adjustments = self.adjust_steps(&autoderef);
185        match pick.autoref_or_ptr_adjustment {
186            Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => {
187                let region = self.next_region_var(RegionVariableOrigin::Autoref(self.span));
188                // Type we're wrapping in a reference, used later for unsizing
189                let base_ty = target;
190
191                target = Ty::new_ref(self.tcx, region, target, mutbl);
192
193                // Method call receivers are the primary use case
194                // for two-phase borrows.
195                let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::Yes);
196
197                adjustments
198                    .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target });
199
200                if unsize {
201                    let unsized_ty = if let ty::Array(elem_ty, _) = base_ty.kind() {
202                        Ty::new_slice(self.tcx, *elem_ty)
203                    } else {
204                        bug!(
205                            "AutorefOrPtrAdjustment's unsize flag should only be set for array ty, found {}",
206                            base_ty
207                        )
208                    };
209                    target = Ty::new_ref(self.tcx, region, unsized_ty, mutbl.into());
210                    adjustments.push(Adjustment {
211                        kind: Adjust::Pointer(PointerCoercion::Unsize),
212                        target,
213                    });
214                }
215            }
216            Some(probe::AutorefOrPtrAdjustment::ToConstPtr) => {
217                target = match target.kind() {
218                    &ty::RawPtr(ty, mutbl) => {
219                        assert!(mutbl.is_mut());
220                        Ty::new_imm_ptr(self.tcx, ty)
221                    }
222                    other => panic!("Cannot adjust receiver type {other:?} to const ptr"),
223                };
224
225                adjustments.push(Adjustment {
226                    kind: Adjust::Pointer(PointerCoercion::MutToConstPointer),
227                    target,
228                });
229            }
230
231            Some(probe::AutorefOrPtrAdjustment::ReborrowPin(mutbl)) => {
232                let region = self.next_region_var(RegionVariableOrigin::Autoref(self.span));
233
234                target = match target.kind() {
235                    ty::Adt(pin, args) if self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => {
236                        let inner_ty = match args[0].expect_ty().kind() {
237                            ty::Ref(_, ty, _) => *ty,
238                            _ => bug!("Expected a reference type for argument to Pin"),
239                        };
240                        Ty::new_pinned_ref(self.tcx, region, inner_ty, mutbl)
241                    }
242                    _ => bug!("Cannot adjust receiver type for reborrowing pin of {target:?}"),
243                };
244
245                adjustments.push(Adjustment { kind: Adjust::ReborrowPin(mutbl), target });
246            }
247            None => {}
248        }
249
250        self.register_predicates(autoderef.into_obligations());
251
252        // Write out the final adjustments.
253        if !self.skip_record_for_diagnostics {
254            self.apply_adjustments(self.self_expr, adjustments);
255        }
256
257        target
258    }
259
260    /// Returns a set of generic parameters for the method *receiver* where all type and region
261    /// parameters are instantiated with fresh variables. This generic parameters does not include any
262    /// parameters declared on the method itself.
263    ///
264    /// Note that this generic parameters may include late-bound regions from the impl level. If so,
265    /// these are instantiated later in the `instantiate_method_sig` routine.
266    fn fresh_receiver_args(
267        &mut self,
268        self_ty: Ty<'tcx>,
269        pick: &probe::Pick<'tcx>,
270    ) -> GenericArgsRef<'tcx> {
271        match pick.kind {
272            probe::InherentImplPick => {
273                let impl_def_id = pick.item.container_id(self.tcx);
274                assert!(
275                    self.tcx.impl_trait_ref(impl_def_id).is_none(),
276                    "impl {impl_def_id:?} is not an inherent impl"
277                );
278                self.fresh_args_for_item(self.span, impl_def_id)
279            }
280
281            probe::ObjectPick => {
282                let trait_def_id = pick.item.container_id(self.tcx);
283
284                // If the trait is not object safe (specifically, we care about when
285                // the receiver is not valid), then there's a chance that we will not
286                // actually be able to recover the object by derefing the receiver like
287                // we should if it were valid.
288                if !self.tcx.is_dyn_compatible(trait_def_id) {
289                    return ty::GenericArgs::extend_with_error(self.tcx, trait_def_id, &[]);
290                }
291
292                // This shouldn't happen for non-region error kinds, but may occur
293                // when we have error regions. Specifically, since we canonicalize
294                // during method steps, we may successfully deref when we assemble
295                // the pick, but fail to deref when we try to extract the object
296                // type from the pick during confirmation. This is fine, we're basically
297                // already doomed by this point.
298                if self_ty.references_error() {
299                    return ty::GenericArgs::extend_with_error(self.tcx, trait_def_id, &[]);
300                }
301
302                self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| {
303                    // The object data has no entry for the Self
304                    // Type. For the purposes of this method call, we
305                    // instantiate the object type itself. This
306                    // wouldn't be a sound instantiation in all cases,
307                    // since each instance of the object type is a
308                    // different existential and hence could match
309                    // distinct types (e.g., if `Self` appeared as an
310                    // argument type), but those cases have already
311                    // been ruled out when we deemed the trait to be
312                    // "dyn-compatible".
313                    let original_poly_trait_ref = principal.with_self_ty(this.tcx, object_ty);
314                    let upcast_poly_trait_ref = this.upcast(original_poly_trait_ref, trait_def_id);
315                    let upcast_trait_ref =
316                        this.instantiate_binder_with_fresh_vars(upcast_poly_trait_ref);
317                    debug!(
318                        "original_poly_trait_ref={:?} upcast_trait_ref={:?} target_trait={:?}",
319                        original_poly_trait_ref, upcast_trait_ref, trait_def_id
320                    );
321                    upcast_trait_ref.args
322                })
323            }
324
325            probe::TraitPick => {
326                let trait_def_id = pick.item.container_id(self.tcx);
327
328                // Make a trait reference `$0 : Trait<$1...$n>`
329                // consisting entirely of type variables. Later on in
330                // the process we will unify the transformed-self-type
331                // of the method with the actual type in order to
332                // unify some of these variables.
333                self.fresh_args_for_item(self.span, trait_def_id)
334            }
335
336            probe::WhereClausePick(poly_trait_ref) => {
337                // Where clauses can have bound regions in them. We need to instantiate
338                // those to convert from a poly-trait-ref to a trait-ref.
339                self.instantiate_binder_with_fresh_vars(poly_trait_ref).args
340            }
341        }
342    }
343
344    fn extract_existential_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R
345    where
346        F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>) -> R,
347    {
348        // If we specified that this is an object method, then the
349        // self-type ought to be something that can be dereferenced to
350        // yield an object-type (e.g., `&Object` or `Box<Object>`
351        // etc).
352
353        let mut autoderef = self.fcx.autoderef(self.span, self_ty);
354
355        // We don't need to gate this behind arbitrary self types
356        // per se, but it does make things a bit more gated.
357        if self.tcx.features().arbitrary_self_types()
358            || self.tcx.features().arbitrary_self_types_pointers()
359        {
360            autoderef = autoderef.use_receiver_trait();
361        }
362
363        autoderef
364            .include_raw_pointers()
365            .find_map(|(ty, _)| match ty.kind() {
366                ty::Dynamic(data, ..) => Some(closure(
367                    self,
368                    ty,
369                    data.principal().unwrap_or_else(|| {
370                        span_bug!(self.span, "calling trait method on empty object?")
371                    }),
372                )),
373                _ => None,
374            })
375            .unwrap_or_else(|| {
376                span_bug!(
377                    self.span,
378                    "self-type `{}` for ObjectPick never dereferenced to an object",
379                    self_ty
380                )
381            })
382    }
383
384    fn instantiate_method_args(
385        &mut self,
386        pick: &probe::Pick<'tcx>,
387        seg: &hir::PathSegment<'tcx>,
388        parent_args: GenericArgsRef<'tcx>,
389    ) -> GenericArgsRef<'tcx> {
390        // Determine the values for the generic parameters of the method.
391        // If they were not explicitly supplied, just construct fresh
392        // variables.
393        let generics = self.tcx.generics_of(pick.item.def_id);
394
395        let arg_count_correct = check_generic_arg_count_for_call(
396            self.fcx,
397            pick.item.def_id,
398            generics,
399            seg,
400            IsMethodCall::Yes,
401        );
402
403        // Create generic parameters for early-bound lifetime parameters,
404        // combining parameters from the type and those from the method.
405        assert_eq!(generics.parent_count, parent_args.len());
406
407        struct GenericArgsCtxt<'a, 'tcx> {
408            cfcx: &'a ConfirmContext<'a, 'tcx>,
409            pick: &'a probe::Pick<'tcx>,
410            seg: &'a hir::PathSegment<'tcx>,
411        }
412        impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
413            fn args_for_def_id(
414                &mut self,
415                def_id: DefId,
416            ) -> (Option<&'a hir::GenericArgs<'tcx>>, bool) {
417                if def_id == self.pick.item.def_id {
418                    if let Some(data) = self.seg.args {
419                        return (Some(data), false);
420                    }
421                }
422                (None, false)
423            }
424
425            fn provided_kind(
426                &mut self,
427                preceding_args: &[ty::GenericArg<'tcx>],
428                param: &ty::GenericParamDef,
429                arg: &GenericArg<'tcx>,
430            ) -> ty::GenericArg<'tcx> {
431                match (&param.kind, arg) {
432                    (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => self
433                        .cfcx
434                        .fcx
435                        .lowerer()
436                        .lower_lifetime(lt, RegionInferReason::Param(param))
437                        .into(),
438                    (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
439                        // We handle the ambig portions of `Ty` in the match arms below
440                        self.cfcx.lower_ty(ty.as_unambig_ty()).raw.into()
441                    }
442                    (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
443                        self.cfcx.lower_ty(&inf.to_ty()).raw.into()
444                    }
445                    (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
446                        .cfcx
447                        // We handle the ambig portions of `ConstArg` in the match arms below
448                        .lower_const_arg(
449                            ct.as_unambig_ct(),
450                            FeedConstTy::Param(param.def_id, preceding_args),
451                        )
452                        .into(),
453                    (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
454                        self.cfcx.ct_infer(Some(param), inf.span).into()
455                    }
456                    (kind, arg) => {
457                        bug!("mismatched method arg kind {kind:?} in turbofish: {arg:?}")
458                    }
459                }
460            }
461
462            fn inferred_kind(
463                &mut self,
464                _preceding_args: &[ty::GenericArg<'tcx>],
465                param: &ty::GenericParamDef,
466                _infer_args: bool,
467            ) -> ty::GenericArg<'tcx> {
468                self.cfcx.var_for_def(self.cfcx.span, param)
469            }
470        }
471
472        let args = lower_generic_args(
473            self.fcx,
474            pick.item.def_id,
475            parent_args,
476            false,
477            None,
478            &arg_count_correct,
479            &mut GenericArgsCtxt { cfcx: self, pick, seg },
480        );
481
482        // When the method is confirmed, the `args` includes
483        // parameters from not just the method, but also the impl of
484        // the method -- in particular, the `Self` type will be fully
485        // resolved. However, those are not something that the "user
486        // specified" -- i.e., those types come from the inferred type
487        // of the receiver, not something the user wrote. So when we
488        // create the user-args, we want to replace those earlier
489        // types with just the types that the user actually wrote --
490        // that is, those that appear on the *method itself*.
491        //
492        // As an example, if the user wrote something like
493        // `foo.bar::<u32>(...)` -- the `Self` type here will be the
494        // type of `foo` (possibly adjusted), but we don't want to
495        // include that. We want just the `[_, u32]` part.
496        if !args.is_empty() && !generics.is_own_empty() {
497            let user_type_annotation = self.probe(|_| {
498                let user_args = UserArgs {
499                    args: GenericArgs::for_item(self.tcx, pick.item.def_id, |param, _| {
500                        let i = param.index as usize;
501                        if i < generics.parent_count {
502                            self.fcx.var_for_def(DUMMY_SP, param)
503                        } else {
504                            args[i]
505                        }
506                    }),
507                    user_self_ty: None, // not relevant here
508                };
509
510                self.fcx.canonicalize_user_type_annotation(ty::UserType::new(
511                    ty::UserTypeKind::TypeOf(pick.item.def_id, user_args),
512                ))
513            });
514
515            debug!("instantiate_method_args: user_type_annotation={:?}", user_type_annotation);
516
517            if !self.skip_record_for_diagnostics {
518                self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
519            }
520        }
521
522        self.normalize(self.span, args)
523    }
524
525    fn unify_receivers(
526        &mut self,
527        self_ty: Ty<'tcx>,
528        method_self_ty: Ty<'tcx>,
529        pick: &probe::Pick<'tcx>,
530    ) {
531        debug!(
532            "unify_receivers: self_ty={:?} method_self_ty={:?} span={:?} pick={:?}",
533            self_ty, method_self_ty, self.span, pick
534        );
535        let cause = self.cause(self.self_expr.span, ObligationCauseCode::Misc);
536        match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) {
537            Ok(InferOk { obligations, value: () }) => {
538                self.register_predicates(obligations);
539            }
540            Err(terr) => {
541                if self.tcx.features().arbitrary_self_types() {
542                    self.err_ctxt()
543                        .report_mismatched_types(
544                            &cause,
545                            self.param_env,
546                            method_self_ty,
547                            self_ty,
548                            terr,
549                        )
550                        .emit();
551                } else {
552                    // This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
553                    // may run before wfcheck if the function is used in const eval.
554                    self.dcx().span_delayed_bug(
555                        cause.span,
556                        format!("{self_ty} was a subtype of {method_self_ty} but now is not?"),
557                    );
558                }
559            }
560        }
561    }
562
563    // NOTE: this returns the *unnormalized* predicates and method sig. Because of
564    // inference guessing, the predicates and method signature can't be normalized
565    // until we unify the `Self` type.
566    fn instantiate_method_sig(
567        &mut self,
568        pick: &probe::Pick<'tcx>,
569        all_args: GenericArgsRef<'tcx>,
570    ) -> (ty::FnSig<'tcx>, ty::InstantiatedPredicates<'tcx>) {
571        debug!("instantiate_method_sig(pick={:?}, all_args={:?})", pick, all_args);
572
573        // Instantiate the bounds on the method with the
574        // type/early-bound-regions instantiations performed. There can
575        // be no late-bound regions appearing here.
576        let def_id = pick.item.def_id;
577        let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args);
578
579        debug!("method_predicates after instantiation = {:?}", method_predicates);
580
581        let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args);
582        debug!("type scheme instantiated, sig={:?}", sig);
583
584        let sig = self.instantiate_binder_with_fresh_vars(sig);
585        debug!("late-bound lifetimes from method instantiated, sig={:?}", sig);
586
587        (sig, method_predicates)
588    }
589
590    fn add_obligations(
591        &mut self,
592        sig: ty::FnSig<'tcx>,
593        all_args: GenericArgsRef<'tcx>,
594        method_predicates: ty::InstantiatedPredicates<'tcx>,
595        def_id: DefId,
596    ) {
597        debug!(
598            "add_obligations: sig={:?} all_args={:?} method_predicates={:?} def_id={:?}",
599            sig, all_args, method_predicates, def_id
600        );
601
602        // FIXME: could replace with the following, but we already calculated `method_predicates`,
603        // so we just call `predicates_for_generics` directly to avoid redoing work.
604        // `self.add_required_obligations(self.span, def_id, &all_args);`
605        for obligation in traits::predicates_for_generics(
606            |idx, span| {
607                let code = ObligationCauseCode::WhereClauseInExpr(
608                    def_id,
609                    span,
610                    self.call_expr.hir_id,
611                    idx,
612                );
613                self.cause(self.span, code)
614            },
615            self.param_env,
616            method_predicates,
617        ) {
618            self.register_predicate(obligation);
619        }
620
621        // this is a projection from a trait reference, so we have to
622        // make sure that the trait reference inputs are well-formed.
623        self.add_wf_bounds(all_args, self.call_expr.span);
624
625        // the function type must also be well-formed (this is not
626        // implied by the args being well-formed because of inherent
627        // impls and late-bound regions - see issue #28609).
628        for ty in sig.inputs_and_output {
629            self.register_wf_obligation(
630                ty.into(),
631                self.span,
632                ObligationCauseCode::WellFormed(None),
633            );
634        }
635    }
636
637    ///////////////////////////////////////////////////////////////////////////
638    // MISCELLANY
639
640    fn predicates_require_illegal_sized_bound(
641        &self,
642        predicates: ty::InstantiatedPredicates<'tcx>,
643    ) -> Option<Span> {
644        let sized_def_id = self.tcx.lang_items().sized_trait()?;
645
646        traits::elaborate(self.tcx, predicates.predicates.iter().copied())
647            // We don't care about regions here.
648            .filter_map(|pred| match pred.kind().skip_binder() {
649                ty::ClauseKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => {
650                    let span = predicates
651                        .iter()
652                        .find_map(|(p, span)| if p == pred { Some(span) } else { None })
653                        .unwrap_or(DUMMY_SP);
654                    Some((trait_pred, span))
655                }
656                _ => None,
657            })
658            .find_map(|(trait_pred, span)| match trait_pred.self_ty().kind() {
659                ty::Dynamic(..) => Some(span),
660                _ => None,
661            })
662    }
663
664    fn check_for_illegal_method_calls(&self, pick: &probe::Pick<'_>) {
665        // Disallow calls to the method `drop` defined in the `Drop` trait.
666        if let Some(trait_def_id) = pick.item.trait_container(self.tcx)
667            && let Err(e) = callee::check_legal_trait_for_method_call(
668                self.tcx,
669                self.span,
670                Some(self.self_expr.span),
671                self.call_expr.span,
672                trait_def_id,
673                self.body_id.to_def_id(),
674            )
675        {
676            self.set_tainted_by_errors(e);
677        }
678    }
679
680    fn lint_shadowed_supertrait_items(
681        &self,
682        pick: &probe::Pick<'_>,
683        segment: &hir::PathSegment<'tcx>,
684    ) {
685        if pick.shadowed_candidates.is_empty() {
686            return;
687        }
688
689        let shadower_span = self.tcx.def_span(pick.item.def_id);
690        let subtrait = self.tcx.item_name(pick.item.trait_container(self.tcx).unwrap());
691        let shadower = SupertraitItemShadower { span: shadower_span, subtrait };
692
693        let shadowee = if let [shadowee] = &pick.shadowed_candidates[..] {
694            let shadowee_span = self.tcx.def_span(shadowee.def_id);
695            let supertrait = self.tcx.item_name(shadowee.trait_container(self.tcx).unwrap());
696            SupertraitItemShadowee::Labeled { span: shadowee_span, supertrait }
697        } else {
698            let (traits, spans): (Vec<_>, Vec<_>) = pick
699                .shadowed_candidates
700                .iter()
701                .map(|item| {
702                    (
703                        self.tcx.item_name(item.trait_container(self.tcx).unwrap()),
704                        self.tcx.def_span(item.def_id),
705                    )
706                })
707                .unzip();
708            SupertraitItemShadowee::Several { traits: traits.into(), spans: spans.into() }
709        };
710
711        self.tcx.emit_node_span_lint(
712            SUPERTRAIT_ITEM_SHADOWING_USAGE,
713            segment.hir_id,
714            segment.ident.span,
715            SupertraitItemShadowing { shadower, shadowee, item: segment.ident.name, subtrait },
716        );
717    }
718
719    fn upcast(
720        &mut self,
721        source_trait_ref: ty::PolyTraitRef<'tcx>,
722        target_trait_def_id: DefId,
723    ) -> ty::PolyTraitRef<'tcx> {
724        let upcast_trait_refs =
725            traits::upcast_choices(self.tcx, source_trait_ref, target_trait_def_id);
726
727        // must be exactly one trait ref or we'd get an ambig error etc
728        if let &[upcast_trait_ref] = upcast_trait_refs.as_slice() {
729            upcast_trait_ref
730        } else {
731            self.dcx().span_delayed_bug(
732                self.span,
733                format!(
734                    "cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`",
735                    source_trait_ref, target_trait_def_id, upcast_trait_refs
736                ),
737            );
738
739            ty::Binder::dummy(ty::TraitRef::new_from_args(
740                self.tcx,
741                target_trait_def_id,
742                ty::GenericArgs::extend_with_error(self.tcx, target_trait_def_id, &[]),
743            ))
744        }
745    }
746
747    fn instantiate_binder_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T
748    where
749        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
750    {
751        self.fcx.instantiate_binder_with_fresh_vars(
752            self.span,
753            BoundRegionConversionTime::FnCall,
754            value,
755        )
756    }
757}