]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/wfcheck.rs
Rollup merge of #97712 - RalfJung:untyped, r=scottmcm
[rust.git] / compiler / rustc_typeck / src / check / wfcheck.rs
1 use crate::check::regionck::OutlivesEnvironmentExt;
2 use crate::check::{FnCtxt, Inherited};
3 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
4
5 use rustc_ast as ast;
6 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
7 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
8 use rustc_hir as hir;
9 use rustc_hir::def_id::{DefId, LocalDefId};
10 use rustc_hir::lang_items::LangItem;
11 use rustc_hir::ItemKind;
12 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
13 use rustc_infer::infer::outlives::obligations::TypeOutlives;
14 use rustc_infer::infer::region_constraints::GenericKind;
15 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
16 use rustc_middle::ty::query::Providers;
17 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
18 use rustc_middle::ty::trait_def::TraitSpecializationKind;
19 use rustc_middle::ty::{
20     self, AdtKind, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt,
21     TypeFoldable, TypeSuperFoldable, TypeVisitor,
22 };
23 use rustc_session::parse::feature_err;
24 use rustc_span::symbol::{sym, Ident, Symbol};
25 use rustc_span::{Span, DUMMY_SP};
26 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
27 use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
28
29 use std::cell::LazyCell;
30 use std::convert::TryInto;
31 use std::iter;
32 use std::ops::ControlFlow;
33
34 /// Helper type of a temporary returned by `.for_item(...)`.
35 /// This is necessary because we can't write the following bound:
36 ///
37 /// ```ignore (illustrative)
38 /// F: for<'b, 'tcx> where 'tcx FnOnce(FnCtxt<'b, 'tcx>)
39 /// ```
40 pub(super) struct CheckWfFcxBuilder<'tcx> {
41     inherited: super::InheritedBuilder<'tcx>,
42     id: hir::HirId,
43     span: Span,
44     param_env: ty::ParamEnv<'tcx>,
45 }
46
47 impl<'tcx> CheckWfFcxBuilder<'tcx> {
48     pub(super) fn with_fcx<F>(&mut self, f: F)
49     where
50         F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet<Ty<'tcx>>,
51     {
52         let id = self.id;
53         let span = self.span;
54         let param_env = self.param_env;
55         self.inherited.enter(|inh| {
56             let fcx = FnCtxt::new(&inh, param_env, id);
57             if !inh.tcx.features().trivial_bounds {
58                 // As predicates are cached rather than obligations, this
59                 // needs to be called first so that they are checked with an
60                 // empty `param_env`.
61                 check_false_global_bounds(&fcx, span, id);
62             }
63             let wf_tys = f(&fcx);
64             fcx.select_all_obligations_or_error();
65             fcx.regionck_item(id, span, wf_tys);
66         });
67     }
68 }
69
70 fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
71     let node = tcx.hir().expect_owner(def_id);
72     match node {
73         hir::OwnerNode::Crate(_) => {}
74         hir::OwnerNode::Item(item) => check_item(tcx, item),
75         hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
76         hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
77         hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
78     }
79
80     if let Some(generics) = node.generics() {
81         for param in generics.params {
82             check_param_wf(tcx, param)
83         }
84     }
85 }
86
87 /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
88 /// well-formed, meaning that they do not require any constraints not declared in the struct
89 /// definition itself. For example, this definition would be illegal:
90 ///
91 /// ```rust
92 /// struct Ref<'a, T> { x: &'a T }
93 /// ```
94 ///
95 /// because the type did not declare that `T:'a`.
96 ///
97 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
98 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
99 /// the types first.
100 #[instrument(skip(tcx), level = "debug")]
101 fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
102     let def_id = item.def_id;
103
104     debug!(
105         ?item.def_id,
106         item.name = ? tcx.def_path_str(def_id.to_def_id())
107     );
108
109     match item.kind {
110         // Right now we check that every default trait implementation
111         // has an implementation of itself. Basically, a case like:
112         //
113         //     impl Trait for T {}
114         //
115         // has a requirement of `T: Trait` which was required for default
116         // method implementations. Although this could be improved now that
117         // there's a better infrastructure in place for this, it's being left
118         // for a follow-up work.
119         //
120         // Since there's such a requirement, we need to check *just* positive
121         // implementations, otherwise things like:
122         //
123         //     impl !Send for T {}
124         //
125         // won't be allowed unless there's an *explicit* implementation of `Send`
126         // for `T`
127         hir::ItemKind::Impl(ref impl_) => {
128             let is_auto = tcx
129                 .impl_trait_ref(item.def_id)
130                 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
131             if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
132                 let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
133                 let mut err =
134                     tcx.sess.struct_span_err(sp, "impls of auto traits cannot be default");
135                 err.span_labels(impl_.defaultness_span, "default because of this");
136                 err.span_label(sp, "auto trait");
137                 err.emit();
138             }
139             // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
140             match (tcx.impl_polarity(def_id), impl_.polarity) {
141                 (ty::ImplPolarity::Positive, _) => {
142                     check_impl(tcx, item, impl_.self_ty, &impl_.of_trait);
143                 }
144                 (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
145                     // FIXME(#27579): what amount of WF checking do we need for neg impls?
146                     if let hir::Defaultness::Default { .. } = impl_.defaultness {
147                         let mut spans = vec![span];
148                         spans.extend(impl_.defaultness_span);
149                         struct_span_err!(
150                             tcx.sess,
151                             spans,
152                             E0750,
153                             "negative impls cannot be default impls"
154                         )
155                         .emit();
156                     }
157                 }
158                 (ty::ImplPolarity::Reservation, _) => {
159                     // FIXME: what amount of WF checking do we need for reservation impls?
160                 }
161                 _ => unreachable!(),
162             }
163         }
164         hir::ItemKind::Fn(ref sig, ..) => {
165             check_item_fn(tcx, item.def_id, item.ident, item.span, sig.decl);
166         }
167         hir::ItemKind::Static(ty, ..) => {
168             check_item_type(tcx, item.def_id, ty.span, false);
169         }
170         hir::ItemKind::Const(ty, ..) => {
171             check_item_type(tcx, item.def_id, ty.span, false);
172         }
173         hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
174             check_type_defn(tcx, item, false, |fcx| vec![fcx.non_enum_variant(struct_def)]);
175
176             check_variances_for_type_defn(tcx, item, ast_generics);
177         }
178         hir::ItemKind::Union(ref struct_def, ref ast_generics) => {
179             check_type_defn(tcx, item, true, |fcx| vec![fcx.non_enum_variant(struct_def)]);
180
181             check_variances_for_type_defn(tcx, item, ast_generics);
182         }
183         hir::ItemKind::Enum(ref enum_def, ref ast_generics) => {
184             check_type_defn(tcx, item, true, |fcx| fcx.enum_variants(enum_def));
185
186             check_variances_for_type_defn(tcx, item, ast_generics);
187         }
188         hir::ItemKind::Trait(..) => {
189             check_trait(tcx, item);
190         }
191         hir::ItemKind::TraitAlias(..) => {
192             check_trait(tcx, item);
193         }
194         // `ForeignItem`s are handled separately.
195         hir::ItemKind::ForeignMod { .. } => {}
196         _ => {}
197     }
198 }
199
200 fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
201     let def_id = item.def_id;
202
203     debug!(
204         ?item.def_id,
205         item.name = ? tcx.def_path_str(def_id.to_def_id())
206     );
207
208     match item.kind {
209         hir::ForeignItemKind::Fn(decl, ..) => {
210             check_item_fn(tcx, item.def_id, item.ident, item.span, decl)
211         }
212         hir::ForeignItemKind::Static(ty, ..) => check_item_type(tcx, item.def_id, ty.span, true),
213         hir::ForeignItemKind::Type => (),
214     }
215 }
216
217 fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
218     let def_id = trait_item.def_id;
219
220     let (method_sig, span) = match trait_item.kind {
221         hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
222         hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span),
223         _ => (None, trait_item.span),
224     };
225     check_object_unsafe_self_trait_by_name(tcx, trait_item);
226     check_associated_item(tcx, trait_item.def_id, span, method_sig);
227
228     let encl_trait_def_id = tcx.local_parent(def_id);
229     let encl_trait = tcx.hir().expect_item(encl_trait_def_id);
230     let encl_trait_def_id = encl_trait.def_id.to_def_id();
231     let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
232         Some("fn")
233     } else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() {
234         Some("fn_mut")
235     } else {
236         None
237     };
238
239     if let (Some(fn_lang_item_name), "call") =
240         (fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str())
241     {
242         // We are looking at the `call` function of the `fn` or `fn_mut` lang item.
243         // Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
244         if let Some(hir::FnSig { decl, span, .. }) = method_sig {
245             if let [self_ty, _] = decl.inputs {
246                 if !matches!(self_ty.kind, hir::TyKind::Rptr(_, _)) {
247                     tcx.sess
248                         .struct_span_err(
249                             self_ty.span,
250                             &format!(
251                                 "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
252                             ),
253                         )
254                         .emit();
255                 }
256             } else {
257                 tcx.sess
258                     .struct_span_err(
259                         *span,
260                         &format!(
261                             "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
262                         ),
263                     )
264                     .emit();
265             }
266         } else {
267             tcx.sess
268                 .struct_span_err(
269                     trait_item.span,
270                     &format!(
271                         "`call` trait item in `{fn_lang_item_name}` lang item must be a function",
272                     ),
273                 )
274                 .emit();
275         }
276     }
277 }
278
279 /// Require that the user writes where clauses on GATs for the implicit
280 /// outlives bounds involving trait parameters in trait functions and
281 /// lifetimes passed as GAT substs. See `self-outlives-lint` test.
282 ///
283 /// We use the following trait as an example throughout this function:
284 /// ```rust,ignore (this code fails due to this lint)
285 /// trait IntoIter {
286 ///     type Iter<'a>: Iterator<Item = Self::Item<'a>>;
287 ///     type Item<'a>;
288 ///     fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
289 /// }
290 /// ```
291 fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRef]) {
292     // Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
293     let mut required_bounds_by_item = FxHashMap::default();
294
295     // Loop over all GATs together, because if this lint suggests adding a where-clause bound
296     // to one GAT, it might then require us to an additional bound on another GAT.
297     // In our `IntoIter` example, we discover a missing `Self: 'a` bound on `Iter<'a>`, which
298     // then in a second loop adds a `Self: 'a` bound to `Item` due to the relationship between
299     // those GATs.
300     loop {
301         let mut should_continue = false;
302         for gat_item in associated_items {
303             let gat_def_id = gat_item.id.def_id;
304             let gat_item = tcx.associated_item(gat_def_id);
305             // If this item is not an assoc ty, or has no substs, then it's not a GAT
306             if gat_item.kind != ty::AssocKind::Type {
307                 continue;
308             }
309             let gat_generics = tcx.generics_of(gat_def_id);
310             // FIXME(jackh726): we can also warn in the more general case
311             if gat_generics.params.is_empty() {
312                 continue;
313             }
314
315             // Gather the bounds with which all other items inside of this trait constrain the GAT.
316             // This is calculated by taking the intersection of the bounds that each item
317             // constrains the GAT with individually.
318             let mut new_required_bounds: Option<FxHashSet<ty::Predicate<'_>>> = None;
319             for item in associated_items {
320                 let item_def_id = item.id.def_id;
321                 // Skip our own GAT, since it does not constrain itself at all.
322                 if item_def_id == gat_def_id {
323                     continue;
324                 }
325
326                 let item_hir_id = item.id.hir_id();
327                 let param_env = tcx.param_env(item_def_id);
328
329                 let item_required_bounds = match item.kind {
330                     // In our example, this corresponds to `into_iter` method
331                     hir::AssocItemKind::Fn { .. } => {
332                         // For methods, we check the function signature's return type for any GATs
333                         // to constrain. In the `into_iter` case, we see that the return type
334                         // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
335                         let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions(
336                             item_def_id.to_def_id(),
337                             tcx.fn_sig(item_def_id),
338                         );
339                         gather_gat_bounds(
340                             tcx,
341                             param_env,
342                             item_hir_id,
343                             sig.output(),
344                             // We also assume that all of the function signature's parameter types
345                             // are well formed.
346                             &sig.inputs().iter().copied().collect(),
347                             gat_def_id,
348                             gat_generics,
349                         )
350                     }
351                     // In our example, this corresponds to the `Iter` and `Item` associated types
352                     hir::AssocItemKind::Type => {
353                         // If our associated item is a GAT with missing bounds, add them to
354                         // the param-env here. This allows this GAT to propagate missing bounds
355                         // to other GATs.
356                         let param_env = augment_param_env(
357                             tcx,
358                             param_env,
359                             required_bounds_by_item.get(&item_def_id),
360                         );
361                         gather_gat_bounds(
362                             tcx,
363                             param_env,
364                             item_hir_id,
365                             tcx.explicit_item_bounds(item_def_id)
366                                 .iter()
367                                 .copied()
368                                 .collect::<Vec<_>>(),
369                             &FxHashSet::default(),
370                             gat_def_id,
371                             gat_generics,
372                         )
373                     }
374                     hir::AssocItemKind::Const => None,
375                 };
376
377                 if let Some(item_required_bounds) = item_required_bounds {
378                     // Take the intersection of the required bounds for this GAT, and
379                     // the item_required_bounds which are the ones implied by just
380                     // this item alone.
381                     // This is why we use an Option<_>, since we need to distinguish
382                     // the empty set of bounds from the _uninitialized_ set of bounds.
383                     if let Some(new_required_bounds) = &mut new_required_bounds {
384                         new_required_bounds.retain(|b| item_required_bounds.contains(b));
385                     } else {
386                         new_required_bounds = Some(item_required_bounds);
387                     }
388                 }
389             }
390
391             if let Some(new_required_bounds) = new_required_bounds {
392                 let required_bounds = required_bounds_by_item.entry(gat_def_id).or_default();
393                 if new_required_bounds.into_iter().any(|p| required_bounds.insert(p)) {
394                     // Iterate until our required_bounds no longer change
395                     // Since they changed here, we should continue the loop
396                     should_continue = true;
397                 }
398             }
399         }
400         // We know that this loop will eventually halt, since we only set `should_continue` if the
401         // `required_bounds` for this item grows. Since we are not creating any new region or type
402         // variables, the set of all region and type bounds that we could ever insert are limited
403         // by the number of unique types and regions we observe in a given item.
404         if !should_continue {
405             break;
406         }
407     }
408
409     for (gat_def_id, required_bounds) in required_bounds_by_item {
410         let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id);
411         debug!(?required_bounds);
412         let param_env = tcx.param_env(gat_def_id);
413         let gat_hir = gat_item_hir.hir_id();
414
415         let mut unsatisfied_bounds: Vec<_> = required_bounds
416             .into_iter()
417             .filter(|clause| match clause.kind().skip_binder() {
418                 ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
419                     !region_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b)
420                 }
421                 ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
422                     !ty_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b)
423                 }
424                 _ => bug!("Unexpected PredicateKind"),
425             })
426             .map(|clause| clause.to_string())
427             .collect();
428
429         // We sort so that order is predictable
430         unsatisfied_bounds.sort();
431
432         if !unsatisfied_bounds.is_empty() {
433             let plural = if unsatisfied_bounds.len() > 1 { "s" } else { "" };
434             let mut err = tcx.sess.struct_span_err(
435                 gat_item_hir.span,
436                 &format!("missing required bound{} on `{}`", plural, gat_item_hir.ident),
437             );
438
439             let suggestion = format!(
440                 "{} {}",
441                 gat_item_hir.generics.add_where_or_trailing_comma(),
442                 unsatisfied_bounds.join(", "),
443             );
444             err.span_suggestion(
445                 gat_item_hir.generics.tail_span_for_predicate_suggestion(),
446                 &format!("add the required where clause{plural}"),
447                 suggestion,
448                 Applicability::MachineApplicable,
449             );
450
451             let bound =
452                 if unsatisfied_bounds.len() > 1 { "these bounds are" } else { "this bound is" };
453             err.note(&format!(
454                 "{} currently required to ensure that impls have maximum flexibility",
455                 bound
456             ));
457             err.note(
458                 "we are soliciting feedback, see issue #87479 \
459                  <https://github.com/rust-lang/rust/issues/87479> \
460                  for more information",
461             );
462
463             err.emit();
464         }
465     }
466 }
467
468 /// Add a new set of predicates to the caller_bounds of an existing param_env.
469 fn augment_param_env<'tcx>(
470     tcx: TyCtxt<'tcx>,
471     param_env: ty::ParamEnv<'tcx>,
472     new_predicates: Option<&FxHashSet<ty::Predicate<'tcx>>>,
473 ) -> ty::ParamEnv<'tcx> {
474     let Some(new_predicates) = new_predicates else {
475         return param_env;
476     };
477
478     if new_predicates.is_empty() {
479         return param_env;
480     }
481
482     let bounds =
483         tcx.mk_predicates(param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()));
484     // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
485     // i.e. traits::normalize_param_env_or_error
486     ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness())
487 }
488
489 /// We use the following trait as an example throughout this function.
490 /// Specifically, let's assume that `to_check` here is the return type
491 /// of `into_iter`, and the GAT we are checking this for is `Iter`.
492 /// ```rust,ignore (this code fails due to this lint)
493 /// trait IntoIter {
494 ///     type Iter<'a>: Iterator<Item = Self::Item<'a>>;
495 ///     type Item<'a>;
496 ///     fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
497 /// }
498 /// ```
499 fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
500     tcx: TyCtxt<'tcx>,
501     param_env: ty::ParamEnv<'tcx>,
502     item_hir: hir::HirId,
503     to_check: T,
504     wf_tys: &FxHashSet<Ty<'tcx>>,
505     gat_def_id: LocalDefId,
506     gat_generics: &'tcx ty::Generics,
507 ) -> Option<FxHashSet<ty::Predicate<'tcx>>> {
508     // The bounds we that we would require from `to_check`
509     let mut bounds = FxHashSet::default();
510
511     let (regions, types) = GATSubstCollector::visit(gat_def_id.to_def_id(), to_check);
512
513     // If both regions and types are empty, then this GAT isn't in the
514     // set of types we are checking, and we shouldn't try to do clause analysis
515     // (particularly, doing so would end up with an empty set of clauses,
516     // since the current method would require none, and we take the
517     // intersection of requirements of all methods)
518     if types.is_empty() && regions.is_empty() {
519         return None;
520     }
521
522     for (region_a, region_a_idx) in &regions {
523         // Ignore `'static` lifetimes for the purpose of this lint: it's
524         // because we know it outlives everything and so doesn't give meaningful
525         // clues
526         if let ty::ReStatic = **region_a {
527             continue;
528         }
529         // For each region argument (e.g., `'a` in our example), check for a
530         // relationship to the type arguments (e.g., `Self`). If there is an
531         // outlives relationship (`Self: 'a`), then we want to ensure that is
532         // reflected in a where clause on the GAT itself.
533         for (ty, ty_idx) in &types {
534             // In our example, requires that `Self: 'a`
535             if ty_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *ty, *region_a) {
536                 debug!(?ty_idx, ?region_a_idx);
537                 debug!("required clause: {ty} must outlive {region_a}");
538                 // Translate into the generic parameters of the GAT. In
539                 // our example, the type was `Self`, which will also be
540                 // `Self` in the GAT.
541                 let ty_param = gat_generics.param_at(*ty_idx, tcx);
542                 let ty_param = tcx
543                     .mk_ty(ty::Param(ty::ParamTy { index: ty_param.index, name: ty_param.name }));
544                 // Same for the region. In our example, 'a corresponds
545                 // to the 'me parameter.
546                 let region_param = gat_generics.param_at(*region_a_idx, tcx);
547                 let region_param =
548                     tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
549                         def_id: region_param.def_id,
550                         index: region_param.index,
551                         name: region_param.name,
552                     }));
553                 // The predicate we expect to see. (In our example,
554                 // `Self: 'me`.)
555                 let clause =
556                     ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_param, region_param));
557                 let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
558                 bounds.insert(clause);
559             }
560         }
561
562         // For each region argument (e.g., `'a` in our example), also check for a
563         // relationship to the other region arguments. If there is an outlives
564         // relationship, then we want to ensure that is reflected in the where clause
565         // on the GAT itself.
566         for (region_b, region_b_idx) in &regions {
567             // Again, skip `'static` because it outlives everything. Also, we trivially
568             // know that a region outlives itself.
569             if ty::ReStatic == **region_b || region_a == region_b {
570                 continue;
571             }
572             if region_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *region_a, *region_b) {
573                 debug!(?region_a_idx, ?region_b_idx);
574                 debug!("required clause: {region_a} must outlive {region_b}");
575                 // Translate into the generic parameters of the GAT.
576                 let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
577                 let region_a_param =
578                     tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
579                         def_id: region_a_param.def_id,
580                         index: region_a_param.index,
581                         name: region_a_param.name,
582                     }));
583                 // Same for the region.
584                 let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
585                 let region_b_param =
586                     tcx.mk_region(ty::RegionKind::ReEarlyBound(ty::EarlyBoundRegion {
587                         def_id: region_b_param.def_id,
588                         index: region_b_param.index,
589                         name: region_b_param.name,
590                     }));
591                 // The predicate we expect to see.
592                 let clause = ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
593                     region_a_param,
594                     region_b_param,
595                 ));
596                 let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
597                 bounds.insert(clause);
598             }
599         }
600     }
601
602     Some(bounds)
603 }
604
605 /// Given a known `param_env` and a set of well formed types, can we prove that
606 /// `ty` outlives `region`.
607 fn ty_known_to_outlive<'tcx>(
608     tcx: TyCtxt<'tcx>,
609     id: hir::HirId,
610     param_env: ty::ParamEnv<'tcx>,
611     wf_tys: &FxHashSet<Ty<'tcx>>,
612     ty: Ty<'tcx>,
613     region: ty::Region<'tcx>,
614 ) -> bool {
615     resolve_regions_with_wf_tys(tcx, id, param_env, &wf_tys, |infcx, region_bound_pairs| {
616         let origin = infer::RelateParamBound(DUMMY_SP, ty, None);
617         let outlives = &mut TypeOutlives::new(infcx, tcx, region_bound_pairs, None, param_env);
618         outlives.type_must_outlive(origin, ty, region);
619     })
620 }
621
622 /// Given a known `param_env` and a set of well formed types, can we prove that
623 /// `region_a` outlives `region_b`
624 fn region_known_to_outlive<'tcx>(
625     tcx: TyCtxt<'tcx>,
626     id: hir::HirId,
627     param_env: ty::ParamEnv<'tcx>,
628     wf_tys: &FxHashSet<Ty<'tcx>>,
629     region_a: ty::Region<'tcx>,
630     region_b: ty::Region<'tcx>,
631 ) -> bool {
632     resolve_regions_with_wf_tys(tcx, id, param_env, &wf_tys, |mut infcx, _| {
633         use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate;
634         let origin = infer::RelateRegionParamBound(DUMMY_SP);
635         // `region_a: region_b` -> `region_b <= region_a`
636         infcx.push_sub_region_constraint(origin, region_b, region_a);
637     })
638 }
639
640 /// Given a known `param_env` and a set of well formed types, set up an
641 /// `InferCtxt`, call the passed function (to e.g. set up region constraints
642 /// to be tested), then resolve region and return errors
643 fn resolve_regions_with_wf_tys<'tcx>(
644     tcx: TyCtxt<'tcx>,
645     id: hir::HirId,
646     param_env: ty::ParamEnv<'tcx>,
647     wf_tys: &FxHashSet<Ty<'tcx>>,
648     add_constraints: impl for<'a> FnOnce(
649         &'a InferCtxt<'a, 'tcx>,
650         &'a Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
651     ),
652 ) -> bool {
653     // Unfortunately, we have to use a new `InferCtxt` each call, because
654     // region constraints get added and solved there and we need to test each
655     // call individually.
656     tcx.infer_ctxt().enter(|infcx| {
657         let mut outlives_environment = OutlivesEnvironment::new(param_env);
658         outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id, DUMMY_SP);
659         outlives_environment.save_implied_bounds(id);
660         let region_bound_pairs = outlives_environment.region_bound_pairs_map().get(&id).unwrap();
661
662         add_constraints(&infcx, region_bound_pairs);
663
664         let errors = infcx.resolve_regions(id.expect_owner().to_def_id(), &outlives_environment);
665
666         debug!(?errors, "errors");
667
668         // If we were able to prove that the type outlives the region without
669         // an error, it must be because of the implied or explicit bounds...
670         errors.is_empty()
671     })
672 }
673
674 /// TypeVisitor that looks for uses of GATs like
675 /// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
676 /// the two vectors, `regions` and `types` (depending on their kind). For each
677 /// parameter `Pi` also track the index `i`.
678 struct GATSubstCollector<'tcx> {
679     gat: DefId,
680     // Which region appears and which parameter index its substituted for
681     regions: FxHashSet<(ty::Region<'tcx>, usize)>,
682     // Which params appears and which parameter index its substituted for
683     types: FxHashSet<(Ty<'tcx>, usize)>,
684 }
685
686 impl<'tcx> GATSubstCollector<'tcx> {
687     fn visit<T: TypeFoldable<'tcx>>(
688         gat: DefId,
689         t: T,
690     ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
691         let mut visitor =
692             GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
693         t.visit_with(&mut visitor);
694         (visitor.regions, visitor.types)
695     }
696 }
697
698 impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
699     type BreakTy = !;
700
701     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
702         match t.kind() {
703             ty::Projection(p) if p.item_def_id == self.gat => {
704                 for (idx, subst) in p.substs.iter().enumerate() {
705                     match subst.unpack() {
706                         GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
707                             self.regions.insert((lt, idx));
708                         }
709                         GenericArgKind::Type(t) => {
710                             self.types.insert((t, idx));
711                         }
712                         _ => {}
713                     }
714                 }
715             }
716             _ => {}
717         }
718         t.super_visit_with(self)
719     }
720 }
721
722 fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
723     match ty.kind {
724         hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
725             [s] => s.res.and_then(|r| r.opt_def_id()) == Some(trait_def_id.to_def_id()),
726             _ => false,
727         },
728         _ => false,
729     }
730 }
731
732 /// Detect when an object unsafe trait is referring to itself in one of its associated items.
733 /// When this is done, suggest using `Self` instead.
734 fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
735     let (trait_name, trait_def_id) =
736         match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id())) {
737             hir::Node::Item(item) => match item.kind {
738                 hir::ItemKind::Trait(..) => (item.ident, item.def_id),
739                 _ => return,
740             },
741             _ => return,
742         };
743     let mut trait_should_be_self = vec![];
744     match &item.kind {
745         hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty))
746             if could_be_self(trait_def_id, ty) =>
747         {
748             trait_should_be_self.push(ty.span)
749         }
750         hir::TraitItemKind::Fn(sig, _) => {
751             for ty in sig.decl.inputs {
752                 if could_be_self(trait_def_id, ty) {
753                     trait_should_be_self.push(ty.span);
754                 }
755             }
756             match sig.decl.output {
757                 hir::FnRetTy::Return(ty) if could_be_self(trait_def_id, ty) => {
758                     trait_should_be_self.push(ty.span);
759                 }
760                 _ => {}
761             }
762         }
763         _ => {}
764     }
765     if !trait_should_be_self.is_empty() {
766         if tcx.object_safety_violations(trait_def_id).is_empty() {
767             return;
768         }
769         let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect();
770         tcx.sess
771             .struct_span_err(
772                 trait_should_be_self,
773                 "associated item referring to unboxed trait object for its own trait",
774             )
775             .span_label(trait_name.span, "in this trait")
776             .multipart_suggestion(
777                 "you might have meant to use `Self` to refer to the implementing type",
778                 sugg,
779                 Applicability::MachineApplicable,
780             )
781             .emit();
782     }
783 }
784
785 fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
786     let def_id = impl_item.def_id;
787
788     let (method_sig, span) = match impl_item.kind {
789         hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
790         // Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`.
791         hir::ImplItemKind::TyAlias(ty) if ty.span != DUMMY_SP => (None, ty.span),
792         _ => (None, impl_item.span),
793     };
794
795     check_associated_item(tcx, def_id, span, method_sig);
796 }
797
798 fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
799     match param.kind {
800         // We currently only check wf of const params here.
801         hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (),
802
803         // Const parameters are well formed if their type is structural match.
804         hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
805             let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id));
806
807             if tcx.features().adt_const_params {
808                 let err = match ty.peel_refs().kind() {
809                     ty::FnPtr(_) => Some("function pointers"),
810                     ty::RawPtr(_) => Some("raw pointers"),
811                     _ => None,
812                 };
813
814                 if let Some(unsupported_type) = err {
815                     tcx.sess.span_err(
816                         hir_ty.span,
817                         &format!(
818                             "using {} as const generic parameters is forbidden",
819                             unsupported_type
820                         ),
821                     );
822                 }
823
824                 if let Some(non_structural_match_ty) =
825                     traits::search_for_structural_match_violation(param.span, tcx, ty)
826                 {
827                     // We use the same error code in both branches, because this is really the same
828                     // issue: we just special-case the message for type parameters to make it
829                     // clearer.
830                     if let ty::Param(_) = ty.peel_refs().kind() {
831                         // Const parameters may not have type parameters as their types,
832                         // because we cannot be sure that the type parameter derives `PartialEq`
833                         // and `Eq` (just implementing them is not enough for `structural_match`).
834                         struct_span_err!(
835                             tcx.sess,
836                             hir_ty.span,
837                             E0741,
838                             "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
839                             used as the type of a const parameter",
840                             ty,
841                         )
842                         .span_label(
843                             hir_ty.span,
844                             format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
845                         )
846                         .note(
847                             "it is not currently possible to use a type parameter as the type of a \
848                             const parameter",
849                         )
850                         .emit();
851                     } else {
852                         let mut diag = struct_span_err!(
853                             tcx.sess,
854                             hir_ty.span,
855                             E0741,
856                             "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
857                             the type of a const parameter",
858                             non_structural_match_ty.ty,
859                         );
860
861                         if ty == non_structural_match_ty.ty {
862                             diag.span_label(
863                                 hir_ty.span,
864                                 format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
865                             );
866                         }
867
868                         diag.emit();
869                     }
870                 }
871             } else {
872                 let err_ty_str;
873                 let mut is_ptr = true;
874
875                 let err = match ty.kind() {
876                     ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
877                     ty::FnPtr(_) => Some("function pointers"),
878                     ty::RawPtr(_) => Some("raw pointers"),
879                     _ => {
880                         is_ptr = false;
881                         err_ty_str = format!("`{ty}`");
882                         Some(err_ty_str.as_str())
883                     }
884                 };
885
886                 if let Some(unsupported_type) = err {
887                     if is_ptr {
888                         tcx.sess.span_err(
889                             hir_ty.span,
890                             &format!(
891                                 "using {unsupported_type} as const generic parameters is forbidden",
892                             ),
893                         );
894                     } else {
895                         let mut err = tcx.sess.struct_span_err(
896                             hir_ty.span,
897                             &format!(
898                                 "{unsupported_type} is forbidden as the type of a const generic parameter",
899                             ),
900                         );
901                         err.note("the only supported types are integers, `bool` and `char`");
902                         if tcx.sess.is_nightly_build() {
903                             err.help(
904                             "more complex types are supported with `#![feature(adt_const_params)]`",
905                         );
906                         }
907                         err.emit();
908                     }
909                 }
910             }
911         }
912     }
913 }
914
915 #[tracing::instrument(level = "debug", skip(tcx, span, sig_if_method))]
916 fn check_associated_item(
917     tcx: TyCtxt<'_>,
918     item_id: LocalDefId,
919     span: Span,
920     sig_if_method: Option<&hir::FnSig<'_>>,
921 ) {
922     let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id)));
923     for_id(tcx, item_id, span).with_fcx(|fcx| {
924         let item = fcx.tcx.associated_item(item_id);
925
926         let (mut implied_bounds, self_ty) = match item.container {
927             ty::TraitContainer(_) => (FxHashSet::default(), fcx.tcx.types.self_param),
928             ty::ImplContainer(def_id) => {
929                 (fcx.impl_implied_bounds(def_id, span), fcx.tcx.type_of(def_id))
930             }
931         };
932
933         match item.kind {
934             ty::AssocKind::Const => {
935                 let ty = fcx.tcx.type_of(item.def_id);
936                 let ty = fcx.normalize_associated_types_in_wf(span, ty, WellFormedLoc::Ty(item_id));
937                 fcx.register_wf_obligation(ty.into(), span, code.clone());
938             }
939             ty::AssocKind::Fn => {
940                 let sig = fcx.tcx.fn_sig(item.def_id);
941                 let hir_sig = sig_if_method.expect("bad signature for method");
942                 check_fn_or_method(
943                     fcx,
944                     item.ident(fcx.tcx).span,
945                     sig,
946                     hir_sig.decl,
947                     item.def_id.expect_local(),
948                     &mut implied_bounds,
949                 );
950                 check_method_receiver(fcx, hir_sig, item, self_ty);
951             }
952             ty::AssocKind::Type => {
953                 if let ty::AssocItemContainer::TraitContainer(_) = item.container {
954                     check_associated_type_bounds(fcx, item, span)
955                 }
956                 if item.defaultness.has_value() {
957                     let ty = fcx.tcx.type_of(item.def_id);
958                     let ty =
959                         fcx.normalize_associated_types_in_wf(span, ty, WellFormedLoc::Ty(item_id));
960                     fcx.register_wf_obligation(ty.into(), span, code.clone());
961                 }
962             }
963         }
964
965         implied_bounds
966     })
967 }
968
969 pub(super) fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>) -> CheckWfFcxBuilder<'tcx> {
970     for_id(tcx, item.def_id, item.span)
971 }
972
973 fn for_id(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> CheckWfFcxBuilder<'_> {
974     CheckWfFcxBuilder {
975         inherited: Inherited::build(tcx, def_id),
976         id: hir::HirId::make_owner(def_id),
977         span,
978         param_env: tcx.param_env(def_id),
979     }
980 }
981
982 fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> {
983     match kind {
984         ItemKind::Struct(..) => Some(AdtKind::Struct),
985         ItemKind::Union(..) => Some(AdtKind::Union),
986         ItemKind::Enum(..) => Some(AdtKind::Enum),
987         _ => None,
988     }
989 }
990
991 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
992 fn check_type_defn<'tcx, F>(
993     tcx: TyCtxt<'tcx>,
994     item: &hir::Item<'tcx>,
995     all_sized: bool,
996     mut lookup_fields: F,
997 ) where
998     F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec<AdtVariant<'tcx>>,
999 {
1000     for_item(tcx, item).with_fcx(|fcx| {
1001         let variants = lookup_fields(fcx);
1002         let packed = tcx.adt_def(item.def_id).repr().packed();
1003
1004         for variant in &variants {
1005             // All field types must be well-formed.
1006             for field in &variant.fields {
1007                 fcx.register_wf_obligation(
1008                     field.ty.into(),
1009                     field.span,
1010                     ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))),
1011                 )
1012             }
1013
1014             // For DST, or when drop needs to copy things around, all
1015             // intermediate types must be sized.
1016             let needs_drop_copy = || {
1017                 packed && {
1018                     let ty = variant.fields.last().unwrap().ty;
1019                     let ty = tcx.erase_regions(ty);
1020                     if ty.needs_infer() {
1021                         tcx.sess
1022                             .delay_span_bug(item.span, &format!("inference variables in {:?}", ty));
1023                         // Just treat unresolved type expression as if it needs drop.
1024                         true
1025                     } else {
1026                         ty.needs_drop(tcx, tcx.param_env(item.def_id))
1027                     }
1028                 }
1029             };
1030             // All fields (except for possibly the last) should be sized.
1031             let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy();
1032             let unsized_len = if all_sized { 0 } else { 1 };
1033             for (idx, field) in
1034                 variant.fields[..variant.fields.len() - unsized_len].iter().enumerate()
1035             {
1036                 let last = idx == variant.fields.len() - 1;
1037                 fcx.register_bound(
1038                     field.ty,
1039                     tcx.require_lang_item(LangItem::Sized, None),
1040                     traits::ObligationCause::new(
1041                         field.span,
1042                         fcx.body_id,
1043                         traits::FieldSized {
1044                             adt_kind: match item_adt_kind(&item.kind) {
1045                                 Some(i) => i,
1046                                 None => bug!(),
1047                             },
1048                             span: field.span,
1049                             last,
1050                         },
1051                     ),
1052                 );
1053             }
1054
1055             // Explicit `enum` discriminant values must const-evaluate successfully.
1056             if let Some(discr_def_id) = variant.explicit_discr {
1057                 let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id());
1058
1059                 let cause = traits::ObligationCause::new(
1060                     tcx.def_span(discr_def_id),
1061                     fcx.body_id,
1062                     traits::MiscObligation,
1063                 );
1064                 fcx.register_predicate(traits::Obligation::new(
1065                     cause,
1066                     fcx.param_env,
1067                     ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
1068                         ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
1069                         discr_substs,
1070                     )))
1071                     .to_predicate(tcx),
1072                 ));
1073             }
1074         }
1075
1076         check_where_clauses(fcx, item.span, item.def_id, None);
1077
1078         // No implied bounds in a struct definition.
1079         FxHashSet::default()
1080     });
1081 }
1082
1083 #[instrument(skip(tcx, item))]
1084 fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
1085     debug!(?item.def_id);
1086
1087     let trait_def = tcx.trait_def(item.def_id);
1088     if trait_def.is_marker
1089         || matches!(trait_def.specialization_kind, TraitSpecializationKind::Marker)
1090     {
1091         for associated_def_id in &*tcx.associated_item_def_ids(item.def_id) {
1092             struct_span_err!(
1093                 tcx.sess,
1094                 tcx.def_span(*associated_def_id),
1095                 E0714,
1096                 "marker traits cannot have associated items",
1097             )
1098             .emit();
1099         }
1100     }
1101
1102     // FIXME: this shouldn't use an `FnCtxt` at all.
1103     for_item(tcx, item).with_fcx(|fcx| {
1104         check_where_clauses(fcx, item.span, item.def_id, None);
1105
1106         FxHashSet::default()
1107     });
1108
1109     // Only check traits, don't check trait aliases
1110     if let hir::ItemKind::Trait(_, _, _, _, items) = item.kind {
1111         check_gat_where_clauses(tcx, items);
1112     }
1113 }
1114
1115 /// Checks all associated type defaults of trait `trait_def_id`.
1116 ///
1117 /// Assuming the defaults are used, check that all predicates (bounds on the
1118 /// assoc type and where clauses on the trait) hold.
1119 fn check_associated_type_bounds(fcx: &FnCtxt<'_, '_>, item: &ty::AssocItem, span: Span) {
1120     let tcx = fcx.tcx;
1121
1122     let bounds = tcx.explicit_item_bounds(item.def_id);
1123
1124     debug!("check_associated_type_bounds: bounds={:?}", bounds);
1125     let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
1126         let normalized_bound = fcx.normalize_associated_types_in(span, bound);
1127         traits::wf::predicate_obligations(
1128             fcx,
1129             fcx.param_env,
1130             fcx.body_id,
1131             normalized_bound,
1132             bound_span,
1133         )
1134     });
1135
1136     for obligation in wf_obligations {
1137         debug!("next obligation cause: {:?}", obligation.cause);
1138         fcx.register_predicate(obligation);
1139     }
1140 }
1141
1142 fn check_item_fn(
1143     tcx: TyCtxt<'_>,
1144     def_id: LocalDefId,
1145     ident: Ident,
1146     span: Span,
1147     decl: &hir::FnDecl<'_>,
1148 ) {
1149     for_id(tcx, def_id, span).with_fcx(|fcx| {
1150         let sig = tcx.fn_sig(def_id);
1151         let mut implied_bounds = FxHashSet::default();
1152         check_fn_or_method(fcx, ident.span, sig, decl, def_id, &mut implied_bounds);
1153         implied_bounds
1154     })
1155 }
1156
1157 fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_foreign_ty: bool) {
1158     debug!("check_item_type: {:?}", item_id);
1159
1160     for_id(tcx, item_id, ty_span).with_fcx(|fcx| {
1161         let ty = tcx.type_of(item_id);
1162         let item_ty = fcx.normalize_associated_types_in_wf(ty_span, ty, WellFormedLoc::Ty(item_id));
1163
1164         let mut forbid_unsized = true;
1165         if allow_foreign_ty {
1166             let tail = fcx.tcx.struct_tail_erasing_lifetimes(item_ty, fcx.param_env);
1167             if let ty::Foreign(_) = tail.kind() {
1168                 forbid_unsized = false;
1169             }
1170         }
1171
1172         fcx.register_wf_obligation(
1173             item_ty.into(),
1174             ty_span,
1175             ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id))),
1176         );
1177         if forbid_unsized {
1178             fcx.register_bound(
1179                 item_ty,
1180                 tcx.require_lang_item(LangItem::Sized, None),
1181                 traits::ObligationCause::new(ty_span, fcx.body_id, traits::MiscObligation),
1182             );
1183         }
1184
1185         // Ensure that the end result is `Sync` in a non-thread local `static`.
1186         let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
1187             == Some(hir::Mutability::Not)
1188             && !tcx.is_foreign_item(item_id.to_def_id())
1189             && !tcx.is_thread_local_static(item_id.to_def_id());
1190
1191         if should_check_for_sync {
1192             fcx.register_bound(
1193                 item_ty,
1194                 tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
1195                 traits::ObligationCause::new(ty_span, fcx.body_id, traits::SharedStatic),
1196             );
1197         }
1198
1199         // No implied bounds in a const, etc.
1200         FxHashSet::default()
1201     });
1202 }
1203
1204 #[tracing::instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
1205 fn check_impl<'tcx>(
1206     tcx: TyCtxt<'tcx>,
1207     item: &'tcx hir::Item<'tcx>,
1208     ast_self_ty: &hir::Ty<'_>,
1209     ast_trait_ref: &Option<hir::TraitRef<'_>>,
1210 ) {
1211     for_item(tcx, item).with_fcx(|fcx| {
1212         match *ast_trait_ref {
1213             Some(ref ast_trait_ref) => {
1214                 // `#[rustc_reservation_impl]` impls are not real impls and
1215                 // therefore don't need to be WF (the trait's `Self: Trait` predicate
1216                 // won't hold).
1217                 let trait_ref = tcx.impl_trait_ref(item.def_id).unwrap();
1218                 let trait_ref =
1219                     fcx.normalize_associated_types_in(ast_trait_ref.path.span, trait_ref);
1220                 let obligations = traits::wf::trait_obligations(
1221                     fcx,
1222                     fcx.param_env,
1223                     fcx.body_id,
1224                     &trait_ref,
1225                     ast_trait_ref.path.span,
1226                     item,
1227                 );
1228                 debug!(?obligations);
1229                 for obligation in obligations {
1230                     fcx.register_predicate(obligation);
1231                 }
1232             }
1233             None => {
1234                 let self_ty = tcx.type_of(item.def_id);
1235                 let self_ty = fcx.normalize_associated_types_in(item.span, self_ty);
1236                 fcx.register_wf_obligation(
1237                     self_ty.into(),
1238                     ast_self_ty.span,
1239                     ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(
1240                         item.hir_id().expect_owner(),
1241                     ))),
1242                 );
1243             }
1244         }
1245
1246         check_where_clauses(fcx, item.span, item.def_id, None);
1247
1248         fcx.impl_implied_bounds(item.def_id.to_def_id(), item.span)
1249     });
1250 }
1251
1252 /// Checks where-clauses and inline bounds that are declared on `def_id`.
1253 #[instrument(skip(fcx), level = "debug")]
1254 fn check_where_clauses<'tcx, 'fcx>(
1255     fcx: &FnCtxt<'fcx, 'tcx>,
1256     span: Span,
1257     def_id: LocalDefId,
1258     return_ty: Option<(Ty<'tcx>, Span)>,
1259 ) {
1260     let tcx = fcx.tcx;
1261
1262     let predicates = tcx.predicates_of(def_id);
1263     let generics = tcx.generics_of(def_id);
1264
1265     let is_our_default = |def: &ty::GenericParamDef| match def.kind {
1266         GenericParamDefKind::Type { has_default, .. }
1267         | GenericParamDefKind::Const { has_default } => {
1268             has_default && def.index >= generics.parent_count as u32
1269         }
1270         GenericParamDefKind::Lifetime => unreachable!(),
1271     };
1272
1273     // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
1274     // For example, this forbids the declaration:
1275     //
1276     //     struct Foo<T = Vec<[u32]>> { .. }
1277     //
1278     // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
1279     for param in &generics.params {
1280         match param.kind {
1281             GenericParamDefKind::Type { .. } => {
1282                 if is_our_default(param) {
1283                     let ty = tcx.type_of(param.def_id);
1284                     // Ignore dependent defaults -- that is, where the default of one type
1285                     // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
1286                     // be sure if it will error or not as user might always specify the other.
1287                     if !ty.needs_subst() {
1288                         fcx.register_wf_obligation(
1289                             ty.into(),
1290                             tcx.def_span(param.def_id),
1291                             ObligationCauseCode::MiscObligation,
1292                         );
1293                     }
1294                 }
1295             }
1296             GenericParamDefKind::Const { .. } => {
1297                 if is_our_default(param) {
1298                     // FIXME(const_generics_defaults): This
1299                     // is incorrect when dealing with unused substs, for example
1300                     // for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
1301                     // we should eagerly error.
1302                     let default_ct = tcx.const_param_default(param.def_id);
1303                     if !default_ct.needs_subst() {
1304                         fcx.register_wf_obligation(
1305                             default_ct.into(),
1306                             tcx.def_span(param.def_id),
1307                             ObligationCauseCode::WellFormed(None),
1308                         );
1309                     }
1310                 }
1311             }
1312             // Doesn't have defaults.
1313             GenericParamDefKind::Lifetime => {}
1314         }
1315     }
1316
1317     // Check that trait predicates are WF when params are substituted by their defaults.
1318     // We don't want to overly constrain the predicates that may be written but we want to
1319     // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
1320     // Therefore we check if a predicate which contains a single type param
1321     // with a concrete default is WF with that default substituted.
1322     // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
1323     //
1324     // First we build the defaulted substitution.
1325     let substs = InternalSubsts::for_item(tcx, def_id.to_def_id(), |param, _| {
1326         match param.kind {
1327             GenericParamDefKind::Lifetime => {
1328                 // All regions are identity.
1329                 tcx.mk_param_from_def(param)
1330             }
1331
1332             GenericParamDefKind::Type { .. } => {
1333                 // If the param has a default, ...
1334                 if is_our_default(param) {
1335                     let default_ty = tcx.type_of(param.def_id);
1336                     // ... and it's not a dependent default, ...
1337                     if !default_ty.needs_subst() {
1338                         // ... then substitute it with the default.
1339                         return default_ty.into();
1340                     }
1341                 }
1342
1343                 tcx.mk_param_from_def(param)
1344             }
1345             GenericParamDefKind::Const { .. } => {
1346                 // If the param has a default, ...
1347                 if is_our_default(param) {
1348                     let default_ct = tcx.const_param_default(param.def_id);
1349                     // ... and it's not a dependent default, ...
1350                     if !default_ct.needs_subst() {
1351                         // ... then substitute it with the default.
1352                         return default_ct.into();
1353                     }
1354                 }
1355
1356                 tcx.mk_param_from_def(param)
1357             }
1358         }
1359     });
1360
1361     // Now we build the substituted predicates.
1362     let default_obligations = predicates
1363         .predicates
1364         .iter()
1365         .flat_map(|&(pred, sp)| {
1366             #[derive(Default)]
1367             struct CountParams {
1368                 params: FxHashSet<u32>,
1369             }
1370             impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
1371                 type BreakTy = ();
1372
1373                 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
1374                     if let ty::Param(param) = t.kind() {
1375                         self.params.insert(param.index);
1376                     }
1377                     t.super_visit_with(self)
1378                 }
1379
1380                 fn visit_region(&mut self, _: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
1381                     ControlFlow::BREAK
1382                 }
1383
1384                 fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
1385                     if let ty::ConstKind::Param(param) = c.kind() {
1386                         self.params.insert(param.index);
1387                     }
1388                     c.super_visit_with(self)
1389                 }
1390             }
1391             let mut param_count = CountParams::default();
1392             let has_region = pred.visit_with(&mut param_count).is_break();
1393             let substituted_pred = EarlyBinder(pred).subst(tcx, substs);
1394             // Don't check non-defaulted params, dependent defaults (including lifetimes)
1395             // or preds with multiple params.
1396             if substituted_pred.has_param_types_or_consts()
1397                 || param_count.params.len() > 1
1398                 || has_region
1399             {
1400                 None
1401             } else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
1402                 // Avoid duplication of predicates that contain no parameters, for example.
1403                 None
1404             } else {
1405                 Some((substituted_pred, sp))
1406             }
1407         })
1408         .map(|(pred, sp)| {
1409             // Convert each of those into an obligation. So if you have
1410             // something like `struct Foo<T: Copy = String>`, we would
1411             // take that predicate `T: Copy`, substitute to `String: Copy`
1412             // (actually that happens in the previous `flat_map` call),
1413             // and then try to prove it (in this case, we'll fail).
1414             //
1415             // Note the subtle difference from how we handle `predicates`
1416             // below: there, we are not trying to prove those predicates
1417             // to be *true* but merely *well-formed*.
1418             let pred = fcx.normalize_associated_types_in(sp, pred);
1419             let cause = traits::ObligationCause::new(
1420                 sp,
1421                 fcx.body_id,
1422                 traits::ItemObligation(def_id.to_def_id()),
1423             );
1424             traits::Obligation::new(cause, fcx.param_env, pred)
1425         });
1426
1427     let predicates = predicates.instantiate_identity(tcx);
1428
1429     if let Some((return_ty, _)) = return_ty {
1430         if return_ty.has_infer_types_or_consts() {
1431             fcx.select_obligations_where_possible(false, |_| {});
1432         }
1433     }
1434
1435     let predicates = fcx.normalize_associated_types_in(span, predicates);
1436
1437     debug!(?predicates.predicates);
1438     assert_eq!(predicates.predicates.len(), predicates.spans.len());
1439     let wf_obligations =
1440         iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| {
1441             traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, sp)
1442         });
1443
1444     for obligation in wf_obligations.chain(default_obligations) {
1445         debug!("next obligation cause: {:?}", obligation.cause);
1446         fcx.register_predicate(obligation);
1447     }
1448 }
1449
1450 #[tracing::instrument(level = "debug", skip(fcx, span, hir_decl))]
1451 fn check_fn_or_method<'fcx, 'tcx>(
1452     fcx: &FnCtxt<'fcx, 'tcx>,
1453     span: Span,
1454     sig: ty::PolyFnSig<'tcx>,
1455     hir_decl: &hir::FnDecl<'_>,
1456     def_id: LocalDefId,
1457     implied_bounds: &mut FxHashSet<Ty<'tcx>>,
1458 ) {
1459     let sig = fcx.tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
1460
1461     // Normalize the input and output types one at a time, using a different
1462     // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
1463     // on the entire `FnSig`, since this would use the same `WellFormedLoc`
1464     // for each type, preventing the HIR wf check from generating
1465     // a nice error message.
1466     let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
1467     inputs_and_output =
1468         fcx.tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
1469             fcx.normalize_associated_types_in_wf(
1470                 span,
1471                 ty,
1472                 WellFormedLoc::Param {
1473                     function: def_id,
1474                     // Note that the `param_idx` of the output type is
1475                     // one greater than the index of the last input type.
1476                     param_idx: i.try_into().unwrap(),
1477                 },
1478             )
1479         }));
1480     // Manually call `normalize_associated_types_in` on the other types
1481     // in `FnSig`. This ensures that if the types of these fields
1482     // ever change to include projections, we will start normalizing
1483     // them automatically.
1484     let sig = ty::FnSig {
1485         inputs_and_output,
1486         c_variadic: fcx.normalize_associated_types_in(span, c_variadic),
1487         unsafety: fcx.normalize_associated_types_in(span, unsafety),
1488         abi: fcx.normalize_associated_types_in(span, abi),
1489     };
1490
1491     for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
1492         fcx.register_wf_obligation(
1493             input_ty.into(),
1494             ty.span,
1495             ObligationCauseCode::WellFormed(Some(WellFormedLoc::Param {
1496                 function: def_id,
1497                 param_idx: i.try_into().unwrap(),
1498             })),
1499         );
1500     }
1501
1502     implied_bounds.extend(sig.inputs());
1503
1504     fcx.register_wf_obligation(
1505         sig.output().into(),
1506         hir_decl.output.span(),
1507         ObligationCauseCode::ReturnType,
1508     );
1509
1510     // FIXME(#27579) return types should not be implied bounds
1511     implied_bounds.insert(sig.output());
1512
1513     debug!(?implied_bounds);
1514
1515     check_where_clauses(fcx, span, def_id, Some((sig.output(), hir_decl.output.span())));
1516 }
1517
1518 const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
1519      `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
1520      of the previous types except `Self`)";
1521
1522 #[tracing::instrument(level = "debug", skip(fcx))]
1523 fn check_method_receiver<'fcx, 'tcx>(
1524     fcx: &FnCtxt<'fcx, 'tcx>,
1525     fn_sig: &hir::FnSig<'_>,
1526     method: &ty::AssocItem,
1527     self_ty: Ty<'tcx>,
1528 ) {
1529     // Check that the method has a valid receiver type, given the type `Self`.
1530     debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
1531
1532     if !method.fn_has_self_parameter {
1533         return;
1534     }
1535
1536     let span = fn_sig.decl.inputs[0].span;
1537
1538     let sig = fcx.tcx.fn_sig(method.def_id);
1539     let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, sig);
1540     let sig = fcx.normalize_associated_types_in(span, sig);
1541
1542     debug!("check_method_receiver: sig={:?}", sig);
1543
1544     let self_ty = fcx.normalize_associated_types_in(span, self_ty);
1545
1546     let receiver_ty = sig.inputs()[0];
1547     let receiver_ty = fcx.normalize_associated_types_in(span, receiver_ty);
1548
1549     if fcx.tcx.features().arbitrary_self_types {
1550         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
1551             // Report error; `arbitrary_self_types` was enabled.
1552             e0307(fcx, span, receiver_ty);
1553         }
1554     } else {
1555         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
1556             if receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
1557                 // Report error; would have worked with `arbitrary_self_types`.
1558                 feature_err(
1559                     &fcx.tcx.sess.parse_sess,
1560                     sym::arbitrary_self_types,
1561                     span,
1562                     &format!(
1563                         "`{receiver_ty}` cannot be used as the type of `self` without \
1564                          the `arbitrary_self_types` feature",
1565                     ),
1566                 )
1567                 .help(HELP_FOR_SELF_TYPE)
1568                 .emit();
1569             } else {
1570                 // Report error; would not have worked with `arbitrary_self_types`.
1571                 e0307(fcx, span, receiver_ty);
1572             }
1573         }
1574     }
1575 }
1576
1577 fn e0307<'tcx>(fcx: &FnCtxt<'_, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
1578     struct_span_err!(
1579         fcx.tcx.sess.diagnostic(),
1580         span,
1581         E0307,
1582         "invalid `self` parameter type: {receiver_ty}"
1583     )
1584     .note("type of `self` must be `Self` or a type that dereferences to it")
1585     .help(HELP_FOR_SELF_TYPE)
1586     .emit();
1587 }
1588
1589 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
1590 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1591 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1592 /// strict: `receiver_ty` must implement `Receiver` and directly implement
1593 /// `Deref<Target = self_ty>`.
1594 ///
1595 /// N.B., there are cases this function returns `true` but causes an error to be emitted,
1596 /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
1597 /// wrong lifetime. Be careful of this if you are calling this function speculatively.
1598 fn receiver_is_valid<'fcx, 'tcx>(
1599     fcx: &FnCtxt<'fcx, 'tcx>,
1600     span: Span,
1601     receiver_ty: Ty<'tcx>,
1602     self_ty: Ty<'tcx>,
1603     arbitrary_self_types_enabled: bool,
1604 ) -> bool {
1605     let cause = fcx.cause(span, traits::ObligationCauseCode::MethodReceiver);
1606
1607     let can_eq_self = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok();
1608
1609     // `self: Self` is always valid.
1610     if can_eq_self(receiver_ty) {
1611         if let Some(mut err) = fcx.demand_eqtype_with_origin(&cause, self_ty, receiver_ty) {
1612             err.emit();
1613         }
1614         return true;
1615     }
1616
1617     let mut autoderef = fcx.autoderef(span, receiver_ty);
1618
1619     // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1620     if arbitrary_self_types_enabled {
1621         autoderef = autoderef.include_raw_pointers();
1622     }
1623
1624     // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
1625     autoderef.next();
1626
1627     let receiver_trait_def_id = fcx.tcx.require_lang_item(LangItem::Receiver, None);
1628
1629     // Keep dereferencing `receiver_ty` until we get to `self_ty`.
1630     loop {
1631         if let Some((potential_self_ty, _)) = autoderef.next() {
1632             debug!(
1633                 "receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1634                 potential_self_ty, self_ty
1635             );
1636
1637             if can_eq_self(potential_self_ty) {
1638                 fcx.register_predicates(autoderef.into_obligations());
1639
1640                 if let Some(mut err) =
1641                     fcx.demand_eqtype_with_origin(&cause, self_ty, potential_self_ty)
1642                 {
1643                     err.emit();
1644                 }
1645
1646                 break;
1647             } else {
1648                 // Without `feature(arbitrary_self_types)`, we require that each step in the
1649                 // deref chain implement `receiver`
1650                 if !arbitrary_self_types_enabled
1651                     && !receiver_is_implemented(
1652                         fcx,
1653                         receiver_trait_def_id,
1654                         cause.clone(),
1655                         potential_self_ty,
1656                     )
1657                 {
1658                     return false;
1659                 }
1660             }
1661         } else {
1662             debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
1663             // If the receiver already has errors reported due to it, consider it valid to avoid
1664             // unnecessary errors (#58712).
1665             return receiver_ty.references_error();
1666         }
1667     }
1668
1669     // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
1670     if !arbitrary_self_types_enabled
1671         && !receiver_is_implemented(fcx, receiver_trait_def_id, cause.clone(), receiver_ty)
1672     {
1673         return false;
1674     }
1675
1676     true
1677 }
1678
1679 fn receiver_is_implemented<'tcx>(
1680     fcx: &FnCtxt<'_, 'tcx>,
1681     receiver_trait_def_id: DefId,
1682     cause: ObligationCause<'tcx>,
1683     receiver_ty: Ty<'tcx>,
1684 ) -> bool {
1685     let trait_ref = ty::Binder::dummy(ty::TraitRef {
1686         def_id: receiver_trait_def_id,
1687         substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
1688     });
1689
1690     let obligation = traits::Obligation::new(
1691         cause,
1692         fcx.param_env,
1693         trait_ref.without_const().to_predicate(fcx.tcx),
1694     );
1695
1696     if fcx.predicate_must_hold_modulo_regions(&obligation) {
1697         true
1698     } else {
1699         debug!(
1700             "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
1701             receiver_ty
1702         );
1703         false
1704     }
1705 }
1706
1707 fn check_variances_for_type_defn<'tcx>(
1708     tcx: TyCtxt<'tcx>,
1709     item: &hir::Item<'tcx>,
1710     hir_generics: &hir::Generics<'_>,
1711 ) {
1712     let ty = tcx.type_of(item.def_id);
1713     if tcx.has_error_field(ty) {
1714         return;
1715     }
1716
1717     let ty_predicates = tcx.predicates_of(item.def_id);
1718     assert_eq!(ty_predicates.parent, None);
1719     let variances = tcx.variances_of(item.def_id);
1720
1721     let mut constrained_parameters: FxHashSet<_> = variances
1722         .iter()
1723         .enumerate()
1724         .filter(|&(_, &variance)| variance != ty::Bivariant)
1725         .map(|(index, _)| Parameter(index as u32))
1726         .collect();
1727
1728     identify_constrained_generic_params(tcx, ty_predicates, None, &mut constrained_parameters);
1729
1730     // Lazily calculated because it is only needed in case of an error.
1731     let explicitly_bounded_params = LazyCell::new(|| {
1732         let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
1733         hir_generics
1734             .predicates
1735             .iter()
1736             .filter_map(|predicate| match predicate {
1737                 hir::WherePredicate::BoundPredicate(predicate) => {
1738                     match icx.to_ty(predicate.bounded_ty).kind() {
1739                         ty::Param(data) => Some(Parameter(data.index)),
1740                         _ => None,
1741                     }
1742                 }
1743                 _ => None,
1744             })
1745             .collect::<FxHashSet<_>>()
1746     });
1747
1748     for (index, _) in variances.iter().enumerate() {
1749         let parameter = Parameter(index as u32);
1750
1751         if constrained_parameters.contains(&parameter) {
1752             continue;
1753         }
1754
1755         let param = &hir_generics.params[index];
1756
1757         match param.name {
1758             hir::ParamName::Error => {}
1759             _ => {
1760                 let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
1761                 report_bivariance(tcx, param, has_explicit_bounds);
1762             }
1763         }
1764     }
1765 }
1766
1767 fn report_bivariance(
1768     tcx: TyCtxt<'_>,
1769     param: &rustc_hir::GenericParam<'_>,
1770     has_explicit_bounds: bool,
1771 ) -> ErrorGuaranteed {
1772     let span = param.span;
1773     let param_name = param.name.ident().name;
1774     let mut err = error_392(tcx, span, param_name);
1775
1776     let suggested_marker_id = tcx.lang_items().phantom_data();
1777     // Help is available only in presence of lang items.
1778     let msg = if let Some(def_id) = suggested_marker_id {
1779         format!(
1780             "consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
1781             param_name,
1782             tcx.def_path_str(def_id),
1783         )
1784     } else {
1785         format!("consider removing `{param_name}` or referring to it in a field")
1786     };
1787     err.help(&msg);
1788
1789     if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
1790         err.help(&format!(
1791             "if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
1792             param_name
1793         ));
1794     }
1795     err.emit()
1796 }
1797
1798 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
1799 /// aren't true.
1800 fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirId) {
1801     let empty_env = ty::ParamEnv::empty();
1802
1803     let def_id = fcx.tcx.hir().local_def_id(id);
1804     let predicates_with_span =
1805         fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, span)| (*p, *span));
1806     // Check elaborated bounds.
1807     let implied_obligations = traits::elaborate_predicates_with_span(fcx.tcx, predicates_with_span);
1808
1809     for obligation in implied_obligations {
1810         // We lower empty bounds like `Vec<dyn Copy>:` as
1811         // `WellFormed(Vec<dyn Copy>)`, which will later get checked by
1812         // regular WF checking
1813         if let ty::PredicateKind::WellFormed(..) = obligation.predicate.kind().skip_binder() {
1814             continue;
1815         }
1816         let pred = obligation.predicate;
1817         // Match the existing behavior.
1818         if pred.is_global() && !pred.has_late_bound_regions() {
1819             let pred = fcx.normalize_associated_types_in(span, pred);
1820             let hir_node = fcx.tcx.hir().find(id);
1821
1822             // only use the span of the predicate clause (#90869)
1823
1824             if let Some(hir::Generics { predicates, .. }) =
1825                 hir_node.and_then(|node| node.generics())
1826             {
1827                 let obligation_span = obligation.cause.span(fcx.tcx);
1828
1829                 span = predicates
1830                     .iter()
1831                     // There seems to be no better way to find out which predicate we are in
1832                     .find(|pred| pred.span().contains(obligation_span))
1833                     .map(|pred| pred.span())
1834                     .unwrap_or(obligation_span);
1835             }
1836
1837             let obligation = traits::Obligation::new(
1838                 traits::ObligationCause::new(span, id, traits::TrivialBound),
1839                 empty_env,
1840                 pred,
1841             );
1842             fcx.register_predicate(obligation);
1843         }
1844     }
1845
1846     fcx.select_all_obligations_or_error();
1847 }
1848
1849 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) {
1850     let items = tcx.hir_module_items(module);
1851     items.par_items(|item| tcx.ensure().check_well_formed(item.def_id));
1852     items.par_impl_items(|item| tcx.ensure().check_well_formed(item.def_id));
1853     items.par_trait_items(|item| tcx.ensure().check_well_formed(item.def_id));
1854     items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.def_id));
1855 }
1856
1857 ///////////////////////////////////////////////////////////////////////////
1858 // ADT
1859
1860 // FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
1861 struct AdtVariant<'tcx> {
1862     /// Types of fields in the variant, that must be well-formed.
1863     fields: Vec<AdtField<'tcx>>,
1864
1865     /// Explicit discriminant of this variant (e.g. `A = 123`),
1866     /// that must evaluate to a constant value.
1867     explicit_discr: Option<LocalDefId>,
1868 }
1869
1870 struct AdtField<'tcx> {
1871     ty: Ty<'tcx>,
1872     def_id: LocalDefId,
1873     span: Span,
1874 }
1875
1876 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1877     // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
1878     fn non_enum_variant(&self, struct_def: &hir::VariantData<'_>) -> AdtVariant<'tcx> {
1879         let fields = struct_def
1880             .fields()
1881             .iter()
1882             .map(|field| {
1883                 let def_id = self.tcx.hir().local_def_id(field.hir_id);
1884                 let field_ty = self.tcx.type_of(def_id);
1885                 let field_ty = self.normalize_associated_types_in(field.ty.span, field_ty);
1886                 let field_ty = self.resolve_vars_if_possible(field_ty);
1887                 debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty);
1888                 AdtField { ty: field_ty, span: field.ty.span, def_id }
1889             })
1890             .collect();
1891         AdtVariant { fields, explicit_discr: None }
1892     }
1893
1894     fn enum_variants(&self, enum_def: &hir::EnumDef<'_>) -> Vec<AdtVariant<'tcx>> {
1895         enum_def
1896             .variants
1897             .iter()
1898             .map(|variant| AdtVariant {
1899                 fields: self.non_enum_variant(&variant.data).fields,
1900                 explicit_discr: variant
1901                     .disr_expr
1902                     .map(|explicit_discr| self.tcx.hir().local_def_id(explicit_discr.hir_id)),
1903             })
1904             .collect()
1905     }
1906
1907     pub(super) fn impl_implied_bounds(
1908         &self,
1909         impl_def_id: DefId,
1910         span: Span,
1911     ) -> FxHashSet<Ty<'tcx>> {
1912         match self.tcx.impl_trait_ref(impl_def_id) {
1913             Some(trait_ref) => {
1914                 // Trait impl: take implied bounds from all types that
1915                 // appear in the trait reference.
1916                 let trait_ref = self.normalize_associated_types_in(span, trait_ref);
1917                 trait_ref.substs.types().collect()
1918             }
1919
1920             None => {
1921                 // Inherent impl: take implied bounds from the `self` type.
1922                 let self_ty = self.tcx.type_of(impl_def_id);
1923                 let self_ty = self.normalize_associated_types_in(span, self_ty);
1924                 FxHashSet::from_iter([self_ty])
1925             }
1926         }
1927     }
1928 }
1929
1930 fn error_392(
1931     tcx: TyCtxt<'_>,
1932     span: Span,
1933     param_name: Symbol,
1934 ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
1935     let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{param_name}` is never used");
1936     err.span_label(span, "unused parameter");
1937     err
1938 }
1939
1940 pub fn provide(providers: &mut Providers) {
1941     *providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
1942 }