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