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