rustc_hir_analysis/check/
compare_impl_item.rs

1use core::ops::ControlFlow;
2use std::borrow::Cow;
3use std::iter;
4
5use hir::def_id::{DefId, DefIdMap, LocalDefId};
6use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
7use rustc_errors::codes::*;
8use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
9use rustc_hir::def::{DefKind, Res};
10use rustc_hir::intravisit::VisitorExt;
11use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
12use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
13use rustc_infer::traits::util;
14use rustc_middle::ty::error::{ExpectedFound, TypeError};
15use rustc_middle::ty::fold::BottomUpFolder;
16use rustc_middle::ty::util::ExplicitSelf;
17use rustc_middle::ty::{
18    self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
19    TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
20};
21use rustc_middle::{bug, span_bug};
22use rustc_span::Span;
23use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
24use rustc_trait_selection::infer::InferCtxtExt;
25use rustc_trait_selection::regions::InferCtxtRegionExt;
26use rustc_trait_selection::traits::{
27    self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
28};
29use tracing::{debug, instrument};
30
31use super::potentially_plural_count;
32use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
33
34pub(super) mod refine;
35
36/// Call the query `tcx.compare_impl_item()` directly instead.
37pub(super) fn compare_impl_item(
38    tcx: TyCtxt<'_>,
39    impl_item_def_id: LocalDefId,
40) -> Result<(), ErrorGuaranteed> {
41    let impl_item = tcx.associated_item(impl_item_def_id);
42    let trait_item = tcx.associated_item(impl_item.trait_item_def_id.unwrap());
43    let impl_trait_ref =
44        tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity();
45    debug!(?impl_trait_ref);
46
47    match impl_item.kind {
48        ty::AssocKind::Fn => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
49        ty::AssocKind::Type => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref),
50        ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref),
51    }
52}
53
54/// Checks that a method from an impl conforms to the signature of
55/// the same method as declared in the trait.
56///
57/// # Parameters
58///
59/// - `impl_m`: type of the method we are checking
60/// - `trait_m`: the method in the trait
61/// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
62#[instrument(level = "debug", skip(tcx))]
63fn compare_impl_method<'tcx>(
64    tcx: TyCtxt<'tcx>,
65    impl_m: ty::AssocItem,
66    trait_m: ty::AssocItem,
67    impl_trait_ref: ty::TraitRef<'tcx>,
68) -> Result<(), ErrorGuaranteed> {
69    check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
70    compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
71    Ok(())
72}
73
74/// Checks a bunch of different properties of the impl/trait methods for
75/// compatibility, such as asyncness, number of argument, self receiver kind,
76/// and number of early- and late-bound generics.
77fn check_method_is_structurally_compatible<'tcx>(
78    tcx: TyCtxt<'tcx>,
79    impl_m: ty::AssocItem,
80    trait_m: ty::AssocItem,
81    impl_trait_ref: ty::TraitRef<'tcx>,
82    delay: bool,
83) -> Result<(), ErrorGuaranteed> {
84    compare_self_type(tcx, impl_m, trait_m, impl_trait_ref, delay)?;
85    compare_number_of_generics(tcx, impl_m, trait_m, delay)?;
86    compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
87    compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
88    compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
89    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
90    Ok(())
91}
92
93/// This function is best explained by example. Consider a trait with its implementation:
94///
95/// ```rust
96/// trait Trait<'t, T> {
97///     // `trait_m`
98///     fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
99/// }
100///
101/// struct Foo;
102///
103/// impl<'i, 'j, U> Trait<'j, &'i U> for Foo {
104///     // `impl_m`
105///     fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo { Foo }
106/// }
107/// ```
108///
109/// We wish to decide if those two method types are compatible.
110/// For this we have to show that, assuming the bounds of the impl hold, the
111/// bounds of `trait_m` imply the bounds of `impl_m`.
112///
113/// We start out with `trait_to_impl_args`, that maps the trait
114/// type parameters to impl type parameters. This is taken from the
115/// impl trait reference:
116///
117/// ```rust,ignore (pseudo-Rust)
118/// trait_to_impl_args = {'t => 'j, T => &'i U, Self => Foo}
119/// ```
120///
121/// We create a mapping `dummy_args` that maps from the impl type
122/// parameters to fresh types and regions. For type parameters,
123/// this is the identity transform, but we could as well use any
124/// placeholder types. For regions, we convert from bound to free
125/// regions (Note: but only early-bound regions, i.e., those
126/// declared on the impl or used in type parameter bounds).
127///
128/// ```rust,ignore (pseudo-Rust)
129/// impl_to_placeholder_args = {'i => 'i0, U => U0, N => N0 }
130/// ```
131///
132/// Now we can apply `placeholder_args` to the type of the impl method
133/// to yield a new function type in terms of our fresh, placeholder
134/// types:
135///
136/// ```rust,ignore (pseudo-Rust)
137/// <'b> fn(t: &'i0 U0, m: &'b N0) -> Foo
138/// ```
139///
140/// We now want to extract and instantiate the type of the *trait*
141/// method and compare it. To do so, we must create a compound
142/// instantiation by combining `trait_to_impl_args` and
143/// `impl_to_placeholder_args`, and also adding a mapping for the method
144/// type parameters. We extend the mapping to also include
145/// the method parameters.
146///
147/// ```rust,ignore (pseudo-Rust)
148/// trait_to_placeholder_args = { T => &'i0 U0, Self => Foo, M => N0 }
149/// ```
150///
151/// Applying this to the trait method type yields:
152///
153/// ```rust,ignore (pseudo-Rust)
154/// <'a> fn(t: &'i0 U0, m: &'a N0) -> Foo
155/// ```
156///
157/// This type is also the same but the name of the bound region (`'a`
158/// vs `'b`). However, the normal subtyping rules on fn types handle
159/// this kind of equivalency just fine.
160///
161/// We now use these generic parameters to ensure that all declared bounds
162/// are satisfied by the implementation's method.
163///
164/// We do this by creating a parameter environment which contains a
165/// generic parameter corresponding to `impl_to_placeholder_args`. We then build
166/// `trait_to_placeholder_args` and use it to convert the predicates contained
167/// in the `trait_m` generics to the placeholder form.
168///
169/// Finally we register each of these predicates as an obligation and check that
170/// they hold.
171#[instrument(level = "debug", skip(tcx, impl_trait_ref))]
172fn compare_method_predicate_entailment<'tcx>(
173    tcx: TyCtxt<'tcx>,
174    impl_m: ty::AssocItem,
175    trait_m: ty::AssocItem,
176    impl_trait_ref: ty::TraitRef<'tcx>,
177) -> Result<(), ErrorGuaranteed> {
178    // This node-id should be used for the `body_id` field on each
179    // `ObligationCause` (and the `FnCtxt`).
180    //
181    // FIXME(@lcnr): remove that after removing `cause.body_id` from
182    // obligations.
183    let impl_m_def_id = impl_m.def_id.expect_local();
184    let impl_m_span = tcx.def_span(impl_m_def_id);
185    let cause = ObligationCause::new(
186        impl_m_span,
187        impl_m_def_id,
188        ObligationCauseCode::CompareImplItem {
189            impl_item_def_id: impl_m_def_id,
190            trait_item_def_id: trait_m.def_id,
191            kind: impl_m.kind,
192        },
193    );
194
195    // Create mapping from trait method to impl method.
196    let impl_def_id = impl_m.container_id(tcx);
197    let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
198        tcx,
199        impl_m.container_id(tcx),
200        impl_trait_ref.args,
201    );
202    debug!(?trait_to_impl_args);
203
204    let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
205    let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
206
207    // This is the only tricky bit of the new way we check implementation methods
208    // We need to build a set of predicates where only the method-level bounds
209    // are from the trait and we assume all other bounds from the implementation
210    // to be previously satisfied.
211    //
212    // We then register the obligations from the impl_m and check to see
213    // if all constraints hold.
214    let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap());
215    let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates;
216    hybrid_preds.extend(
217        trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
218    );
219
220    let is_conditionally_const = tcx.is_conditionally_const(impl_def_id);
221    if is_conditionally_const {
222        // Augment the hybrid param-env with the const conditions
223        // of the impl header and the trait method.
224        hybrid_preds.extend(
225            tcx.const_conditions(impl_def_id)
226                .instantiate_identity(tcx)
227                .into_iter()
228                .chain(
229                    tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args),
230                )
231                .map(|(trait_ref, _)| {
232                    trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe)
233                }),
234        );
235    }
236
237    let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
238    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
239    let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
240    debug!(caller_bounds=?param_env.caller_bounds());
241
242    let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
243    let ocx = ObligationCtxt::new_with_diagnostics(infcx);
244
245    // Create obligations for each predicate declared by the impl
246    // definition in the context of the hybrid param-env. This makes
247    // sure that the impl's method's where clauses are not more
248    // restrictive than the trait's method (and the impl itself).
249    let impl_m_own_bounds = impl_m_predicates.instantiate_own_identity();
250    for (predicate, span) in impl_m_own_bounds {
251        let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
252        let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
253
254        let cause = ObligationCause::new(
255            span,
256            impl_m_def_id,
257            ObligationCauseCode::CompareImplItem {
258                impl_item_def_id: impl_m_def_id,
259                trait_item_def_id: trait_m.def_id,
260                kind: impl_m.kind,
261            },
262        );
263        ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
264    }
265
266    // If we're within a const implementation, we need to make sure that the method
267    // does not assume stronger `~const` bounds than the trait definition.
268    //
269    // This registers the `~const` bounds of the impl method, which we will prove
270    // using the hybrid param-env that we earlier augmented with the const conditions
271    // from the impl header and trait method declaration.
272    if is_conditionally_const {
273        for (const_condition, span) in
274            tcx.const_conditions(impl_m.def_id).instantiate_own_identity()
275        {
276            let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
277            let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
278
279            let cause = ObligationCause::new(
280                span,
281                impl_m_def_id,
282                ObligationCauseCode::CompareImplItem {
283                    impl_item_def_id: impl_m_def_id,
284                    trait_item_def_id: trait_m.def_id,
285                    kind: impl_m.kind,
286                },
287            );
288            ocx.register_obligation(traits::Obligation::new(
289                tcx,
290                cause,
291                param_env,
292                const_condition.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
293            ));
294        }
295    }
296
297    // We now need to check that the signature of the impl method is
298    // compatible with that of the trait method. We do this by
299    // checking that `impl_fty <: trait_fty`.
300    //
301    // FIXME. Unfortunately, this doesn't quite work right now because
302    // associated type normalization is not integrated into subtype
303    // checks. For the comparison to be valid, we need to
304    // normalize the associated types in the impl/trait methods
305    // first. However, because function types bind regions, just
306    // calling `FnCtxt::normalize` would have no effect on
307    // any associated types appearing in the fn arguments or return
308    // type.
309
310    let mut wf_tys = FxIndexSet::default();
311
312    let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
313        impl_m_span,
314        infer::HigherRankedType,
315        tcx.fn_sig(impl_m.def_id).instantiate_identity(),
316    );
317
318    let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id);
319    let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
320    debug!(?impl_sig);
321
322    let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args);
323    let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
324
325    // Next, add all inputs and output as well-formed tys. Importantly,
326    // we have to do this before normalization, since the normalized ty may
327    // not contain the input parameters. See issue #87748.
328    wf_tys.extend(trait_sig.inputs_and_output.iter());
329    let trait_sig = ocx.normalize(&norm_cause, param_env, trait_sig);
330    // We also have to add the normalized trait signature
331    // as we don't normalize during implied bounds computation.
332    wf_tys.extend(trait_sig.inputs_and_output.iter());
333    debug!(?trait_sig);
334
335    // FIXME: We'd want to keep more accurate spans than "the method signature" when
336    // processing the comparison between the trait and impl fn, but we sadly lose them
337    // and point at the whole signature when a trait bound or specific input or output
338    // type would be more appropriate. In other places we have a `Vec<Span>`
339    // corresponding to their `Vec<Predicate>`, but we don't have that here.
340    // Fixing this would improve the output of test `issue-83765.rs`.
341    let result = ocx.sup(&cause, param_env, trait_sig, impl_sig);
342
343    if let Err(terr) = result {
344        debug!(?impl_sig, ?trait_sig, ?terr, "sub_types failed");
345
346        let emitted = report_trait_method_mismatch(
347            infcx,
348            cause,
349            param_env,
350            terr,
351            (trait_m, trait_sig),
352            (impl_m, impl_sig),
353            impl_trait_ref,
354        );
355        return Err(emitted);
356    }
357
358    if !(impl_sig, trait_sig).references_error() {
359        // Select obligations to make progress on inference before processing
360        // the wf obligation below.
361        // FIXME(-Znext-solver): Not needed when the hack below is removed.
362        let errors = ocx.select_where_possible();
363        if !errors.is_empty() {
364            let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
365            return Err(reported);
366        }
367
368        // See #108544. Annoying, we can end up in cases where, because of winnowing,
369        // we pick param env candidates over a more general impl, leading to more
370        // stricter lifetime requirements than we would otherwise need. This can
371        // trigger the lint. Instead, let's only consider type outlives and
372        // region outlives obligations.
373        //
374        // FIXME(-Znext-solver): Try removing this hack again once the new
375        // solver is stable. We should just be able to register a WF pred for
376        // the fn sig.
377        let mut wf_args: smallvec::SmallVec<[_; 4]> =
378            unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
379        // Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
380        // will give back the well-formed predicate of the same array.
381        let mut wf_args_seen: FxHashSet<_> = wf_args.iter().copied().collect();
382        while let Some(arg) = wf_args.pop() {
383            let Some(obligations) = rustc_trait_selection::traits::wf::obligations(
384                infcx,
385                param_env,
386                impl_m_def_id,
387                0,
388                arg,
389                impl_m_span,
390            ) else {
391                continue;
392            };
393            for obligation in obligations {
394                debug!(?obligation);
395                match obligation.predicate.kind().skip_binder() {
396                    // We need to register Projection oblgiations too, because we may end up with
397                    // an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
398                    // If we only register the region outlives obligation, this leads to an unconstrained var.
399                    // See `implied_bounds_entailment_alias_var.rs` test.
400                    ty::PredicateKind::Clause(
401                        ty::ClauseKind::RegionOutlives(..)
402                        | ty::ClauseKind::TypeOutlives(..)
403                        | ty::ClauseKind::Projection(..),
404                    ) => ocx.register_obligation(obligation),
405                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
406                        if wf_args_seen.insert(arg) {
407                            wf_args.push(arg)
408                        }
409                    }
410                    _ => {}
411                }
412            }
413        }
414    }
415
416    // Check that all obligations are satisfied by the implementation's
417    // version.
418    let errors = ocx.select_all_or_error();
419    if !errors.is_empty() {
420        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
421        return Err(reported);
422    }
423
424    // Finally, resolve all regions. This catches wily misuses of
425    // lifetime parameters.
426    let errors = infcx.resolve_regions(impl_m_def_id, param_env, wf_tys);
427    if !errors.is_empty() {
428        return Err(infcx
429            .tainted_by_errors()
430            .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors)));
431    }
432
433    Ok(())
434}
435
436struct RemapLateParam<'tcx> {
437    tcx: TyCtxt<'tcx>,
438    mapping: FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>,
439}
440
441impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
442    fn cx(&self) -> TyCtxt<'tcx> {
443        self.tcx
444    }
445
446    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
447        if let ty::ReLateParam(fr) = *r {
448            ty::Region::new_late_param(
449                self.tcx,
450                fr.scope,
451                self.mapping.get(&fr.kind).copied().unwrap_or(fr.kind),
452            )
453        } else {
454            r
455        }
456    }
457}
458
459/// Given a method def-id in an impl, compare the method signature of the impl
460/// against the trait that it's implementing. In doing so, infer the hidden types
461/// that this method's signature provides to satisfy each return-position `impl Trait`
462/// in the trait signature.
463///
464/// The method is also responsible for making sure that the hidden types for each
465/// RPITIT actually satisfy the bounds of the `impl Trait`, i.e. that if we infer
466/// `impl Trait = Foo`, that `Foo: Trait` holds.
467///
468/// For example, given the sample code:
469///
470/// ```
471/// use std::ops::Deref;
472///
473/// trait Foo {
474///     fn bar() -> impl Deref<Target = impl Sized>;
475///              // ^- RPITIT #1        ^- RPITIT #2
476/// }
477///
478/// impl Foo for () {
479///     fn bar() -> Box<String> { Box::new(String::new()) }
480/// }
481/// ```
482///
483/// The hidden types for the RPITITs in `bar` would be inferred to:
484///     * `impl Deref` (RPITIT #1) = `Box<String>`
485///     * `impl Sized` (RPITIT #2) = `String`
486///
487/// The relationship between these two types is straightforward in this case, but
488/// may be more tenuously connected via other `impl`s and normalization rules for
489/// cases of more complicated nested RPITITs.
490#[instrument(skip(tcx), level = "debug", ret)]
491pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
492    tcx: TyCtxt<'tcx>,
493    impl_m_def_id: LocalDefId,
494) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
495    let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
496    let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
497    let impl_trait_ref =
498        tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
499    // First, check a few of the same things as `compare_impl_method`,
500    // just so we don't ICE during instantiation later.
501    check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
502
503    let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
504    let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
505    let cause = ObligationCause::new(
506        return_span,
507        impl_m_def_id,
508        ObligationCauseCode::CompareImplItem {
509            impl_item_def_id: impl_m_def_id,
510            trait_item_def_id: trait_m.def_id,
511            kind: impl_m.kind,
512        },
513    );
514
515    // Create mapping from trait to impl (i.e. impl trait header + impl method identity args).
516    let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
517        tcx,
518        impl_m.container_id(tcx),
519        impl_trait_ref.args,
520    );
521
522    let hybrid_preds = tcx
523        .predicates_of(impl_m.container_id(tcx))
524        .instantiate_identity(tcx)
525        .into_iter()
526        .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args))
527        .map(|(clause, _)| clause);
528    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
529    let param_env = traits::normalize_param_env_or_error(
530        tcx,
531        param_env,
532        ObligationCause::misc(tcx.def_span(impl_m_def_id), impl_m_def_id),
533    );
534
535    let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
536    let ocx = ObligationCtxt::new_with_diagnostics(infcx);
537
538    // Check that the where clauses of the impl are satisfied by the hybrid param env.
539    // You might ask -- what does this have to do with RPITIT inference? Nothing.
540    // We check these because if the where clauses of the signatures do not match
541    // up, then we don't want to give spurious other errors that point at the RPITITs.
542    // They're not necessary to check, though, because we already check them in
543    // `compare_method_predicate_entailment`.
544    let impl_m_own_bounds = tcx.predicates_of(impl_m_def_id).instantiate_own_identity();
545    for (predicate, span) in impl_m_own_bounds {
546        let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
547        let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
548
549        let cause = ObligationCause::new(
550            span,
551            impl_m_def_id,
552            ObligationCauseCode::CompareImplItem {
553                impl_item_def_id: impl_m_def_id,
554                trait_item_def_id: trait_m.def_id,
555                kind: impl_m.kind,
556            },
557        );
558        ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
559    }
560
561    // Normalize the impl signature with fresh variables for lifetime inference.
562    let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
563    let impl_sig = ocx.normalize(
564        &misc_cause,
565        param_env,
566        infcx.instantiate_binder_with_fresh_vars(
567            return_span,
568            infer::HigherRankedType,
569            tcx.fn_sig(impl_m.def_id).instantiate_identity(),
570        ),
571    );
572    impl_sig.error_reported()?;
573    let impl_return_ty = impl_sig.output();
574
575    // Normalize the trait signature with liberated bound vars, passing it through
576    // the ImplTraitInTraitCollector, which gathers all of the RPITITs and replaces
577    // them with inference variables.
578    // We will use these inference variables to collect the hidden types of RPITITs.
579    let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id);
580    let unnormalized_trait_sig = tcx
581        .liberate_late_bound_regions(
582            impl_m.def_id,
583            tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
584        )
585        .fold_with(&mut collector);
586
587    let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig);
588    trait_sig.error_reported()?;
589    let trait_return_ty = trait_sig.output();
590
591    // RPITITs are allowed to use the implied predicates of the method that
592    // defines them. This is because we want code like:
593    // ```
594    // trait Foo {
595    //     fn test<'a, T>(_: &'a T) -> impl Sized;
596    // }
597    // impl Foo for () {
598    //     fn test<'a, T>(x: &'a T) -> &'a T { x }
599    // }
600    // ```
601    // .. to compile. However, since we use both the normalized and unnormalized
602    // inputs and outputs from the instantiated trait signature, we will end up
603    // seeing the hidden type of an RPIT in the signature itself. Naively, this
604    // means that we will use the hidden type to imply the hidden type's own
605    // well-formedness.
606    //
607    // To avoid this, we replace the infer vars used for hidden type inference
608    // with placeholders, which imply nothing about outlives bounds, and then
609    // prove below that the hidden types are well formed.
610    let universe = infcx.create_next_universe();
611    let mut idx = 0;
612    let mapping: FxIndexMap<_, _> = collector
613        .types
614        .iter()
615        .map(|(_, &(ty, _))| {
616            assert!(
617                infcx.resolve_vars_if_possible(ty) == ty && ty.is_ty_var(),
618                "{ty:?} should not have been constrained via normalization",
619                ty = infcx.resolve_vars_if_possible(ty)
620            );
621            idx += 1;
622            (
623                ty,
624                Ty::new_placeholder(
625                    tcx,
626                    ty::Placeholder {
627                        universe,
628                        bound: ty::BoundTy {
629                            var: ty::BoundVar::from_usize(idx),
630                            kind: ty::BoundTyKind::Anon,
631                        },
632                    },
633                ),
634            )
635        })
636        .collect();
637    let mut type_mapper = BottomUpFolder {
638        tcx,
639        ty_op: |ty| *mapping.get(&ty).unwrap_or(&ty),
640        lt_op: |lt| lt,
641        ct_op: |ct| ct,
642    };
643    let wf_tys = FxIndexSet::from_iter(
644        unnormalized_trait_sig
645            .inputs_and_output
646            .iter()
647            .chain(trait_sig.inputs_and_output.iter())
648            .map(|ty| ty.fold_with(&mut type_mapper)),
649    );
650
651    match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) {
652        Ok(()) => {}
653        Err(terr) => {
654            let mut diag = struct_span_code_err!(
655                tcx.dcx(),
656                cause.span,
657                E0053,
658                "method `{}` has an incompatible return type for trait",
659                trait_m.name
660            );
661            let hir = tcx.hir();
662            infcx.err_ctxt().note_type_err(
663                &mut diag,
664                &cause,
665                hir.get_if_local(impl_m.def_id)
666                    .and_then(|node| node.fn_decl())
667                    .map(|decl| (decl.output.span(), Cow::from("return type in trait"), false)),
668                Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound {
669                    expected: trait_return_ty.into(),
670                    found: impl_return_ty.into(),
671                }))),
672                terr,
673                false,
674                None,
675            );
676            return Err(diag.emit());
677        }
678    }
679
680    debug!(?trait_sig, ?impl_sig, "equating function signatures");
681
682    // Unify the whole function signature. We need to do this to fully infer
683    // the lifetimes of the return type, but do this after unifying just the
684    // return types, since we want to avoid duplicating errors from
685    // `compare_method_predicate_entailment`.
686    match ocx.eq(&cause, param_env, trait_sig, impl_sig) {
687        Ok(()) => {}
688        Err(terr) => {
689            // This function gets called during `compare_method_predicate_entailment` when normalizing a
690            // signature that contains RPITIT. When the method signatures don't match, we have to
691            // emit an error now because `compare_method_predicate_entailment` will not report the error
692            // when normalization fails.
693            let emitted = report_trait_method_mismatch(
694                infcx,
695                cause,
696                param_env,
697                terr,
698                (trait_m, trait_sig),
699                (impl_m, impl_sig),
700                impl_trait_ref,
701            );
702            return Err(emitted);
703        }
704    }
705
706    if !unnormalized_trait_sig.output().references_error() && collector.types.is_empty() {
707        tcx.dcx().delayed_bug(
708            "expect >0 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`",
709        );
710    }
711
712    // FIXME: This has the same issue as #108544, but since this isn't breaking
713    // existing code, I'm not particularly inclined to do the same hack as above
714    // where we process wf obligations manually. This can be fixed in a forward-
715    // compatible way later.
716    let collected_types = collector.types;
717    for (_, &(ty, _)) in &collected_types {
718        ocx.register_obligation(traits::Obligation::new(
719            tcx,
720            misc_cause.clone(),
721            param_env,
722            ty::ClauseKind::WellFormed(ty.into()),
723        ));
724    }
725
726    // Check that all obligations are satisfied by the implementation's
727    // RPITs.
728    let errors = ocx.select_all_or_error();
729    if !errors.is_empty() {
730        if let Err(guar) = try_report_async_mismatch(tcx, infcx, &errors, trait_m, impl_m, impl_sig)
731        {
732            return Err(guar);
733        }
734
735        let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
736        return Err(guar);
737    }
738
739    // Finally, resolve all regions. This catches wily misuses of
740    // lifetime parameters.
741    ocx.resolve_regions_and_report_errors(impl_m_def_id, param_env, wf_tys)?;
742
743    let mut remapped_types = DefIdMap::default();
744    for (def_id, (ty, args)) in collected_types {
745        match infcx.fully_resolve(ty) {
746            Ok(ty) => {
747                // `ty` contains free regions that we created earlier while liberating the
748                // trait fn signature. However, projection normalization expects `ty` to
749                // contains `def_id`'s early-bound regions.
750                let id_args = GenericArgs::identity_for_item(tcx, def_id);
751                debug!(?id_args, ?args);
752                let map: FxIndexMap<_, _> = std::iter::zip(args, id_args)
753                    .skip(tcx.generics_of(trait_m.def_id).count())
754                    .filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
755                    .collect();
756                debug!(?map);
757
758                // NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
759                // region args that are synthesized during AST lowering. These are args
760                // that are appended to the parent args (trait and trait method). However,
761                // we're trying to infer the uninstantiated type value of the RPITIT inside
762                // the *impl*, so we can later use the impl's method args to normalize
763                // an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`).
764                //
765                // Due to the design of RPITITs, during AST lowering, we have no idea that
766                // an impl method corresponds to a trait method with RPITITs in it. Therefore,
767                // we don't have a list of early-bound region args for the RPITIT in the impl.
768                // Since early region parameters are index-based, we can't just rebase these
769                // (trait method) early-bound region args onto the impl, and there's no
770                // guarantee that the indices from the trait args and impl args line up.
771                // So to fix this, we subtract the number of trait args and add the number of
772                // impl args to *renumber* these early-bound regions to their corresponding
773                // indices in the impl's generic parameters list.
774                //
775                // Also, we only need to account for a difference in trait and impl args,
776                // since we previously enforce that the trait method and impl method have the
777                // same generics.
778                let num_trait_args = impl_trait_ref.args.len();
779                let num_impl_args = tcx.generics_of(impl_m.container_id(tcx)).own_params.len();
780                let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
781                    tcx,
782                    map,
783                    num_trait_args,
784                    num_impl_args,
785                    def_id,
786                    impl_m_def_id: impl_m.def_id,
787                    ty,
788                    return_span,
789                }) {
790                    Ok(ty) => ty,
791                    Err(guar) => Ty::new_error(tcx, guar),
792                };
793                remapped_types.insert(def_id, ty::EarlyBinder::bind(ty));
794            }
795            Err(err) => {
796                // This code path is not reached in any tests, but may be
797                // reachable. If this is triggered, it should be converted to
798                // `span_delayed_bug` and the triggering case turned into a
799                // test.
800                tcx.dcx()
801                    .span_bug(return_span, format!("could not fully resolve: {ty} => {err:?}"));
802            }
803        }
804    }
805
806    // We may not collect all RPITITs that we see in the HIR for a trait signature
807    // because an RPITIT was located within a missing item. Like if we have a sig
808    // returning `-> Missing<impl Sized>`, that gets converted to `-> {type error}`,
809    // and when walking through the signature we end up never collecting the def id
810    // of the `impl Sized`. Insert that here, so we don't ICE later.
811    for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) {
812        if !remapped_types.contains_key(assoc_item) {
813            remapped_types.insert(
814                *assoc_item,
815                ty::EarlyBinder::bind(Ty::new_error_with_message(
816                    tcx,
817                    return_span,
818                    "missing synthetic item for RPITIT",
819                )),
820            );
821        }
822    }
823
824    Ok(&*tcx.arena.alloc(remapped_types))
825}
826
827struct ImplTraitInTraitCollector<'a, 'tcx, E> {
828    ocx: &'a ObligationCtxt<'a, 'tcx, E>,
829    types: FxIndexMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
830    span: Span,
831    param_env: ty::ParamEnv<'tcx>,
832    body_id: LocalDefId,
833}
834
835impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E>
836where
837    E: 'tcx,
838{
839    fn new(
840        ocx: &'a ObligationCtxt<'a, 'tcx, E>,
841        span: Span,
842        param_env: ty::ParamEnv<'tcx>,
843        body_id: LocalDefId,
844    ) -> Self {
845        ImplTraitInTraitCollector { ocx, types: FxIndexMap::default(), span, param_env, body_id }
846    }
847}
848
849impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E>
850where
851    E: 'tcx,
852{
853    fn cx(&self) -> TyCtxt<'tcx> {
854        self.ocx.infcx.tcx
855    }
856
857    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
858        if let ty::Alias(ty::Projection, proj) = ty.kind()
859            && self.cx().is_impl_trait_in_trait(proj.def_id)
860        {
861            if let Some((ty, _)) = self.types.get(&proj.def_id) {
862                return *ty;
863            }
864            //FIXME(RPITIT): Deny nested RPITIT in args too
865            if proj.args.has_escaping_bound_vars() {
866                bug!("FIXME(RPITIT): error here");
867            }
868            // Replace with infer var
869            let infer_ty = self.ocx.infcx.next_ty_var(self.span);
870            self.types.insert(proj.def_id, (infer_ty, proj.args));
871            // Recurse into bounds
872            for (pred, pred_span) in self
873                .cx()
874                .explicit_item_bounds(proj.def_id)
875                .iter_instantiated_copied(self.cx(), proj.args)
876            {
877                let pred = pred.fold_with(self);
878                let pred = self.ocx.normalize(
879                    &ObligationCause::misc(self.span, self.body_id),
880                    self.param_env,
881                    pred,
882                );
883
884                self.ocx.register_obligation(traits::Obligation::new(
885                    self.cx(),
886                    ObligationCause::new(
887                        self.span,
888                        self.body_id,
889                        ObligationCauseCode::WhereClause(proj.def_id, pred_span),
890                    ),
891                    self.param_env,
892                    pred,
893                ));
894            }
895            infer_ty
896        } else {
897            ty.super_fold_with(self)
898        }
899    }
900}
901
902struct RemapHiddenTyRegions<'tcx> {
903    tcx: TyCtxt<'tcx>,
904    /// Map from early/late params of the impl to identity regions of the RPITIT (GAT)
905    /// in the trait.
906    map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
907    num_trait_args: usize,
908    num_impl_args: usize,
909    /// Def id of the RPITIT (GAT) in the *trait*.
910    def_id: DefId,
911    /// Def id of the impl method which owns the opaque hidden type we're remapping.
912    impl_m_def_id: DefId,
913    /// The hidden type we're remapping. Useful for diagnostics.
914    ty: Ty<'tcx>,
915    /// Span of the return type. Useful for diagnostics.
916    return_span: Span,
917}
918
919impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
920    type Error = ErrorGuaranteed;
921
922    fn cx(&self) -> TyCtxt<'tcx> {
923        self.tcx
924    }
925
926    fn try_fold_region(
927        &mut self,
928        region: ty::Region<'tcx>,
929    ) -> Result<ty::Region<'tcx>, Self::Error> {
930        match region.kind() {
931            // Never remap bound regions or `'static`
932            ty::ReBound(..) | ty::ReStatic | ty::ReError(_) => return Ok(region),
933            // We always remap liberated late-bound regions from the function.
934            ty::ReLateParam(_) => {}
935            // Remap early-bound regions as long as they don't come from the `impl` itself,
936            // in which case we don't really need to renumber them.
937            ty::ReEarlyParam(ebr) => {
938                if ebr.index as usize >= self.num_impl_args {
939                    // Remap
940                } else {
941                    return Ok(region);
942                }
943            }
944            ty::ReVar(_) | ty::RePlaceholder(_) | ty::ReErased => unreachable!(
945                "should not have leaked vars or placeholders into hidden type of RPITIT"
946            ),
947        }
948
949        let e = if let Some(id_region) = self.map.get(&region) {
950            if let ty::ReEarlyParam(e) = id_region.kind() {
951                e
952            } else {
953                bug!(
954                    "expected to map region {region} to early-bound identity region, but got {id_region}"
955                );
956            }
957        } else {
958            let guar = match region.opt_param_def_id(self.tcx, self.impl_m_def_id) {
959                Some(def_id) => {
960                    let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
961                        self.tcx.def_span(opaque_ty.def_id)
962                    } else {
963                        self.return_span
964                    };
965                    self.tcx
966                        .dcx()
967                        .struct_span_err(
968                            return_span,
969                            "return type captures more lifetimes than trait definition",
970                        )
971                        .with_span_label(self.tcx.def_span(def_id), "this lifetime was captured")
972                        .with_span_note(
973                            self.tcx.def_span(self.def_id),
974                            "hidden type must only reference lifetimes captured by this impl trait",
975                        )
976                        .with_note(format!("hidden type inferred to be `{}`", self.ty))
977                        .emit()
978                }
979                None => {
980                    // This code path is not reached in any tests, but may be
981                    // reachable. If this is triggered, it should be converted
982                    // to `delayed_bug` and the triggering case turned into a
983                    // test.
984                    self.tcx.dcx().bug("should've been able to remap region");
985                }
986            };
987            return Err(guar);
988        };
989
990        Ok(ty::Region::new_early_param(
991            self.tcx,
992            ty::EarlyParamRegion {
993                name: e.name,
994                index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
995            },
996        ))
997    }
998}
999
1000fn report_trait_method_mismatch<'tcx>(
1001    infcx: &InferCtxt<'tcx>,
1002    mut cause: ObligationCause<'tcx>,
1003    param_env: ty::ParamEnv<'tcx>,
1004    terr: TypeError<'tcx>,
1005    (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
1006    (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
1007    impl_trait_ref: ty::TraitRef<'tcx>,
1008) -> ErrorGuaranteed {
1009    let tcx = infcx.tcx;
1010    let (impl_err_span, trait_err_span) =
1011        extract_spans_for_error_reporting(infcx, terr, &cause, impl_m, trait_m);
1012
1013    let mut diag = struct_span_code_err!(
1014        tcx.dcx(),
1015        impl_err_span,
1016        E0053,
1017        "method `{}` has an incompatible type for trait",
1018        trait_m.name
1019    );
1020    match &terr {
1021        TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
1022            if trait_m.fn_has_self_parameter =>
1023        {
1024            let ty = trait_sig.inputs()[0];
1025            let sugg = match ExplicitSelf::determine(ty, |ty| ty == impl_trait_ref.self_ty()) {
1026                ExplicitSelf::ByValue => "self".to_owned(),
1027                ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
1028                ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
1029                _ => format!("self: {ty}"),
1030            };
1031
1032            // When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
1033            // span points only at the type `Box<Self`>, but we want to cover the whole
1034            // argument pattern and type.
1035            let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
1036            let span = tcx
1037                .hir()
1038                .body_param_names(body)
1039                .zip(sig.decl.inputs.iter())
1040                .map(|(param, ty)| param.span.to(ty.span))
1041                .next()
1042                .unwrap_or(impl_err_span);
1043
1044            diag.span_suggestion_verbose(
1045                span,
1046                "change the self-receiver type to match the trait",
1047                sugg,
1048                Applicability::MachineApplicable,
1049            );
1050        }
1051        TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(_, i) => {
1052            if trait_sig.inputs().len() == *i {
1053                // Suggestion to change output type. We do not suggest in `async` functions
1054                // to avoid complex logic or incorrect output.
1055                if let ImplItemKind::Fn(sig, _) =
1056                    &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind
1057                    && !sig.header.asyncness.is_async()
1058                {
1059                    let msg = "change the output type to match the trait";
1060                    let ap = Applicability::MachineApplicable;
1061                    match sig.decl.output {
1062                        hir::FnRetTy::DefaultReturn(sp) => {
1063                            let sugg = format!(" -> {}", trait_sig.output());
1064                            diag.span_suggestion_verbose(sp, msg, sugg, ap);
1065                        }
1066                        hir::FnRetTy::Return(hir_ty) => {
1067                            let sugg = trait_sig.output();
1068                            diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap);
1069                        }
1070                    };
1071                };
1072            } else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
1073                diag.span_suggestion_verbose(
1074                    impl_err_span,
1075                    "change the parameter type to match the trait",
1076                    trait_ty,
1077                    Applicability::MachineApplicable,
1078                );
1079            }
1080        }
1081        _ => {}
1082    }
1083
1084    cause.span = impl_err_span;
1085    infcx.err_ctxt().note_type_err(
1086        &mut diag,
1087        &cause,
1088        trait_err_span.map(|sp| (sp, Cow::from("type in trait"), false)),
1089        Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound {
1090            expected: ty::Binder::dummy(trait_sig),
1091            found: ty::Binder::dummy(impl_sig),
1092        }))),
1093        terr,
1094        false,
1095        None,
1096    );
1097
1098    diag.emit()
1099}
1100
1101fn check_region_bounds_on_impl_item<'tcx>(
1102    tcx: TyCtxt<'tcx>,
1103    impl_m: ty::AssocItem,
1104    trait_m: ty::AssocItem,
1105    delay: bool,
1106) -> Result<(), ErrorGuaranteed> {
1107    let impl_generics = tcx.generics_of(impl_m.def_id);
1108    let impl_params = impl_generics.own_counts().lifetimes;
1109
1110    let trait_generics = tcx.generics_of(trait_m.def_id);
1111    let trait_params = trait_generics.own_counts().lifetimes;
1112
1113    debug!(?trait_generics, ?impl_generics);
1114
1115    // Must have same number of early-bound lifetime parameters.
1116    // Unfortunately, if the user screws up the bounds, then this
1117    // will change classification between early and late. E.g.,
1118    // if in trait we have `<'a,'b:'a>`, and in impl we just have
1119    // `<'a,'b>`, then we have 2 early-bound lifetime parameters
1120    // in trait but 0 in the impl. But if we report "expected 2
1121    // but found 0" it's confusing, because it looks like there
1122    // are zero. Since I don't quite know how to phrase things at
1123    // the moment, give a kind of vague error message.
1124    if trait_params != impl_params {
1125        let span = tcx
1126            .hir()
1127            .get_generics(impl_m.def_id.expect_local())
1128            .expect("expected impl item to have generics or else we can't compare them")
1129            .span;
1130
1131        let mut generics_span = None;
1132        let mut bounds_span = vec![];
1133        let mut where_span = None;
1134        if let Some(trait_node) = tcx.hir().get_if_local(trait_m.def_id)
1135            && let Some(trait_generics) = trait_node.generics()
1136        {
1137            generics_span = Some(trait_generics.span);
1138            // FIXME: we could potentially look at the impl's bounds to not point at bounds that
1139            // *are* present in the impl.
1140            for p in trait_generics.predicates {
1141                if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
1142                    for b in pred.bounds {
1143                        if let hir::GenericBound::Outlives(lt) = b {
1144                            bounds_span.push(lt.ident.span);
1145                        }
1146                    }
1147                }
1148            }
1149            if let Some(impl_node) = tcx.hir().get_if_local(impl_m.def_id)
1150                && let Some(impl_generics) = impl_node.generics()
1151            {
1152                let mut impl_bounds = 0;
1153                for p in impl_generics.predicates {
1154                    if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
1155                        for b in pred.bounds {
1156                            if let hir::GenericBound::Outlives(_) = b {
1157                                impl_bounds += 1;
1158                            }
1159                        }
1160                    }
1161                }
1162                if impl_bounds == bounds_span.len() {
1163                    bounds_span = vec![];
1164                } else if impl_generics.has_where_clause_predicates {
1165                    where_span = Some(impl_generics.where_clause_span);
1166                }
1167            }
1168        }
1169        let reported = tcx
1170            .dcx()
1171            .create_err(LifetimesOrBoundsMismatchOnTrait {
1172                span,
1173                item_kind: impl_m.descr(),
1174                ident: impl_m.ident(tcx),
1175                generics_span,
1176                bounds_span,
1177                where_span,
1178            })
1179            .emit_unless(delay);
1180        return Err(reported);
1181    }
1182
1183    Ok(())
1184}
1185
1186#[instrument(level = "debug", skip(infcx))]
1187fn extract_spans_for_error_reporting<'tcx>(
1188    infcx: &infer::InferCtxt<'tcx>,
1189    terr: TypeError<'_>,
1190    cause: &ObligationCause<'tcx>,
1191    impl_m: ty::AssocItem,
1192    trait_m: ty::AssocItem,
1193) -> (Span, Option<Span>) {
1194    let tcx = infcx.tcx;
1195    let mut impl_args = {
1196        let (sig, _) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
1197        sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
1198    };
1199
1200    let trait_args = trait_m.def_id.as_local().map(|def_id| {
1201        let (sig, _) = tcx.hir().expect_trait_item(def_id).expect_fn();
1202        sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
1203    });
1204
1205    match terr {
1206        TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => {
1207            (impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
1208        }
1209        _ => (cause.span, tcx.hir().span_if_local(trait_m.def_id)),
1210    }
1211}
1212
1213fn compare_self_type<'tcx>(
1214    tcx: TyCtxt<'tcx>,
1215    impl_m: ty::AssocItem,
1216    trait_m: ty::AssocItem,
1217    impl_trait_ref: ty::TraitRef<'tcx>,
1218    delay: bool,
1219) -> Result<(), ErrorGuaranteed> {
1220    // Try to give more informative error messages about self typing
1221    // mismatches. Note that any mismatch will also be detected
1222    // below, where we construct a canonical function type that
1223    // includes the self parameter as a normal parameter. It's just
1224    // that the error messages you get out of this code are a bit more
1225    // inscrutable, particularly for cases where one method has no
1226    // self.
1227
1228    let self_string = |method: ty::AssocItem| {
1229        let untransformed_self_ty = match method.container {
1230            ty::AssocItemContainer::Impl => impl_trait_ref.self_ty(),
1231            ty::AssocItemContainer::Trait => tcx.types.self_param,
1232        };
1233        let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0);
1234        let (infcx, param_env) = tcx
1235            .infer_ctxt()
1236            .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id));
1237        let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
1238        let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty);
1239        match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
1240            ExplicitSelf::ByValue => "self".to_owned(),
1241            ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
1242            ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
1243            _ => format!("self: {self_arg_ty}"),
1244        }
1245    };
1246
1247    match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
1248        (false, false) | (true, true) => {}
1249
1250        (false, true) => {
1251            let self_descr = self_string(impl_m);
1252            let impl_m_span = tcx.def_span(impl_m.def_id);
1253            let mut err = struct_span_code_err!(
1254                tcx.dcx(),
1255                impl_m_span,
1256                E0185,
1257                "method `{}` has a `{}` declaration in the impl, but not in the trait",
1258                trait_m.name,
1259                self_descr
1260            );
1261            err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
1262            if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
1263                err.span_label(span, format!("trait method declared without `{self_descr}`"));
1264            } else {
1265                err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
1266            }
1267            return Err(err.emit_unless(delay));
1268        }
1269
1270        (true, false) => {
1271            let self_descr = self_string(trait_m);
1272            let impl_m_span = tcx.def_span(impl_m.def_id);
1273            let mut err = struct_span_code_err!(
1274                tcx.dcx(),
1275                impl_m_span,
1276                E0186,
1277                "method `{}` has a `{}` declaration in the trait, but not in the impl",
1278                trait_m.name,
1279                self_descr
1280            );
1281            err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
1282            if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
1283                err.span_label(span, format!("`{self_descr}` used in trait"));
1284            } else {
1285                err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
1286            }
1287
1288            return Err(err.emit_unless(delay));
1289        }
1290    }
1291
1292    Ok(())
1293}
1294
1295/// Checks that the number of generics on a given assoc item in a trait impl is the same
1296/// as the number of generics on the respective assoc item in the trait definition.
1297///
1298/// For example this code emits the errors in the following code:
1299/// ```rust,compile_fail
1300/// trait Trait {
1301///     fn foo();
1302///     type Assoc<T>;
1303/// }
1304///
1305/// impl Trait for () {
1306///     fn foo<T>() {}
1307///     //~^ error
1308///     type Assoc = u32;
1309///     //~^ error
1310/// }
1311/// ```
1312///
1313/// Notably this does not error on `foo<T>` implemented as `foo<const N: u8>` or
1314/// `foo<const N: u8>` implemented as `foo<const N: u32>`. This is handled in
1315/// [`compare_generic_param_kinds`]. This function also does not handle lifetime parameters
1316fn compare_number_of_generics<'tcx>(
1317    tcx: TyCtxt<'tcx>,
1318    impl_: ty::AssocItem,
1319    trait_: ty::AssocItem,
1320    delay: bool,
1321) -> Result<(), ErrorGuaranteed> {
1322    let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
1323    let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
1324
1325    // This avoids us erroring on `foo<T>` implemented as `foo<const N: u8>` as this is implemented
1326    // in `compare_generic_param_kinds` which will give a nicer error message than something like:
1327    // "expected 1 type parameter, found 0 type parameters"
1328    if (trait_own_counts.types + trait_own_counts.consts)
1329        == (impl_own_counts.types + impl_own_counts.consts)
1330    {
1331        return Ok(());
1332    }
1333
1334    // We never need to emit a separate error for RPITITs, since if an RPITIT
1335    // has mismatched type or const generic arguments, then the method that it's
1336    // inheriting the generics from will also have mismatched arguments, and
1337    // we'll report an error for that instead. Delay a bug for safety, though.
1338    if trait_.is_impl_trait_in_trait() {
1339        // FIXME: no tests trigger this. If you find example code that does
1340        // trigger this, please add it to the test suite.
1341        tcx.dcx()
1342            .bug("errors comparing numbers of generics of trait/impl functions were not emitted");
1343    }
1344
1345    let matchings = [
1346        ("type", trait_own_counts.types, impl_own_counts.types),
1347        ("const", trait_own_counts.consts, impl_own_counts.consts),
1348    ];
1349
1350    let item_kind = impl_.descr();
1351
1352    let mut err_occurred = None;
1353    for (kind, trait_count, impl_count) in matchings {
1354        if impl_count != trait_count {
1355            let arg_spans = |kind: ty::AssocKind, generics: &hir::Generics<'_>| {
1356                let mut spans = generics
1357                    .params
1358                    .iter()
1359                    .filter(|p| match p.kind {
1360                        hir::GenericParamKind::Lifetime {
1361                            kind: hir::LifetimeParamKind::Elided(_),
1362                        } => {
1363                            // A fn can have an arbitrary number of extra elided lifetimes for the
1364                            // same signature.
1365                            !matches!(kind, ty::AssocKind::Fn)
1366                        }
1367                        _ => true,
1368                    })
1369                    .map(|p| p.span)
1370                    .collect::<Vec<Span>>();
1371                if spans.is_empty() {
1372                    spans = vec![generics.span]
1373                }
1374                spans
1375            };
1376            let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() {
1377                let trait_item = tcx.hir().expect_trait_item(def_id);
1378                let arg_spans: Vec<Span> = arg_spans(trait_.kind, trait_item.generics);
1379                let impl_trait_spans: Vec<Span> = trait_item
1380                    .generics
1381                    .params
1382                    .iter()
1383                    .filter_map(|p| match p.kind {
1384                        GenericParamKind::Type { synthetic: true, .. } => Some(p.span),
1385                        _ => None,
1386                    })
1387                    .collect();
1388                (Some(arg_spans), impl_trait_spans)
1389            } else {
1390                let trait_span = tcx.hir().span_if_local(trait_.def_id);
1391                (trait_span.map(|s| vec![s]), vec![])
1392            };
1393
1394            let impl_item = tcx.hir().expect_impl_item(impl_.def_id.expect_local());
1395            let impl_item_impl_trait_spans: Vec<Span> = impl_item
1396                .generics
1397                .params
1398                .iter()
1399                .filter_map(|p| match p.kind {
1400                    GenericParamKind::Type { synthetic: true, .. } => Some(p.span),
1401                    _ => None,
1402                })
1403                .collect();
1404            let spans = arg_spans(impl_.kind, impl_item.generics);
1405            let span = spans.first().copied();
1406
1407            let mut err = tcx.dcx().struct_span_err(
1408                spans,
1409                format!(
1410                    "{} `{}` has {} {kind} parameter{} but its trait \
1411                     declaration has {} {kind} parameter{}",
1412                    item_kind,
1413                    trait_.name,
1414                    impl_count,
1415                    pluralize!(impl_count),
1416                    trait_count,
1417                    pluralize!(trait_count),
1418                    kind = kind,
1419                ),
1420            );
1421            err.code(E0049);
1422
1423            let msg =
1424                format!("expected {trait_count} {kind} parameter{}", pluralize!(trait_count),);
1425            if let Some(spans) = trait_spans {
1426                let mut spans = spans.iter();
1427                if let Some(span) = spans.next() {
1428                    err.span_label(*span, msg);
1429                }
1430                for span in spans {
1431                    err.span_label(*span, "");
1432                }
1433            } else {
1434                err.span_label(tcx.def_span(trait_.def_id), msg);
1435            }
1436
1437            if let Some(span) = span {
1438                err.span_label(
1439                    span,
1440                    format!("found {} {} parameter{}", impl_count, kind, pluralize!(impl_count),),
1441                );
1442            }
1443
1444            for span in impl_trait_spans.iter().chain(impl_item_impl_trait_spans.iter()) {
1445                err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
1446            }
1447
1448            let reported = err.emit_unless(delay);
1449            err_occurred = Some(reported);
1450        }
1451    }
1452
1453    if let Some(reported) = err_occurred { Err(reported) } else { Ok(()) }
1454}
1455
1456fn compare_number_of_method_arguments<'tcx>(
1457    tcx: TyCtxt<'tcx>,
1458    impl_m: ty::AssocItem,
1459    trait_m: ty::AssocItem,
1460    delay: bool,
1461) -> Result<(), ErrorGuaranteed> {
1462    let impl_m_fty = tcx.fn_sig(impl_m.def_id);
1463    let trait_m_fty = tcx.fn_sig(trait_m.def_id);
1464    let trait_number_args = trait_m_fty.skip_binder().inputs().skip_binder().len();
1465    let impl_number_args = impl_m_fty.skip_binder().inputs().skip_binder().len();
1466
1467    if trait_number_args != impl_number_args {
1468        let trait_span = trait_m
1469            .def_id
1470            .as_local()
1471            .and_then(|def_id| {
1472                let (trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).expect_fn();
1473                let pos = trait_number_args.saturating_sub(1);
1474                trait_m_sig.decl.inputs.get(pos).map(|arg| {
1475                    if pos == 0 {
1476                        arg.span
1477                    } else {
1478                        arg.span.with_lo(trait_m_sig.decl.inputs[0].span.lo())
1479                    }
1480                })
1481            })
1482            .or_else(|| tcx.hir().span_if_local(trait_m.def_id));
1483
1484        let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
1485        let pos = impl_number_args.saturating_sub(1);
1486        let impl_span = impl_m_sig
1487            .decl
1488            .inputs
1489            .get(pos)
1490            .map(|arg| {
1491                if pos == 0 {
1492                    arg.span
1493                } else {
1494                    arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo())
1495                }
1496            })
1497            .unwrap_or_else(|| tcx.def_span(impl_m.def_id));
1498
1499        let mut err = struct_span_code_err!(
1500            tcx.dcx(),
1501            impl_span,
1502            E0050,
1503            "method `{}` has {} but the declaration in trait `{}` has {}",
1504            trait_m.name,
1505            potentially_plural_count(impl_number_args, "parameter"),
1506            tcx.def_path_str(trait_m.def_id),
1507            trait_number_args
1508        );
1509
1510        if let Some(trait_span) = trait_span {
1511            err.span_label(
1512                trait_span,
1513                format!(
1514                    "trait requires {}",
1515                    potentially_plural_count(trait_number_args, "parameter")
1516                ),
1517            );
1518        } else {
1519            err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
1520        }
1521
1522        err.span_label(
1523            impl_span,
1524            format!(
1525                "expected {}, found {}",
1526                potentially_plural_count(trait_number_args, "parameter"),
1527                impl_number_args
1528            ),
1529        );
1530
1531        return Err(err.emit_unless(delay));
1532    }
1533
1534    Ok(())
1535}
1536
1537fn compare_synthetic_generics<'tcx>(
1538    tcx: TyCtxt<'tcx>,
1539    impl_m: ty::AssocItem,
1540    trait_m: ty::AssocItem,
1541    delay: bool,
1542) -> Result<(), ErrorGuaranteed> {
1543    // FIXME(chrisvittal) Clean up this function, list of FIXME items:
1544    //     1. Better messages for the span labels
1545    //     2. Explanation as to what is going on
1546    // If we get here, we already have the same number of generics, so the zip will
1547    // be okay.
1548    let mut error_found = None;
1549    let impl_m_generics = tcx.generics_of(impl_m.def_id);
1550    let trait_m_generics = tcx.generics_of(trait_m.def_id);
1551    let impl_m_type_params =
1552        impl_m_generics.own_params.iter().filter_map(|param| match param.kind {
1553            GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
1554            GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None,
1555        });
1556    let trait_m_type_params =
1557        trait_m_generics.own_params.iter().filter_map(|param| match param.kind {
1558            GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
1559            GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None,
1560        });
1561    for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic)) in
1562        iter::zip(impl_m_type_params, trait_m_type_params)
1563    {
1564        if impl_synthetic != trait_synthetic {
1565            let impl_def_id = impl_def_id.expect_local();
1566            let impl_span = tcx.def_span(impl_def_id);
1567            let trait_span = tcx.def_span(trait_def_id);
1568            let mut err = struct_span_code_err!(
1569                tcx.dcx(),
1570                impl_span,
1571                E0643,
1572                "method `{}` has incompatible signature for trait",
1573                trait_m.name
1574            );
1575            err.span_label(trait_span, "declaration in trait here");
1576            if impl_synthetic {
1577                // The case where the impl method uses `impl Trait` but the trait method uses
1578                // explicit generics
1579                err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
1580                let _: Option<_> = try {
1581                    // try taking the name from the trait impl
1582                    // FIXME: this is obviously suboptimal since the name can already be used
1583                    // as another generic argument
1584                    let new_name = tcx.opt_item_name(trait_def_id)?;
1585                    let trait_m = trait_m.def_id.as_local()?;
1586                    let trait_m = tcx.hir().expect_trait_item(trait_m);
1587
1588                    let impl_m = impl_m.def_id.as_local()?;
1589                    let impl_m = tcx.hir().expect_impl_item(impl_m);
1590
1591                    // in case there are no generics, take the spot between the function name
1592                    // and the opening paren of the argument list
1593                    let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
1594                    // in case there are generics, just replace them
1595                    let generics_span = impl_m.generics.span.substitute_dummy(new_generics_span);
1596                    // replace with the generics from the trait
1597                    let new_generics =
1598                        tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
1599
1600                    err.multipart_suggestion(
1601                        "try changing the `impl Trait` argument to a generic parameter",
1602                        vec![
1603                            // replace `impl Trait` with `T`
1604                            (impl_span, new_name.to_string()),
1605                            // replace impl method generics with trait method generics
1606                            // This isn't quite right, as users might have changed the names
1607                            // of the generics, but it works for the common case
1608                            (generics_span, new_generics),
1609                        ],
1610                        Applicability::MaybeIncorrect,
1611                    );
1612                };
1613            } else {
1614                // The case where the trait method uses `impl Trait`, but the impl method uses
1615                // explicit generics.
1616                err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
1617                let _: Option<_> = try {
1618                    let impl_m = impl_m.def_id.as_local()?;
1619                    let impl_m = tcx.hir().expect_impl_item(impl_m);
1620                    let (sig, _) = impl_m.expect_fn();
1621                    let input_tys = sig.decl.inputs;
1622
1623                    struct Visitor(hir::def_id::LocalDefId);
1624                    impl<'v> intravisit::Visitor<'v> for Visitor {
1625                        type Result = ControlFlow<Span>;
1626                        fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) -> Self::Result {
1627                            if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
1628                                && let Res::Def(DefKind::TyParam, def_id) = path.res
1629                                && def_id == self.0.to_def_id()
1630                            {
1631                                ControlFlow::Break(ty.span)
1632                            } else {
1633                                intravisit::walk_ty(self, ty)
1634                            }
1635                        }
1636                    }
1637
1638                    let span = input_tys
1639                        .iter()
1640                        .find_map(|ty| Visitor(impl_def_id).visit_ty_unambig(ty).break_value())?;
1641
1642                    let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
1643                    let bounds = bounds.first()?.span().to(bounds.last()?.span());
1644                    let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
1645
1646                    err.multipart_suggestion(
1647                        "try removing the generic parameter and using `impl Trait` instead",
1648                        vec![
1649                            // delete generic parameters
1650                            (impl_m.generics.span, String::new()),
1651                            // replace param usage with `impl Trait`
1652                            (span, format!("impl {bounds}")),
1653                        ],
1654                        Applicability::MaybeIncorrect,
1655                    );
1656                };
1657            }
1658            error_found = Some(err.emit_unless(delay));
1659        }
1660    }
1661    if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
1662}
1663
1664/// Checks that all parameters in the generics of a given assoc item in a trait impl have
1665/// the same kind as the respective generic parameter in the trait def.
1666///
1667/// For example all 4 errors in the following code are emitted here:
1668/// ```rust,ignore (pseudo-Rust)
1669/// trait Foo {
1670///     fn foo<const N: u8>();
1671///     type Bar<const N: u8>;
1672///     fn baz<const N: u32>();
1673///     type Blah<T>;
1674/// }
1675///
1676/// impl Foo for () {
1677///     fn foo<const N: u64>() {}
1678///     //~^ error
1679///     type Bar<const N: u64> = ();
1680///     //~^ error
1681///     fn baz<T>() {}
1682///     //~^ error
1683///     type Blah<const N: i64> = u32;
1684///     //~^ error
1685/// }
1686/// ```
1687///
1688/// This function does not handle lifetime parameters
1689fn compare_generic_param_kinds<'tcx>(
1690    tcx: TyCtxt<'tcx>,
1691    impl_item: ty::AssocItem,
1692    trait_item: ty::AssocItem,
1693    delay: bool,
1694) -> Result<(), ErrorGuaranteed> {
1695    assert_eq!(impl_item.kind, trait_item.kind);
1696
1697    let ty_const_params_of = |def_id| {
1698        tcx.generics_of(def_id).own_params.iter().filter(|param| {
1699            matches!(
1700                param.kind,
1701                GenericParamDefKind::Const { .. } | GenericParamDefKind::Type { .. }
1702            )
1703        })
1704    };
1705
1706    for (param_impl, param_trait) in
1707        iter::zip(ty_const_params_of(impl_item.def_id), ty_const_params_of(trait_item.def_id))
1708    {
1709        use GenericParamDefKind::*;
1710        if match (&param_impl.kind, &param_trait.kind) {
1711            (Const { .. }, Const { .. })
1712                if tcx.type_of(param_impl.def_id) != tcx.type_of(param_trait.def_id) =>
1713            {
1714                true
1715            }
1716            (Const { .. }, Type { .. }) | (Type { .. }, Const { .. }) => true,
1717            // this is exhaustive so that anyone adding new generic param kinds knows
1718            // to make sure this error is reported for them.
1719            (Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false,
1720            (Lifetime { .. }, _) | (_, Lifetime { .. }) => {
1721                bug!("lifetime params are expected to be filtered by `ty_const_params_of`")
1722            }
1723        } {
1724            let param_impl_span = tcx.def_span(param_impl.def_id);
1725            let param_trait_span = tcx.def_span(param_trait.def_id);
1726
1727            let mut err = struct_span_code_err!(
1728                tcx.dcx(),
1729                param_impl_span,
1730                E0053,
1731                "{} `{}` has an incompatible generic parameter for trait `{}`",
1732                impl_item.descr(),
1733                trait_item.name,
1734                &tcx.def_path_str(tcx.parent(trait_item.def_id))
1735            );
1736
1737            let make_param_message = |prefix: &str, param: &ty::GenericParamDef| match param.kind {
1738                Const { .. } => {
1739                    format!(
1740                        "{} const parameter of type `{}`",
1741                        prefix,
1742                        tcx.type_of(param.def_id).instantiate_identity()
1743                    )
1744                }
1745                Type { .. } => format!("{prefix} type parameter"),
1746                Lifetime { .. } => span_bug!(
1747                    tcx.def_span(param.def_id),
1748                    "lifetime params are expected to be filtered by `ty_const_params_of`"
1749                ),
1750            };
1751
1752            let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap();
1753            err.span_label(trait_header_span, "");
1754            err.span_label(param_trait_span, make_param_message("expected", param_trait));
1755
1756            let impl_header_span = tcx.def_span(tcx.parent(impl_item.def_id));
1757            err.span_label(impl_header_span, "");
1758            err.span_label(param_impl_span, make_param_message("found", param_impl));
1759
1760            let reported = err.emit_unless(delay);
1761            return Err(reported);
1762        }
1763    }
1764
1765    Ok(())
1766}
1767
1768fn compare_impl_const<'tcx>(
1769    tcx: TyCtxt<'tcx>,
1770    impl_const_item: ty::AssocItem,
1771    trait_const_item: ty::AssocItem,
1772    impl_trait_ref: ty::TraitRef<'tcx>,
1773) -> Result<(), ErrorGuaranteed> {
1774    compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?;
1775    compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?;
1776    check_region_bounds_on_impl_item(tcx, impl_const_item, trait_const_item, false)?;
1777    compare_const_predicate_entailment(tcx, impl_const_item, trait_const_item, impl_trait_ref)
1778}
1779
1780/// The equivalent of [compare_method_predicate_entailment], but for associated constants
1781/// instead of associated functions.
1782// FIXME(generic_const_items): If possible extract the common parts of `compare_{type,const}_predicate_entailment`.
1783#[instrument(level = "debug", skip(tcx))]
1784fn compare_const_predicate_entailment<'tcx>(
1785    tcx: TyCtxt<'tcx>,
1786    impl_ct: ty::AssocItem,
1787    trait_ct: ty::AssocItem,
1788    impl_trait_ref: ty::TraitRef<'tcx>,
1789) -> Result<(), ErrorGuaranteed> {
1790    let impl_ct_def_id = impl_ct.def_id.expect_local();
1791    let impl_ct_span = tcx.def_span(impl_ct_def_id);
1792
1793    // The below is for the most part highly similar to the procedure
1794    // for methods above. It is simpler in many respects, especially
1795    // because we shouldn't really have to deal with lifetimes or
1796    // predicates. In fact some of this should probably be put into
1797    // shared functions because of DRY violations...
1798    let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ct.def_id).rebase_onto(
1799        tcx,
1800        impl_ct.container_id(tcx),
1801        impl_trait_ref.args,
1802    );
1803
1804    // Create a parameter environment that represents the implementation's
1805    // associated const.
1806    let impl_ty = tcx.type_of(impl_ct_def_id).instantiate_identity();
1807
1808    let trait_ty = tcx.type_of(trait_ct.def_id).instantiate(tcx, trait_to_impl_args);
1809    let code = ObligationCauseCode::CompareImplItem {
1810        impl_item_def_id: impl_ct_def_id,
1811        trait_item_def_id: trait_ct.def_id,
1812        kind: impl_ct.kind,
1813    };
1814    let mut cause = ObligationCause::new(impl_ct_span, impl_ct_def_id, code.clone());
1815
1816    let impl_ct_predicates = tcx.predicates_of(impl_ct.def_id);
1817    let trait_ct_predicates = tcx.predicates_of(trait_ct.def_id);
1818
1819    // The predicates declared by the impl definition, the trait and the
1820    // associated const in the trait are assumed.
1821    let impl_predicates = tcx.predicates_of(impl_ct_predicates.parent.unwrap());
1822    let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates;
1823    hybrid_preds.extend(
1824        trait_ct_predicates
1825            .instantiate_own(tcx, trait_to_impl_args)
1826            .map(|(predicate, _)| predicate),
1827    );
1828
1829    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
1830    let param_env = traits::normalize_param_env_or_error(
1831        tcx,
1832        param_env,
1833        ObligationCause::misc(impl_ct_span, impl_ct_def_id),
1834    );
1835
1836    let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1837    let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
1838
1839    let impl_ct_own_bounds = impl_ct_predicates.instantiate_own_identity();
1840    for (predicate, span) in impl_ct_own_bounds {
1841        let cause = ObligationCause::misc(span, impl_ct_def_id);
1842        let predicate = ocx.normalize(&cause, param_env, predicate);
1843
1844        let cause = ObligationCause::new(span, impl_ct_def_id, code.clone());
1845        ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
1846    }
1847
1848    // There is no "body" here, so just pass dummy id.
1849    let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
1850    debug!(?impl_ty);
1851
1852    let trait_ty = ocx.normalize(&cause, param_env, trait_ty);
1853    debug!(?trait_ty);
1854
1855    let err = ocx.sup(&cause, param_env, trait_ty, impl_ty);
1856
1857    if let Err(terr) = err {
1858        debug!(?impl_ty, ?trait_ty);
1859
1860        // Locate the Span containing just the type of the offending impl
1861        let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const();
1862        cause.span = ty.span;
1863
1864        let mut diag = struct_span_code_err!(
1865            tcx.dcx(),
1866            cause.span,
1867            E0326,
1868            "implemented const `{}` has an incompatible type for trait",
1869            trait_ct.name
1870        );
1871
1872        let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| {
1873            // Add a label to the Span containing just the type of the const
1874            let (ty, _) = tcx.hir().expect_trait_item(trait_ct_def_id).expect_const();
1875            ty.span
1876        });
1877
1878        infcx.err_ctxt().note_type_err(
1879            &mut diag,
1880            &cause,
1881            trait_c_span.map(|span| (span, Cow::from("type in trait"), false)),
1882            Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound {
1883                expected: trait_ty.into(),
1884                found: impl_ty.into(),
1885            }))),
1886            terr,
1887            false,
1888            None,
1889        );
1890        return Err(diag.emit());
1891    };
1892
1893    // Check that all obligations are satisfied by the implementation's
1894    // version.
1895    let errors = ocx.select_all_or_error();
1896    if !errors.is_empty() {
1897        return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
1898    }
1899
1900    ocx.resolve_regions_and_report_errors(impl_ct_def_id, param_env, [])
1901}
1902
1903#[instrument(level = "debug", skip(tcx))]
1904fn compare_impl_ty<'tcx>(
1905    tcx: TyCtxt<'tcx>,
1906    impl_ty: ty::AssocItem,
1907    trait_ty: ty::AssocItem,
1908    impl_trait_ref: ty::TraitRef<'tcx>,
1909) -> Result<(), ErrorGuaranteed> {
1910    compare_number_of_generics(tcx, impl_ty, trait_ty, false)?;
1911    compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
1912    check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
1913    compare_type_predicate_entailment(tcx, impl_ty, trait_ty, impl_trait_ref)?;
1914    check_type_bounds(tcx, trait_ty, impl_ty, impl_trait_ref)
1915}
1916
1917/// The equivalent of [compare_method_predicate_entailment], but for associated types
1918/// instead of associated functions.
1919#[instrument(level = "debug", skip(tcx))]
1920fn compare_type_predicate_entailment<'tcx>(
1921    tcx: TyCtxt<'tcx>,
1922    impl_ty: ty::AssocItem,
1923    trait_ty: ty::AssocItem,
1924    impl_trait_ref: ty::TraitRef<'tcx>,
1925) -> Result<(), ErrorGuaranteed> {
1926    let impl_def_id = impl_ty.container_id(tcx);
1927    let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto(
1928        tcx,
1929        impl_def_id,
1930        impl_trait_ref.args,
1931    );
1932
1933    let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
1934    let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
1935
1936    let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity();
1937    // If there are no bounds, then there are no const conditions, so no need to check that here.
1938    if impl_ty_own_bounds.len() == 0 {
1939        // Nothing to check.
1940        return Ok(());
1941    }
1942
1943    // This `DefId` should be used for the `body_id` field on each
1944    // `ObligationCause` (and the `FnCtxt`). This is what
1945    // `regionck_item` expects.
1946    let impl_ty_def_id = impl_ty.def_id.expect_local();
1947    debug!(?trait_to_impl_args);
1948
1949    // The predicates declared by the impl definition, the trait and the
1950    // associated type in the trait are assumed.
1951    let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap());
1952    let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates;
1953    hybrid_preds.extend(
1954        trait_ty_predicates
1955            .instantiate_own(tcx, trait_to_impl_args)
1956            .map(|(predicate, _)| predicate),
1957    );
1958    debug!(?hybrid_preds);
1959
1960    let impl_ty_span = tcx.def_span(impl_ty_def_id);
1961    let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id);
1962
1963    let is_conditionally_const = tcx.is_conditionally_const(impl_ty.def_id);
1964    if is_conditionally_const {
1965        // Augment the hybrid param-env with the const conditions
1966        // of the impl header and the trait assoc type.
1967        hybrid_preds.extend(
1968            tcx.const_conditions(impl_ty_predicates.parent.unwrap())
1969                .instantiate_identity(tcx)
1970                .into_iter()
1971                .chain(
1972                    tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args),
1973                )
1974                .map(|(trait_ref, _)| {
1975                    trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe)
1976                }),
1977        );
1978    }
1979
1980    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
1981    let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
1982    debug!(caller_bounds=?param_env.caller_bounds());
1983
1984    let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1985    let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
1986
1987    for (predicate, span) in impl_ty_own_bounds {
1988        let cause = ObligationCause::misc(span, impl_ty_def_id);
1989        let predicate = ocx.normalize(&cause, param_env, predicate);
1990
1991        let cause = ObligationCause::new(
1992            span,
1993            impl_ty_def_id,
1994            ObligationCauseCode::CompareImplItem {
1995                impl_item_def_id: impl_ty.def_id.expect_local(),
1996                trait_item_def_id: trait_ty.def_id,
1997                kind: impl_ty.kind,
1998            },
1999        );
2000        ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
2001    }
2002
2003    if is_conditionally_const {
2004        // Validate the const conditions of the impl associated type.
2005        let impl_ty_own_const_conditions =
2006            tcx.const_conditions(impl_ty.def_id).instantiate_own_identity();
2007        for (const_condition, span) in impl_ty_own_const_conditions {
2008            let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id);
2009            let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
2010
2011            let cause = ObligationCause::new(
2012                span,
2013                impl_ty_def_id,
2014                ObligationCauseCode::CompareImplItem {
2015                    impl_item_def_id: impl_ty_def_id,
2016                    trait_item_def_id: trait_ty.def_id,
2017                    kind: impl_ty.kind,
2018                },
2019            );
2020            ocx.register_obligation(traits::Obligation::new(
2021                tcx,
2022                cause,
2023                param_env,
2024                const_condition.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
2025            ));
2026        }
2027    }
2028
2029    // Check that all obligations are satisfied by the implementation's
2030    // version.
2031    let errors = ocx.select_all_or_error();
2032    if !errors.is_empty() {
2033        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
2034        return Err(reported);
2035    }
2036
2037    // Finally, resolve all regions. This catches wily misuses of
2038    // lifetime parameters.
2039    ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, [])
2040}
2041
2042/// Validate that `ProjectionCandidate`s created for this associated type will
2043/// be valid.
2044///
2045/// Usually given
2046///
2047/// trait X { type Y: Copy } impl X for T { type Y = S; }
2048///
2049/// We are able to normalize `<T as X>::Y` to `S`, and so when we check the
2050/// impl is well-formed we have to prove `S: Copy`.
2051///
2052/// For default associated types the normalization is not possible (the value
2053/// from the impl could be overridden). We also can't normalize generic
2054/// associated types (yet) because they contain bound parameters.
2055#[instrument(level = "debug", skip(tcx))]
2056pub(super) fn check_type_bounds<'tcx>(
2057    tcx: TyCtxt<'tcx>,
2058    trait_ty: ty::AssocItem,
2059    impl_ty: ty::AssocItem,
2060    impl_trait_ref: ty::TraitRef<'tcx>,
2061) -> Result<(), ErrorGuaranteed> {
2062    // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
2063    // other `Foo` impls are incoherent.
2064    tcx.ensure_ok().coherent_trait(impl_trait_ref.def_id)?;
2065
2066    let param_env = tcx.param_env(impl_ty.def_id);
2067    debug!(?param_env);
2068
2069    let container_id = impl_ty.container_id(tcx);
2070    let impl_ty_def_id = impl_ty.def_id.expect_local();
2071    let impl_ty_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
2072    let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
2073
2074    let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
2075    let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
2076
2077    // A synthetic impl Trait for RPITIT desugaring or assoc type for effects desugaring has no HIR,
2078    // which we currently use to get the span for an impl's associated type. Instead, for these,
2079    // use the def_span for the synthesized  associated type.
2080    let impl_ty_span = if impl_ty.is_impl_trait_in_trait() {
2081        tcx.def_span(impl_ty_def_id)
2082    } else {
2083        match tcx.hir_node_by_def_id(impl_ty_def_id) {
2084            hir::Node::TraitItem(hir::TraitItem {
2085                kind: hir::TraitItemKind::Type(_, Some(ty)),
2086                ..
2087            }) => ty.span,
2088            hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span,
2089            item => span_bug!(
2090                tcx.def_span(impl_ty_def_id),
2091                "cannot call `check_type_bounds` on item: {item:?}",
2092            ),
2093        }
2094    };
2095    let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?;
2096
2097    let normalize_cause = ObligationCause::new(
2098        impl_ty_span,
2099        impl_ty_def_id,
2100        ObligationCauseCode::CheckAssociatedTypeBounds {
2101            impl_item_def_id: impl_ty.def_id.expect_local(),
2102            trait_item_def_id: trait_ty.def_id,
2103        },
2104    );
2105    let mk_cause = |span: Span| {
2106        let code = ObligationCauseCode::WhereClause(trait_ty.def_id, span);
2107        ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
2108    };
2109
2110    let mut obligations: Vec<_> = tcx
2111        .explicit_item_bounds(trait_ty.def_id)
2112        .iter_instantiated_copied(tcx, rebased_args)
2113        .map(|(concrete_ty_bound, span)| {
2114            debug!(?concrete_ty_bound);
2115            traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
2116        })
2117        .collect();
2118
2119    // Only in a const implementation do we need to check that the `~const` item bounds hold.
2120    if tcx.is_conditionally_const(impl_ty_def_id) {
2121        obligations.extend(
2122            tcx.explicit_implied_const_bounds(trait_ty.def_id)
2123                .iter_instantiated_copied(tcx, rebased_args)
2124                .map(|(c, span)| {
2125                    traits::Obligation::new(
2126                        tcx,
2127                        mk_cause(span),
2128                        param_env,
2129                        c.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
2130                    )
2131                }),
2132        );
2133    }
2134    debug!(item_bounds=?obligations);
2135
2136    // Normalize predicates with the assumption that the GAT may always normalize
2137    // to its definition type. This should be the param-env we use to *prove* the
2138    // predicate too, but we don't do that because of performance issues.
2139    // See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
2140    let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args);
2141    let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity();
2142    let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
2143    for mut obligation in util::elaborate(tcx, obligations) {
2144        let normalized_predicate = if infcx.next_trait_solver() {
2145            obligation.predicate.fold_with(&mut ReplaceTy {
2146                tcx,
2147                from: trait_projection_ty,
2148                to: impl_identity_ty,
2149            })
2150        } else {
2151            ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate)
2152        };
2153        debug!(?normalized_predicate);
2154        obligation.predicate = normalized_predicate;
2155
2156        ocx.register_obligation(obligation);
2157    }
2158    // Check that all obligations are satisfied by the implementation's
2159    // version.
2160    let errors = ocx.select_all_or_error();
2161    if !errors.is_empty() {
2162        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
2163        return Err(reported);
2164    }
2165
2166    // Finally, resolve all regions. This catches wily misuses of
2167    // lifetime parameters.
2168    ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types)
2169}
2170
2171struct ReplaceTy<'tcx> {
2172    tcx: TyCtxt<'tcx>,
2173    from: Ty<'tcx>,
2174    to: Ty<'tcx>,
2175}
2176
2177impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
2178    fn cx(&self) -> TyCtxt<'tcx> {
2179        self.tcx
2180    }
2181
2182    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
2183        if self.from == ty { self.to } else { ty.super_fold_with(self) }
2184    }
2185}
2186
2187/// Install projection predicates that allow GATs to project to their own
2188/// definition types. This is not allowed in general in cases of default
2189/// associated types in trait definitions, or when specialization is involved,
2190/// but is needed when checking these definition types actually satisfy the
2191/// trait bounds of the GAT.
2192///
2193/// # How it works
2194///
2195/// ```ignore (example)
2196/// impl<A, B> Foo<u32> for (A, B) {
2197///     type Bar<C> = Wrapper<A, B, C>
2198/// }
2199/// ```
2200///
2201/// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>`
2202/// - `normalize_impl_ty_args` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
2203/// - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>`
2204/// - `rebased_args` would be `[(A, B), u32, ^0.0]`, combining the args from
2205///    the *trait* with the generic associated type parameters (as bound vars).
2206///
2207/// A note regarding the use of bound vars here:
2208/// Imagine as an example
2209/// ```
2210/// trait Family {
2211///     type Member<C: Eq>;
2212/// }
2213///
2214/// impl Family for VecFamily {
2215///     type Member<C: Eq> = i32;
2216/// }
2217/// ```
2218/// Here, we would generate
2219/// ```ignore (pseudo-rust)
2220/// forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) }
2221/// ```
2222///
2223/// when we really would like to generate
2224/// ```ignore (pseudo-rust)
2225/// forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) :- Implemented(C: Eq) }
2226/// ```
2227///
2228/// But, this is probably fine, because although the first clause can be used with types `C` that
2229/// do not implement `Eq`, for it to cause some kind of problem, there would have to be a
2230/// `VecFamily::Member<X>` for some type `X` where `!(X: Eq)`, that appears in the value of type
2231/// `Member<C: Eq> = ....` That type would fail a well-formedness check that we ought to be doing
2232/// elsewhere, which would check that any `<T as Family>::Member<X>` meets the bounds declared in
2233/// the trait (notably, that `X: Eq` and `T: Family`).
2234fn param_env_with_gat_bounds<'tcx>(
2235    tcx: TyCtxt<'tcx>,
2236    impl_ty: ty::AssocItem,
2237    impl_trait_ref: ty::TraitRef<'tcx>,
2238) -> ty::ParamEnv<'tcx> {
2239    let param_env = tcx.param_env(impl_ty.def_id);
2240    let container_id = impl_ty.container_id(tcx);
2241    let mut predicates = param_env.caller_bounds().to_vec();
2242
2243    // for RPITITs, we should install predicates that allow us to project all
2244    // of the RPITITs associated with the same body. This is because checking
2245    // the item bounds of RPITITs often involves nested RPITITs having to prove
2246    // bounds about themselves.
2247    let impl_tys_to_install = match impl_ty.opt_rpitit_info {
2248        None => vec![impl_ty],
2249        Some(
2250            ty::ImplTraitInTraitData::Impl { fn_def_id }
2251            | ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
2252        ) => tcx
2253            .associated_types_for_impl_traits_in_associated_fn(fn_def_id)
2254            .iter()
2255            .map(|def_id| tcx.associated_item(*def_id))
2256            .collect(),
2257    };
2258
2259    for impl_ty in impl_tys_to_install {
2260        let trait_ty = match impl_ty.container {
2261            ty::AssocItemContainer::Trait => impl_ty,
2262            ty::AssocItemContainer::Impl => tcx.associated_item(impl_ty.trait_item_def_id.unwrap()),
2263        };
2264
2265        let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
2266            smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).own_params.len());
2267        // Extend the impl's identity args with late-bound GAT vars
2268        let normalize_impl_ty_args = ty::GenericArgs::identity_for_item(tcx, container_id)
2269            .extend_to(tcx, impl_ty.def_id, |param, _| match param.kind {
2270                GenericParamDefKind::Type { .. } => {
2271                    let kind = ty::BoundTyKind::Param(param.def_id, param.name);
2272                    let bound_var = ty::BoundVariableKind::Ty(kind);
2273                    bound_vars.push(bound_var);
2274                    Ty::new_bound(
2275                        tcx,
2276                        ty::INNERMOST,
2277                        ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
2278                    )
2279                    .into()
2280                }
2281                GenericParamDefKind::Lifetime => {
2282                    let kind = ty::BoundRegionKind::Named(param.def_id, param.name);
2283                    let bound_var = ty::BoundVariableKind::Region(kind);
2284                    bound_vars.push(bound_var);
2285                    ty::Region::new_bound(
2286                        tcx,
2287                        ty::INNERMOST,
2288                        ty::BoundRegion {
2289                            var: ty::BoundVar::from_usize(bound_vars.len() - 1),
2290                            kind,
2291                        },
2292                    )
2293                    .into()
2294                }
2295                GenericParamDefKind::Const { .. } => {
2296                    let bound_var = ty::BoundVariableKind::Const;
2297                    bound_vars.push(bound_var);
2298                    ty::Const::new_bound(
2299                        tcx,
2300                        ty::INNERMOST,
2301                        ty::BoundVar::from_usize(bound_vars.len() - 1),
2302                    )
2303                    .into()
2304                }
2305            });
2306        // When checking something like
2307        //
2308        // trait X { type Y: PartialEq<<Self as X>::Y> }
2309        // impl X for T { default type Y = S; }
2310        //
2311        // We will have to prove the bound S: PartialEq<<T as X>::Y>. In this case
2312        // we want <T as X>::Y to normalize to S. This is valid because we are
2313        // checking the default value specifically here. Add this equality to the
2314        // ParamEnv for normalization specifically.
2315        let normalize_impl_ty =
2316            tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args);
2317        let rebased_args =
2318            normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
2319        let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
2320
2321        match normalize_impl_ty.kind() {
2322            ty::Alias(ty::Projection, proj)
2323                if proj.def_id == trait_ty.def_id && proj.args == rebased_args =>
2324            {
2325                // Don't include this predicate if the projected type is
2326                // exactly the same as the projection. This can occur in
2327                // (somewhat dubious) code like this:
2328                //
2329                // impl<T> X for T where T: X { type Y = <T as X>::Y; }
2330            }
2331            _ => predicates.push(
2332                ty::Binder::bind_with_vars(
2333                    ty::ProjectionPredicate {
2334                        projection_term: ty::AliasTerm::new_from_args(
2335                            tcx,
2336                            trait_ty.def_id,
2337                            rebased_args,
2338                        ),
2339                        term: normalize_impl_ty.into(),
2340                    },
2341                    bound_vars,
2342                )
2343                .upcast(tcx),
2344            ),
2345        };
2346    }
2347
2348    ty::ParamEnv::new(tcx.mk_clauses(&predicates))
2349}
2350
2351/// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
2352/// and extract a better error if so.
2353fn try_report_async_mismatch<'tcx>(
2354    tcx: TyCtxt<'tcx>,
2355    infcx: &InferCtxt<'tcx>,
2356    errors: &[FulfillmentError<'tcx>],
2357    trait_m: ty::AssocItem,
2358    impl_m: ty::AssocItem,
2359    impl_sig: ty::FnSig<'tcx>,
2360) -> Result<(), ErrorGuaranteed> {
2361    if !tcx.asyncness(trait_m.def_id).is_async() {
2362        return Ok(());
2363    }
2364
2365    let ty::Alias(ty::Projection, ty::AliasTy { def_id: async_future_def_id, .. }) =
2366        *tcx.fn_sig(trait_m.def_id).skip_binder().skip_binder().output().kind()
2367    else {
2368        bug!("expected `async fn` to return an RPITIT");
2369    };
2370
2371    for error in errors {
2372        if let ObligationCauseCode::WhereClause(def_id, _) = *error.root_obligation.cause.code()
2373            && def_id == async_future_def_id
2374            && let Some(proj) = error.root_obligation.predicate.as_projection_clause()
2375            && let Some(proj) = proj.no_bound_vars()
2376            && infcx.can_eq(
2377                error.root_obligation.param_env,
2378                proj.term.expect_type(),
2379                impl_sig.output(),
2380            )
2381        {
2382            // FIXME: We should suggest making the fn `async`, but extracting
2383            // the right span is a bit difficult.
2384            return Err(tcx.sess.dcx().emit_err(MethodShouldReturnFuture {
2385                span: tcx.def_span(impl_m.def_id),
2386                method_name: tcx.item_ident(impl_m.def_id),
2387                trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
2388            }));
2389        }
2390    }
2391
2392    Ok(())
2393}