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