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