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