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