]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/collect.rs
Add some high-level docs to `FnCtxt` and `ItemCtxt`
[rust.git] / compiler / rustc_typeck / src / collect.rs
1 //! "Collection" is the process of determining the type and other external
2 //! details of each item in Rust. Collection is specifically concerned
3 //! with *inter-procedural* things -- for example, for a function
4 //! definition, collection will figure out the type and signature of the
5 //! function, but it will not visit the *body* of the function in any way,
6 //! nor examine type annotations on local variables (that's the job of
7 //! type *checking*).
8 //!
9 //! Collecting is ultimately defined by a bundle of queries that
10 //! inquire after various facts about the items in the crate (e.g.,
11 //! `type_of`, `generics_of`, `predicates_of`, etc). See the `provide` function
12 //! for the full set.
13 //!
14 //! At present, however, we do run collection across all items in the
15 //! crate as a kind of pass. This should eventually be factored away.
16
17 use crate::astconv::AstConv;
18 use crate::bounds::Bounds;
19 use crate::check::intrinsic::intrinsic_operation_unsafety;
20 use crate::constrained_generic_params as cgp;
21 use crate::errors;
22 use crate::middle::resolve_lifetime as rl;
23 use rustc_ast as ast;
24 use rustc_ast::{MetaItemKind, NestedMetaItem};
25 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
26 use rustc_data_structures::captures::Captures;
27 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
28 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
29 use rustc_hir as hir;
30 use rustc_hir::def::{CtorKind, DefKind};
31 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
32 use rustc_hir::intravisit::{self, Visitor};
33 use rustc_hir::weak_lang_items;
34 use rustc_hir::{GenericParamKind, HirId, Node};
35 use rustc_middle::hir::nested_filter;
36 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
37 use rustc_middle::mir::mono::Linkage;
38 use rustc_middle::ty::query::Providers;
39 use rustc_middle::ty::subst::InternalSubsts;
40 use rustc_middle::ty::util::Discr;
41 use rustc_middle::ty::util::IntTypeExt;
42 use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, Ty, TyCtxt};
43 use rustc_middle::ty::{ReprOptions, ToPredicate};
44 use rustc_session::lint;
45 use rustc_session::parse::feature_err;
46 use rustc_span::symbol::{kw, sym, Ident, Symbol};
47 use rustc_span::{Span, DUMMY_SP};
48 use rustc_target::spec::{abi, SanitizerSet};
49 use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
50 use std::iter;
51
52 mod item_bounds;
53 mod type_of;
54
55 #[derive(Debug)]
56 struct OnlySelfBounds(bool);
57
58 ///////////////////////////////////////////////////////////////////////////
59 // Main entry point
60
61 fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
62     tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx });
63 }
64
65 pub fn provide(providers: &mut Providers) {
66     *providers = Providers {
67         opt_const_param_of: type_of::opt_const_param_of,
68         type_of: type_of::type_of,
69         item_bounds: item_bounds::item_bounds,
70         explicit_item_bounds: item_bounds::explicit_item_bounds,
71         generics_of,
72         predicates_of,
73         predicates_defined_on,
74         explicit_predicates_of,
75         super_predicates_of,
76         super_predicates_that_define_assoc_type,
77         trait_explicit_predicates_and_bounds,
78         type_param_predicates,
79         trait_def,
80         adt_def,
81         fn_sig,
82         impl_trait_ref,
83         impl_polarity,
84         is_foreign_item,
85         generator_kind,
86         codegen_fn_attrs,
87         asm_target_features,
88         collect_mod_item_types,
89         should_inherit_track_caller,
90         ..*providers
91     };
92 }
93
94 ///////////////////////////////////////////////////////////////////////////
95
96 /// Context specific to some particular item. This is what implements
97 /// `AstConv`.
98 ///
99 /// `ItemCtxt` is primarily used to type-check item signatures, in contrast to [`FnCtxt`],
100 /// which is used to type-check function bodies.
101 ///
102 /// It has information about the predicates that are defined
103 /// on the trait. Unfortunately, this predicate information is
104 /// available in various different forms at various points in the
105 /// process. So we can't just store a pointer to e.g., the AST or the
106 /// parsed ty form, we have to be more flexible. To this end, the
107 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
108 /// `get_type_parameter_bounds` requests, drawing the information from
109 /// the AST (`hir::Generics`), recursively.
110 pub struct ItemCtxt<'tcx> {
111     tcx: TyCtxt<'tcx>,
112     item_def_id: DefId,
113 }
114
115 ///////////////////////////////////////////////////////////////////////////
116
117 #[derive(Default)]
118 pub(crate) struct HirPlaceholderCollector(pub(crate) Vec<Span>);
119
120 impl<'v> Visitor<'v> for HirPlaceholderCollector {
121     fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
122         if let hir::TyKind::Infer = t.kind {
123             self.0.push(t.span);
124         }
125         intravisit::walk_ty(self, t)
126     }
127     fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) {
128         match generic_arg {
129             hir::GenericArg::Infer(inf) => {
130                 self.0.push(inf.span);
131                 intravisit::walk_inf(self, inf);
132             }
133             hir::GenericArg::Type(t) => self.visit_ty(t),
134             _ => {}
135         }
136     }
137     fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
138         if let &hir::ArrayLen::Infer(_, span) = length {
139             self.0.push(span);
140         }
141         intravisit::walk_array_len(self, length)
142     }
143 }
144
145 struct CollectItemTypesVisitor<'tcx> {
146     tcx: TyCtxt<'tcx>,
147 }
148
149 /// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
150 /// and suggest adding type parameters in the appropriate place, taking into consideration any and
151 /// all already existing generic type parameters to avoid suggesting a name that is already in use.
152 pub(crate) fn placeholder_type_error<'tcx>(
153     tcx: TyCtxt<'tcx>,
154     generics: Option<&hir::Generics<'_>>,
155     placeholder_types: Vec<Span>,
156     suggest: bool,
157     hir_ty: Option<&hir::Ty<'_>>,
158     kind: &'static str,
159 ) {
160     if placeholder_types.is_empty() {
161         return;
162     }
163
164     placeholder_type_error_diag(tcx, generics, placeholder_types, vec![], suggest, hir_ty, kind)
165         .emit();
166 }
167
168 pub(crate) fn placeholder_type_error_diag<'tcx>(
169     tcx: TyCtxt<'tcx>,
170     generics: Option<&hir::Generics<'_>>,
171     placeholder_types: Vec<Span>,
172     additional_spans: Vec<Span>,
173     suggest: bool,
174     hir_ty: Option<&hir::Ty<'_>>,
175     kind: &'static str,
176 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
177     if placeholder_types.is_empty() {
178         return bad_placeholder(tcx, additional_spans, kind);
179     }
180
181     let params = generics.map(|g| g.params).unwrap_or_default();
182     let type_name = params.next_type_param_name(None);
183     let mut sugg: Vec<_> =
184         placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
185
186     if let Some(generics) = generics {
187         if let Some(arg) = params.iter().find(|arg| {
188             matches!(arg.name, hir::ParamName::Plain(Ident { name: kw::Underscore, .. }))
189         }) {
190             // Account for `_` already present in cases like `struct S<_>(_);` and suggest
191             // `struct S<T>(T);` instead of `struct S<_, T>(T);`.
192             sugg.push((arg.span, (*type_name).to_string()));
193         } else if let Some(span) = generics.span_for_param_suggestion() {
194             // Account for bounds, we want `fn foo<T: E, K>(_: K)` not `fn foo<T, K: E>(_: K)`.
195             sugg.push((span, format!(", {}", type_name)));
196         } else {
197             sugg.push((generics.span, format!("<{}>", type_name)));
198         }
199     }
200
201     let mut err =
202         bad_placeholder(tcx, placeholder_types.into_iter().chain(additional_spans).collect(), kind);
203
204     // Suggest, but only if it is not a function in const or static
205     if suggest {
206         let mut is_fn = false;
207         let mut is_const_or_static = false;
208
209         if let Some(hir_ty) = hir_ty && let hir::TyKind::BareFn(_) = hir_ty.kind {
210             is_fn = true;
211
212             // Check if parent is const or static
213             let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id);
214             let parent_node = tcx.hir().get(parent_id);
215
216             is_const_or_static = matches!(
217                 parent_node,
218                 Node::Item(&hir::Item {
219                     kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
220                     ..
221                 }) | Node::TraitItem(&hir::TraitItem {
222                     kind: hir::TraitItemKind::Const(..),
223                     ..
224                 }) | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
225             );
226         }
227
228         // if function is wrapped around a const or static,
229         // then don't show the suggestion
230         if !(is_fn && is_const_or_static) {
231             err.multipart_suggestion(
232                 "use type parameters instead",
233                 sugg,
234                 Applicability::HasPlaceholders,
235             );
236         }
237     }
238
239     err
240 }
241
242 fn reject_placeholder_type_signatures_in_item<'tcx>(
243     tcx: TyCtxt<'tcx>,
244     item: &'tcx hir::Item<'tcx>,
245 ) {
246     let (generics, suggest) = match &item.kind {
247         hir::ItemKind::Union(_, generics)
248         | hir::ItemKind::Enum(_, generics)
249         | hir::ItemKind::TraitAlias(generics, _)
250         | hir::ItemKind::Trait(_, _, generics, ..)
251         | hir::ItemKind::Impl(hir::Impl { generics, .. })
252         | hir::ItemKind::Struct(_, generics) => (generics, true),
253         hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
254         | hir::ItemKind::TyAlias(_, generics) => (generics, false),
255         // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
256         _ => return,
257     };
258
259     let mut visitor = HirPlaceholderCollector::default();
260     visitor.visit_item(item);
261
262     placeholder_type_error(tcx, Some(generics), visitor.0, suggest, None, item.kind.descr());
263 }
264
265 impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
266     type NestedFilter = nested_filter::OnlyBodies;
267
268     fn nested_visit_map(&mut self) -> Self::Map {
269         self.tcx.hir()
270     }
271
272     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
273         convert_item(self.tcx, item.item_id());
274         reject_placeholder_type_signatures_in_item(self.tcx, item);
275         intravisit::walk_item(self, item);
276     }
277
278     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
279         for param in generics.params {
280             match param.kind {
281                 hir::GenericParamKind::Lifetime { .. } => {}
282                 hir::GenericParamKind::Type { default: Some(_), .. } => {
283                     let def_id = self.tcx.hir().local_def_id(param.hir_id);
284                     self.tcx.ensure().type_of(def_id);
285                 }
286                 hir::GenericParamKind::Type { .. } => {}
287                 hir::GenericParamKind::Const { default, .. } => {
288                     let def_id = self.tcx.hir().local_def_id(param.hir_id);
289                     self.tcx.ensure().type_of(def_id);
290                     if let Some(default) = default {
291                         let default_def_id = self.tcx.hir().local_def_id(default.hir_id);
292                         // need to store default and type of default
293                         self.tcx.ensure().type_of(default_def_id);
294                         self.tcx.ensure().const_param_default(def_id);
295                     }
296                 }
297             }
298         }
299         intravisit::walk_generics(self, generics);
300     }
301
302     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
303         if let hir::ExprKind::Closure { .. } = expr.kind {
304             let def_id = self.tcx.hir().local_def_id(expr.hir_id);
305             self.tcx.ensure().generics_of(def_id);
306             // We do not call `type_of` for closures here as that
307             // depends on typecheck and would therefore hide
308             // any further errors in case one typeck fails.
309         }
310         intravisit::walk_expr(self, expr);
311     }
312
313     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
314         convert_trait_item(self.tcx, trait_item.trait_item_id());
315         intravisit::walk_trait_item(self, trait_item);
316     }
317
318     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
319         convert_impl_item(self.tcx, impl_item.impl_item_id());
320         intravisit::walk_impl_item(self, impl_item);
321     }
322 }
323
324 ///////////////////////////////////////////////////////////////////////////
325 // Utility types and common code for the above passes.
326
327 fn bad_placeholder<'tcx>(
328     tcx: TyCtxt<'tcx>,
329     mut spans: Vec<Span>,
330     kind: &'static str,
331 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
332     let kind = if kind.ends_with('s') { format!("{}es", kind) } else { format!("{}s", kind) };
333
334     spans.sort();
335     let mut err = struct_span_err!(
336         tcx.sess,
337         spans.clone(),
338         E0121,
339         "the placeholder `_` is not allowed within types on item signatures for {}",
340         kind
341     );
342     for span in spans {
343         err.span_label(span, "not allowed in type signatures");
344     }
345     err
346 }
347
348 impl<'tcx> ItemCtxt<'tcx> {
349     pub fn new(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> ItemCtxt<'tcx> {
350         ItemCtxt { tcx, item_def_id }
351     }
352
353     pub fn to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
354         <dyn AstConv<'_>>::ast_ty_to_ty(self, ast_ty)
355     }
356
357     pub fn hir_id(&self) -> hir::HirId {
358         self.tcx.hir().local_def_id_to_hir_id(self.item_def_id.expect_local())
359     }
360
361     pub fn node(&self) -> hir::Node<'tcx> {
362         self.tcx.hir().get(self.hir_id())
363     }
364 }
365
366 impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
367     fn tcx(&self) -> TyCtxt<'tcx> {
368         self.tcx
369     }
370
371     fn item_def_id(&self) -> Option<DefId> {
372         Some(self.item_def_id)
373     }
374
375     fn get_type_parameter_bounds(
376         &self,
377         span: Span,
378         def_id: DefId,
379         assoc_name: Ident,
380     ) -> ty::GenericPredicates<'tcx> {
381         self.tcx.at(span).type_param_predicates((
382             self.item_def_id,
383             def_id.expect_local(),
384             assoc_name,
385         ))
386     }
387
388     fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
389         None
390     }
391
392     fn allow_ty_infer(&self) -> bool {
393         false
394     }
395
396     fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
397         self.tcx().ty_error_with_message(span, "bad placeholder type")
398     }
399
400     fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
401         let ty = self.tcx.fold_regions(ty, |r, _| match *r {
402             ty::ReErased => self.tcx.lifetimes.re_static,
403             _ => r,
404         });
405         self.tcx().const_error_with_message(ty, span, "bad placeholder constant")
406     }
407
408     fn projected_ty_from_poly_trait_ref(
409         &self,
410         span: Span,
411         item_def_id: DefId,
412         item_segment: &hir::PathSegment<'_>,
413         poly_trait_ref: ty::PolyTraitRef<'tcx>,
414     ) -> Ty<'tcx> {
415         if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
416             let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
417                 self,
418                 self.tcx,
419                 span,
420                 item_def_id,
421                 item_segment,
422                 trait_ref.substs,
423             );
424             self.tcx().mk_projection(item_def_id, item_substs)
425         } else {
426             // There are no late-bound regions; we can just ignore the binder.
427             let mut err = struct_span_err!(
428                 self.tcx().sess,
429                 span,
430                 E0212,
431                 "cannot use the associated type of a trait \
432                  with uninferred generic parameters"
433             );
434
435             match self.node() {
436                 hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
437                     let item =
438                         self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(self.hir_id()));
439                     match &item.kind {
440                         hir::ItemKind::Enum(_, generics)
441                         | hir::ItemKind::Struct(_, generics)
442                         | hir::ItemKind::Union(_, generics) => {
443                             let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
444                             let (lt_sp, sugg) = match generics.params {
445                                 [] => (generics.span, format!("<{}>", lt_name)),
446                                 [bound, ..] => {
447                                     (bound.span.shrink_to_lo(), format!("{}, ", lt_name))
448                                 }
449                             };
450                             let suggestions = vec![
451                                 (lt_sp, sugg),
452                                 (
453                                     span.with_hi(item_segment.ident.span.lo()),
454                                     format!(
455                                         "{}::",
456                                         // Replace the existing lifetimes with a new named lifetime.
457                                         self.tcx.replace_late_bound_regions_uncached(
458                                             poly_trait_ref,
459                                             |_| {
460                                                 self.tcx.mk_region(ty::ReEarlyBound(
461                                                     ty::EarlyBoundRegion {
462                                                         def_id: item_def_id,
463                                                         index: 0,
464                                                         name: Symbol::intern(&lt_name),
465                                                     },
466                                                 ))
467                                             }
468                                         ),
469                                     ),
470                                 ),
471                             ];
472                             err.multipart_suggestion(
473                                 "use a fully qualified path with explicit lifetimes",
474                                 suggestions,
475                                 Applicability::MaybeIncorrect,
476                             );
477                         }
478                         _ => {}
479                     }
480                 }
481                 hir::Node::Item(hir::Item {
482                     kind:
483                         hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..),
484                     ..
485                 }) => {}
486                 hir::Node::Item(_)
487                 | hir::Node::ForeignItem(_)
488                 | hir::Node::TraitItem(_)
489                 | hir::Node::ImplItem(_) => {
490                     err.span_suggestion_verbose(
491                         span.with_hi(item_segment.ident.span.lo()),
492                         "use a fully qualified path with inferred lifetimes",
493                         format!(
494                             "{}::",
495                             // Erase named lt, we want `<A as B<'_>::C`, not `<A as B<'a>::C`.
496                             self.tcx.anonymize_late_bound_regions(poly_trait_ref).skip_binder(),
497                         ),
498                         Applicability::MaybeIncorrect,
499                     );
500                 }
501                 _ => {}
502             }
503             err.emit();
504             self.tcx().ty_error()
505         }
506     }
507
508     fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
509         // Types in item signatures are not normalized to avoid undue dependencies.
510         ty
511     }
512
513     fn set_tainted_by_errors(&self) {
514         // There's no obvious place to track this, so just let it go.
515     }
516
517     fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
518         // There's no place to record types from signatures?
519     }
520 }
521
522 /// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
523 fn get_new_lifetime_name<'tcx>(
524     tcx: TyCtxt<'tcx>,
525     poly_trait_ref: ty::PolyTraitRef<'tcx>,
526     generics: &hir::Generics<'tcx>,
527 ) -> String {
528     let existing_lifetimes = tcx
529         .collect_referenced_late_bound_regions(&poly_trait_ref)
530         .into_iter()
531         .filter_map(|lt| {
532             if let ty::BoundRegionKind::BrNamed(_, name) = lt {
533                 Some(name.as_str().to_string())
534             } else {
535                 None
536             }
537         })
538         .chain(generics.params.iter().filter_map(|param| {
539             if let hir::GenericParamKind::Lifetime { .. } = &param.kind {
540                 Some(param.name.ident().as_str().to_string())
541             } else {
542                 None
543             }
544         }))
545         .collect::<FxHashSet<String>>();
546
547     let a_to_z_repeat_n = |n| {
548         (b'a'..=b'z').map(move |c| {
549             let mut s = '\''.to_string();
550             s.extend(std::iter::repeat(char::from(c)).take(n));
551             s
552         })
553     };
554
555     // If all single char lifetime names are present, we wrap around and double the chars.
556     (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
557 }
558
559 /// Returns the predicates defined on `item_def_id` of the form
560 /// `X: Foo` where `X` is the type parameter `def_id`.
561 fn type_param_predicates(
562     tcx: TyCtxt<'_>,
563     (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
564 ) -> ty::GenericPredicates<'_> {
565     use rustc_hir::*;
566
567     // In the AST, bounds can derive from two places. Either
568     // written inline like `<T: Foo>` or in a where-clause like
569     // `where T: Foo`.
570
571     let param_id = tcx.hir().local_def_id_to_hir_id(def_id);
572     let param_owner = tcx.hir().ty_param_owner(def_id);
573     let generics = tcx.generics_of(param_owner);
574     let index = generics.param_def_id_to_index[&def_id.to_def_id()];
575     let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id));
576
577     // Don't look for bounds where the type parameter isn't in scope.
578     let parent = if item_def_id == param_owner.to_def_id() {
579         None
580     } else {
581         tcx.generics_of(item_def_id).parent
582     };
583
584     let mut result = parent
585         .map(|parent| {
586             let icx = ItemCtxt::new(tcx, parent);
587             icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name)
588         })
589         .unwrap_or_default();
590     let mut extend = None;
591
592     let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local());
593     let ast_generics = match tcx.hir().get(item_hir_id) {
594         Node::TraitItem(item) => &item.generics,
595
596         Node::ImplItem(item) => &item.generics,
597
598         Node::Item(item) => {
599             match item.kind {
600                 ItemKind::Fn(.., ref generics, _)
601                 | ItemKind::Impl(hir::Impl { ref generics, .. })
602                 | ItemKind::TyAlias(_, ref generics)
603                 | ItemKind::OpaqueTy(OpaqueTy {
604                     ref generics,
605                     origin: hir::OpaqueTyOrigin::TyAlias,
606                     ..
607                 })
608                 | ItemKind::Enum(_, ref generics)
609                 | ItemKind::Struct(_, ref generics)
610                 | ItemKind::Union(_, ref generics) => generics,
611                 ItemKind::Trait(_, _, ref generics, ..) => {
612                     // Implied `Self: Trait` and supertrait bounds.
613                     if param_id == item_hir_id {
614                         let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
615                         extend =
616                             Some((identity_trait_ref.without_const().to_predicate(tcx), item.span));
617                     }
618                     generics
619                 }
620                 _ => return result,
621             }
622         }
623
624         Node::ForeignItem(item) => match item.kind {
625             ForeignItemKind::Fn(_, _, ref generics) => generics,
626             _ => return result,
627         },
628
629         _ => return result,
630     };
631
632     let icx = ItemCtxt::new(tcx, item_def_id);
633     let extra_predicates = extend.into_iter().chain(
634         icx.type_parameter_bounds_in_generics(
635             ast_generics,
636             param_id,
637             ty,
638             OnlySelfBounds(true),
639             Some(assoc_name),
640         )
641         .into_iter()
642         .filter(|(predicate, _)| match predicate.kind().skip_binder() {
643             ty::PredicateKind::Trait(data) => data.self_ty().is_param(index),
644             _ => false,
645         }),
646     );
647     result.predicates =
648         tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates));
649     result
650 }
651
652 impl<'tcx> ItemCtxt<'tcx> {
653     /// Finds bounds from `hir::Generics`. This requires scanning through the
654     /// AST. We do this to avoid having to convert *all* the bounds, which
655     /// would create artificial cycles. Instead, we can only convert the
656     /// bounds for a type parameter `X` if `X::Foo` is used.
657     #[instrument(level = "trace", skip(self, ast_generics))]
658     fn type_parameter_bounds_in_generics(
659         &self,
660         ast_generics: &'tcx hir::Generics<'tcx>,
661         param_id: hir::HirId,
662         ty: Ty<'tcx>,
663         only_self_bounds: OnlySelfBounds,
664         assoc_name: Option<Ident>,
665     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
666         let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
667         debug!(?param_def_id);
668         ast_generics
669             .predicates
670             .iter()
671             .filter_map(|wp| match *wp {
672                 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
673                 _ => None,
674             })
675             .flat_map(|bp| {
676                 let bt = if bp.is_param_bound(param_def_id) {
677                     Some(ty)
678                 } else if !only_self_bounds.0 {
679                     Some(self.to_ty(bp.bounded_ty))
680                 } else {
681                     None
682                 };
683                 let bvars = self.tcx.late_bound_vars(bp.bounded_ty.hir_id);
684
685                 bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter(
686                     |(_, b, _)| match assoc_name {
687                         Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
688                         None => true,
689                     },
690                 )
691             })
692             .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars))
693             .collect()
694     }
695
696     fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
697         debug!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b, assoc_name);
698
699         match b {
700             hir::GenericBound::Trait(poly_trait_ref, _) => {
701                 let trait_ref = &poly_trait_ref.trait_ref;
702                 if let Some(trait_did) = trait_ref.trait_def_id() {
703                     self.tcx.trait_may_define_assoc_type(trait_did, assoc_name)
704                 } else {
705                     false
706                 }
707             }
708             _ => false,
709         }
710     }
711 }
712
713 fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
714     let it = tcx.hir().item(item_id);
715     debug!("convert: item {} with id {}", it.ident, it.hir_id());
716     let def_id = item_id.def_id;
717
718     match it.kind {
719         // These don't define types.
720         hir::ItemKind::ExternCrate(_)
721         | hir::ItemKind::Use(..)
722         | hir::ItemKind::Macro(..)
723         | hir::ItemKind::Mod(_)
724         | hir::ItemKind::GlobalAsm(_) => {}
725         hir::ItemKind::ForeignMod { items, .. } => {
726             for item in items {
727                 let item = tcx.hir().foreign_item(item.id);
728                 tcx.ensure().generics_of(item.def_id);
729                 tcx.ensure().type_of(item.def_id);
730                 tcx.ensure().predicates_of(item.def_id);
731                 match item.kind {
732                     hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
733                     hir::ForeignItemKind::Static(..) => {
734                         let mut visitor = HirPlaceholderCollector::default();
735                         visitor.visit_foreign_item(item);
736                         placeholder_type_error(
737                             tcx,
738                             None,
739                             visitor.0,
740                             false,
741                             None,
742                             "static variable",
743                         );
744                     }
745                     _ => (),
746                 }
747             }
748         }
749         hir::ItemKind::Enum(ref enum_definition, _) => {
750             tcx.ensure().generics_of(def_id);
751             tcx.ensure().type_of(def_id);
752             tcx.ensure().predicates_of(def_id);
753             convert_enum_variant_types(tcx, def_id.to_def_id(), enum_definition.variants);
754         }
755         hir::ItemKind::Impl { .. } => {
756             tcx.ensure().generics_of(def_id);
757             tcx.ensure().type_of(def_id);
758             tcx.ensure().impl_trait_ref(def_id);
759             tcx.ensure().predicates_of(def_id);
760         }
761         hir::ItemKind::Trait(..) => {
762             tcx.ensure().generics_of(def_id);
763             tcx.ensure().trait_def(def_id);
764             tcx.at(it.span).super_predicates_of(def_id);
765             tcx.ensure().predicates_of(def_id);
766         }
767         hir::ItemKind::TraitAlias(..) => {
768             tcx.ensure().generics_of(def_id);
769             tcx.at(it.span).super_predicates_of(def_id);
770             tcx.ensure().predicates_of(def_id);
771         }
772         hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
773             tcx.ensure().generics_of(def_id);
774             tcx.ensure().type_of(def_id);
775             tcx.ensure().predicates_of(def_id);
776
777             for f in struct_def.fields() {
778                 let def_id = tcx.hir().local_def_id(f.hir_id);
779                 tcx.ensure().generics_of(def_id);
780                 tcx.ensure().type_of(def_id);
781                 tcx.ensure().predicates_of(def_id);
782             }
783
784             if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
785                 convert_variant_ctor(tcx, ctor_hir_id);
786             }
787         }
788
789         // Desugared from `impl Trait`, so visited by the function's return type.
790         hir::ItemKind::OpaqueTy(hir::OpaqueTy {
791             origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
792             ..
793         }) => {}
794
795         // Don't call `type_of` on opaque types, since that depends on type
796         // checking function bodies. `check_item_type` ensures that it's called
797         // instead.
798         hir::ItemKind::OpaqueTy(..) => {
799             tcx.ensure().generics_of(def_id);
800             tcx.ensure().predicates_of(def_id);
801             tcx.ensure().explicit_item_bounds(def_id);
802         }
803         hir::ItemKind::TyAlias(..)
804         | hir::ItemKind::Static(..)
805         | hir::ItemKind::Const(..)
806         | hir::ItemKind::Fn(..) => {
807             tcx.ensure().generics_of(def_id);
808             tcx.ensure().type_of(def_id);
809             tcx.ensure().predicates_of(def_id);
810             match it.kind {
811                 hir::ItemKind::Fn(..) => tcx.ensure().fn_sig(def_id),
812                 hir::ItemKind::OpaqueTy(..) => tcx.ensure().item_bounds(def_id),
813                 hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
814                     if !is_suggestable_infer_ty(ty) {
815                         let mut visitor = HirPlaceholderCollector::default();
816                         visitor.visit_item(it);
817                         placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr());
818                     }
819                 }
820                 _ => (),
821             }
822         }
823     }
824 }
825
826 fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
827     let trait_item = tcx.hir().trait_item(trait_item_id);
828     tcx.ensure().generics_of(trait_item_id.def_id);
829
830     match trait_item.kind {
831         hir::TraitItemKind::Fn(..) => {
832             tcx.ensure().type_of(trait_item_id.def_id);
833             tcx.ensure().fn_sig(trait_item_id.def_id);
834         }
835
836         hir::TraitItemKind::Const(.., Some(_)) => {
837             tcx.ensure().type_of(trait_item_id.def_id);
838         }
839
840         hir::TraitItemKind::Const(..) => {
841             tcx.ensure().type_of(trait_item_id.def_id);
842             // Account for `const C: _;`.
843             let mut visitor = HirPlaceholderCollector::default();
844             visitor.visit_trait_item(trait_item);
845             placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
846         }
847
848         hir::TraitItemKind::Type(_, Some(_)) => {
849             tcx.ensure().item_bounds(trait_item_id.def_id);
850             tcx.ensure().type_of(trait_item_id.def_id);
851             // Account for `type T = _;`.
852             let mut visitor = HirPlaceholderCollector::default();
853             visitor.visit_trait_item(trait_item);
854             placeholder_type_error(tcx, None, visitor.0, false, None, "associated type");
855         }
856
857         hir::TraitItemKind::Type(_, None) => {
858             tcx.ensure().item_bounds(trait_item_id.def_id);
859             // #74612: Visit and try to find bad placeholders
860             // even if there is no concrete type.
861             let mut visitor = HirPlaceholderCollector::default();
862             visitor.visit_trait_item(trait_item);
863
864             placeholder_type_error(tcx, None, visitor.0, false, None, "associated type");
865         }
866     };
867
868     tcx.ensure().predicates_of(trait_item_id.def_id);
869 }
870
871 fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
872     let def_id = impl_item_id.def_id;
873     tcx.ensure().generics_of(def_id);
874     tcx.ensure().type_of(def_id);
875     tcx.ensure().predicates_of(def_id);
876     let impl_item = tcx.hir().impl_item(impl_item_id);
877     match impl_item.kind {
878         hir::ImplItemKind::Fn(..) => {
879             tcx.ensure().fn_sig(def_id);
880         }
881         hir::ImplItemKind::TyAlias(_) => {
882             // Account for `type T = _;`
883             let mut visitor = HirPlaceholderCollector::default();
884             visitor.visit_impl_item(impl_item);
885
886             placeholder_type_error(tcx, None, visitor.0, false, None, "associated type");
887         }
888         hir::ImplItemKind::Const(..) => {}
889     }
890 }
891
892 fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
893     let def_id = tcx.hir().local_def_id(ctor_id);
894     tcx.ensure().generics_of(def_id);
895     tcx.ensure().type_of(def_id);
896     tcx.ensure().predicates_of(def_id);
897 }
898
899 fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId, variants: &[hir::Variant<'_>]) {
900     let def = tcx.adt_def(def_id);
901     let repr_type = def.repr().discr_type();
902     let initial = repr_type.initial_discriminant(tcx);
903     let mut prev_discr = None::<Discr<'_>>;
904
905     // fill the discriminant values and field types
906     for variant in variants {
907         let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
908         prev_discr = Some(
909             if let Some(ref e) = variant.disr_expr {
910                 let expr_did = tcx.hir().local_def_id(e.hir_id);
911                 def.eval_explicit_discr(tcx, expr_did.to_def_id())
912             } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
913                 Some(discr)
914             } else {
915                 struct_span_err!(tcx.sess, variant.span, E0370, "enum discriminant overflowed")
916                     .span_label(
917                         variant.span,
918                         format!("overflowed on value after {}", prev_discr.unwrap()),
919                     )
920                     .note(&format!(
921                         "explicitly set `{} = {}` if that is desired outcome",
922                         variant.ident, wrapped_discr
923                     ))
924                     .emit();
925                 None
926             }
927             .unwrap_or(wrapped_discr),
928         );
929
930         for f in variant.data.fields() {
931             let def_id = tcx.hir().local_def_id(f.hir_id);
932             tcx.ensure().generics_of(def_id);
933             tcx.ensure().type_of(def_id);
934             tcx.ensure().predicates_of(def_id);
935         }
936
937         // Convert the ctor, if any. This also registers the variant as
938         // an item.
939         if let Some(ctor_hir_id) = variant.data.ctor_hir_id() {
940             convert_variant_ctor(tcx, ctor_hir_id);
941         }
942     }
943 }
944
945 fn convert_variant(
946     tcx: TyCtxt<'_>,
947     variant_did: Option<LocalDefId>,
948     ctor_did: Option<LocalDefId>,
949     ident: Ident,
950     discr: ty::VariantDiscr,
951     def: &hir::VariantData<'_>,
952     adt_kind: ty::AdtKind,
953     parent_did: LocalDefId,
954 ) -> ty::VariantDef {
955     let mut seen_fields: FxHashMap<Ident, Span> = Default::default();
956     let fields = def
957         .fields()
958         .iter()
959         .map(|f| {
960             let fid = tcx.hir().local_def_id(f.hir_id);
961             let dup_span = seen_fields.get(&f.ident.normalize_to_macros_2_0()).cloned();
962             if let Some(prev_span) = dup_span {
963                 tcx.sess.emit_err(errors::FieldAlreadyDeclared {
964                     field_name: f.ident,
965                     span: f.span,
966                     prev_span,
967                 });
968             } else {
969                 seen_fields.insert(f.ident.normalize_to_macros_2_0(), f.span);
970             }
971
972             ty::FieldDef { did: fid.to_def_id(), name: f.ident.name, vis: tcx.visibility(fid) }
973         })
974         .collect();
975     let recovered = match def {
976         hir::VariantData::Struct(_, r) => *r,
977         _ => false,
978     };
979     ty::VariantDef::new(
980         ident.name,
981         variant_did.map(LocalDefId::to_def_id),
982         ctor_did.map(LocalDefId::to_def_id),
983         discr,
984         fields,
985         CtorKind::from_hir(def),
986         adt_kind,
987         parent_did.to_def_id(),
988         recovered,
989         adt_kind == AdtKind::Struct && tcx.has_attr(parent_did.to_def_id(), sym::non_exhaustive)
990             || variant_did.map_or(false, |variant_did| {
991                 tcx.has_attr(variant_did.to_def_id(), sym::non_exhaustive)
992             }),
993     )
994 }
995
996 fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> {
997     use rustc_hir::*;
998
999     let def_id = def_id.expect_local();
1000     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1001     let Node::Item(item) = tcx.hir().get(hir_id) else {
1002         bug!();
1003     };
1004
1005     let repr = ReprOptions::new(tcx, def_id.to_def_id());
1006     let (kind, variants) = match item.kind {
1007         ItemKind::Enum(ref def, _) => {
1008             let mut distance_from_explicit = 0;
1009             let variants = def
1010                 .variants
1011                 .iter()
1012                 .map(|v| {
1013                     let variant_did = Some(tcx.hir().local_def_id(v.id));
1014                     let ctor_did =
1015                         v.data.ctor_hir_id().map(|hir_id| tcx.hir().local_def_id(hir_id));
1016
1017                     let discr = if let Some(ref e) = v.disr_expr {
1018                         distance_from_explicit = 0;
1019                         ty::VariantDiscr::Explicit(tcx.hir().local_def_id(e.hir_id).to_def_id())
1020                     } else {
1021                         ty::VariantDiscr::Relative(distance_from_explicit)
1022                     };
1023                     distance_from_explicit += 1;
1024
1025                     convert_variant(
1026                         tcx,
1027                         variant_did,
1028                         ctor_did,
1029                         v.ident,
1030                         discr,
1031                         &v.data,
1032                         AdtKind::Enum,
1033                         def_id,
1034                     )
1035                 })
1036                 .collect();
1037
1038             (AdtKind::Enum, variants)
1039         }
1040         ItemKind::Struct(ref def, _) => {
1041             let variant_did = None::<LocalDefId>;
1042             let ctor_did = def.ctor_hir_id().map(|hir_id| tcx.hir().local_def_id(hir_id));
1043
1044             let variants = std::iter::once(convert_variant(
1045                 tcx,
1046                 variant_did,
1047                 ctor_did,
1048                 item.ident,
1049                 ty::VariantDiscr::Relative(0),
1050                 def,
1051                 AdtKind::Struct,
1052                 def_id,
1053             ))
1054             .collect();
1055
1056             (AdtKind::Struct, variants)
1057         }
1058         ItemKind::Union(ref def, _) => {
1059             let variant_did = None;
1060             let ctor_did = def.ctor_hir_id().map(|hir_id| tcx.hir().local_def_id(hir_id));
1061
1062             let variants = std::iter::once(convert_variant(
1063                 tcx,
1064                 variant_did,
1065                 ctor_did,
1066                 item.ident,
1067                 ty::VariantDiscr::Relative(0),
1068                 def,
1069                 AdtKind::Union,
1070                 def_id,
1071             ))
1072             .collect();
1073
1074             (AdtKind::Union, variants)
1075         }
1076         _ => bug!(),
1077     };
1078     tcx.alloc_adt_def(def_id.to_def_id(), kind, variants, repr)
1079 }
1080
1081 /// Ensures that the super-predicates of the trait with a `DefId`
1082 /// of `trait_def_id` are converted and stored. This also ensures that
1083 /// the transitive super-predicates are converted.
1084 fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredicates<'_> {
1085     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
1086     tcx.super_predicates_that_define_assoc_type((trait_def_id, None))
1087 }
1088
1089 /// Ensures that the super-predicates of the trait with a `DefId`
1090 /// of `trait_def_id` are converted and stored. This also ensures that
1091 /// the transitive super-predicates are converted.
1092 fn super_predicates_that_define_assoc_type(
1093     tcx: TyCtxt<'_>,
1094     (trait_def_id, assoc_name): (DefId, Option<Ident>),
1095 ) -> ty::GenericPredicates<'_> {
1096     debug!(
1097         "super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})",
1098         trait_def_id, assoc_name
1099     );
1100     if trait_def_id.is_local() {
1101         debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id);
1102         let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
1103
1104         let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
1105             bug!("trait_node_id {} is not an item", trait_hir_id);
1106         };
1107
1108         let (generics, bounds) = match item.kind {
1109             hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
1110             hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
1111             _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
1112         };
1113
1114         let icx = ItemCtxt::new(tcx, trait_def_id);
1115
1116         // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
1117         let self_param_ty = tcx.types.self_param;
1118         let superbounds1 = if let Some(assoc_name) = assoc_name {
1119             <dyn AstConv<'_>>::compute_bounds_that_match_assoc_type(
1120                 &icx,
1121                 self_param_ty,
1122                 bounds,
1123                 assoc_name,
1124             )
1125         } else {
1126             <dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds)
1127         };
1128
1129         let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1130
1131         // Convert any explicit superbounds in the where-clause,
1132         // e.g., `trait Foo where Self: Bar`.
1133         // In the case of trait aliases, however, we include all bounds in the where-clause,
1134         // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
1135         // as one of its "superpredicates".
1136         let is_trait_alias = tcx.is_trait_alias(trait_def_id);
1137         let superbounds2 = icx.type_parameter_bounds_in_generics(
1138             generics,
1139             item.hir_id(),
1140             self_param_ty,
1141             OnlySelfBounds(!is_trait_alias),
1142             assoc_name,
1143         );
1144
1145         // Combine the two lists to form the complete set of superbounds:
1146         let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
1147         debug!(?superbounds);
1148
1149         // Now require that immediate supertraits are converted,
1150         // which will, in turn, reach indirect supertraits.
1151         if assoc_name.is_none() {
1152             // Now require that immediate supertraits are converted,
1153             // which will, in turn, reach indirect supertraits.
1154             for &(pred, span) in superbounds {
1155                 debug!("superbound: {:?}", pred);
1156                 if let ty::PredicateKind::Trait(bound) = pred.kind().skip_binder() {
1157                     tcx.at(span).super_predicates_of(bound.def_id());
1158                 }
1159             }
1160         }
1161
1162         ty::GenericPredicates { parent: None, predicates: superbounds }
1163     } else {
1164         // if `assoc_name` is None, then the query should've been redirected to an
1165         // external provider
1166         assert!(assoc_name.is_some());
1167         tcx.super_predicates_of(trait_def_id)
1168     }
1169 }
1170
1171 fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
1172     let item = tcx.hir().expect_item(def_id.expect_local());
1173
1174     let (is_auto, unsafety, items) = match item.kind {
1175         hir::ItemKind::Trait(is_auto, unsafety, .., items) => {
1176             (is_auto == hir::IsAuto::Yes, unsafety, items)
1177         }
1178         hir::ItemKind::TraitAlias(..) => (false, hir::Unsafety::Normal, &[][..]),
1179         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
1180     };
1181
1182     let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
1183     if paren_sugar && !tcx.features().unboxed_closures {
1184         tcx.sess
1185             .struct_span_err(
1186                 item.span,
1187                 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1188                  which traits can use parenthetical notation",
1189             )
1190             .help("add `#![feature(unboxed_closures)]` to the crate attributes to use it")
1191             .emit();
1192     }
1193
1194     let is_marker = tcx.has_attr(def_id, sym::marker);
1195     let skip_array_during_method_dispatch =
1196         tcx.has_attr(def_id, sym::rustc_skip_array_during_method_dispatch);
1197     let spec_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
1198         ty::trait_def::TraitSpecializationKind::Marker
1199     } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
1200         ty::trait_def::TraitSpecializationKind::AlwaysApplicable
1201     } else {
1202         ty::trait_def::TraitSpecializationKind::None
1203     };
1204     let must_implement_one_of = tcx
1205         .get_attr(def_id, sym::rustc_must_implement_one_of)
1206         // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]`
1207         // and that they are all identifiers
1208         .and_then(|attr| match attr.meta_item_list() {
1209             Some(items) if items.len() < 2 => {
1210                 tcx.sess
1211                     .struct_span_err(
1212                         attr.span,
1213                         "the `#[rustc_must_implement_one_of]` attribute must be \
1214                         used with at least 2 args",
1215                     )
1216                     .emit();
1217
1218                 None
1219             }
1220             Some(items) => items
1221                 .into_iter()
1222                 .map(|item| item.ident().ok_or(item.span()))
1223                 .collect::<Result<Box<[_]>, _>>()
1224                 .map_err(|span| {
1225                     tcx.sess
1226                         .struct_span_err(span, "must be a name of an associated function")
1227                         .emit();
1228                 })
1229                 .ok()
1230                 .zip(Some(attr.span)),
1231             // Error is reported by `rustc_attr!`
1232             None => None,
1233         })
1234         // Check that all arguments of `#[rustc_must_implement_one_of]` reference
1235         // functions in the trait with default implementations
1236         .and_then(|(list, attr_span)| {
1237             let errors = list.iter().filter_map(|ident| {
1238                 let item = items.iter().find(|item| item.ident == *ident);
1239
1240                 match item {
1241                     Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
1242                         if !tcx.impl_defaultness(item.id.def_id).has_value() {
1243                             tcx.sess
1244                                 .struct_span_err(
1245                                     item.span,
1246                                     "This function doesn't have a default implementation",
1247                                 )
1248                                 .span_note(attr_span, "required by this annotation")
1249                                 .emit();
1250
1251                             return Some(());
1252                         }
1253
1254                         return None;
1255                     }
1256                     Some(item) => {
1257                         tcx.sess
1258                             .struct_span_err(item.span, "Not a function")
1259                             .span_note(attr_span, "required by this annotation")
1260                             .note(
1261                                 "All `#[rustc_must_implement_one_of]` arguments \
1262                             must be associated function names",
1263                             )
1264                             .emit();
1265                     }
1266                     None => {
1267                         tcx.sess
1268                             .struct_span_err(ident.span, "Function not found in this trait")
1269                             .emit();
1270                     }
1271                 }
1272
1273                 Some(())
1274             });
1275
1276             (errors.count() == 0).then_some(list)
1277         })
1278         // Check for duplicates
1279         .and_then(|list| {
1280             let mut set: FxHashMap<Symbol, Span> = FxHashMap::default();
1281             let mut no_dups = true;
1282
1283             for ident in &*list {
1284                 if let Some(dup) = set.insert(ident.name, ident.span) {
1285                     tcx.sess
1286                         .struct_span_err(vec![dup, ident.span], "Functions names are duplicated")
1287                         .note(
1288                             "All `#[rustc_must_implement_one_of]` arguments \
1289                             must be unique",
1290                         )
1291                         .emit();
1292
1293                     no_dups = false;
1294                 }
1295             }
1296
1297             no_dups.then_some(list)
1298         });
1299
1300     ty::TraitDef::new(
1301         def_id,
1302         unsafety,
1303         paren_sugar,
1304         is_auto,
1305         is_marker,
1306         skip_array_during_method_dispatch,
1307         spec_kind,
1308         must_implement_one_of,
1309     )
1310 }
1311
1312 fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<Span> {
1313     struct LateBoundRegionsDetector<'tcx> {
1314         tcx: TyCtxt<'tcx>,
1315         outer_index: ty::DebruijnIndex,
1316         has_late_bound_regions: Option<Span>,
1317     }
1318
1319     impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> {
1320         fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
1321             if self.has_late_bound_regions.is_some() {
1322                 return;
1323             }
1324             match ty.kind {
1325                 hir::TyKind::BareFn(..) => {
1326                     self.outer_index.shift_in(1);
1327                     intravisit::walk_ty(self, ty);
1328                     self.outer_index.shift_out(1);
1329                 }
1330                 _ => intravisit::walk_ty(self, ty),
1331             }
1332         }
1333
1334         fn visit_poly_trait_ref(
1335             &mut self,
1336             tr: &'tcx hir::PolyTraitRef<'tcx>,
1337             m: hir::TraitBoundModifier,
1338         ) {
1339             if self.has_late_bound_regions.is_some() {
1340                 return;
1341             }
1342             self.outer_index.shift_in(1);
1343             intravisit::walk_poly_trait_ref(self, tr, m);
1344             self.outer_index.shift_out(1);
1345         }
1346
1347         fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
1348             if self.has_late_bound_regions.is_some() {
1349                 return;
1350             }
1351
1352             match self.tcx.named_region(lt.hir_id) {
1353                 Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {}
1354                 Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {}
1355                 Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => {
1356                     self.has_late_bound_regions = Some(lt.span);
1357                 }
1358             }
1359         }
1360     }
1361
1362     fn has_late_bound_regions<'tcx>(
1363         tcx: TyCtxt<'tcx>,
1364         generics: &'tcx hir::Generics<'tcx>,
1365         decl: &'tcx hir::FnDecl<'tcx>,
1366     ) -> Option<Span> {
1367         let mut visitor = LateBoundRegionsDetector {
1368             tcx,
1369             outer_index: ty::INNERMOST,
1370             has_late_bound_regions: None,
1371         };
1372         for param in generics.params {
1373             if let GenericParamKind::Lifetime { .. } = param.kind {
1374                 if tcx.is_late_bound(param.hir_id) {
1375                     return Some(param.span);
1376                 }
1377             }
1378         }
1379         visitor.visit_fn_decl(decl);
1380         visitor.has_late_bound_regions
1381     }
1382
1383     match node {
1384         Node::TraitItem(item) => match item.kind {
1385             hir::TraitItemKind::Fn(ref sig, _) => {
1386                 has_late_bound_regions(tcx, &item.generics, sig.decl)
1387             }
1388             _ => None,
1389         },
1390         Node::ImplItem(item) => match item.kind {
1391             hir::ImplItemKind::Fn(ref sig, _) => {
1392                 has_late_bound_regions(tcx, &item.generics, sig.decl)
1393             }
1394             _ => None,
1395         },
1396         Node::ForeignItem(item) => match item.kind {
1397             hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => {
1398                 has_late_bound_regions(tcx, generics, fn_decl)
1399             }
1400             _ => None,
1401         },
1402         Node::Item(item) => match item.kind {
1403             hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
1404                 has_late_bound_regions(tcx, generics, sig.decl)
1405             }
1406             _ => None,
1407         },
1408         _ => None,
1409     }
1410 }
1411
1412 struct AnonConstInParamTyDetector {
1413     in_param_ty: bool,
1414     found_anon_const_in_param_ty: bool,
1415     ct: HirId,
1416 }
1417
1418 impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
1419     fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
1420         if let GenericParamKind::Const { ty, default: _ } = p.kind {
1421             let prev = self.in_param_ty;
1422             self.in_param_ty = true;
1423             self.visit_ty(ty);
1424             self.in_param_ty = prev;
1425         }
1426     }
1427
1428     fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
1429         if self.in_param_ty && self.ct == c.hir_id {
1430             self.found_anon_const_in_param_ty = true;
1431         } else {
1432             intravisit::walk_anon_const(self, c)
1433         }
1434     }
1435 }
1436
1437 fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
1438     use rustc_hir::*;
1439
1440     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
1441
1442     let node = tcx.hir().get(hir_id);
1443     let parent_def_id = match node {
1444         Node::ImplItem(_)
1445         | Node::TraitItem(_)
1446         | Node::Variant(_)
1447         | Node::Ctor(..)
1448         | Node::Field(_) => {
1449             let parent_id = tcx.hir().get_parent_item(hir_id);
1450             Some(parent_id.to_def_id())
1451         }
1452         // FIXME(#43408) always enable this once `lazy_normalization` is
1453         // stable enough and does not need a feature gate anymore.
1454         Node::AnonConst(_) => {
1455             let parent_def_id = tcx.hir().get_parent_item(hir_id);
1456
1457             let mut in_param_ty = false;
1458             for (_parent, node) in tcx.hir().parent_iter(hir_id) {
1459                 if let Some(generics) = node.generics() {
1460                     let mut visitor = AnonConstInParamTyDetector {
1461                         in_param_ty: false,
1462                         found_anon_const_in_param_ty: false,
1463                         ct: hir_id,
1464                     };
1465
1466                     visitor.visit_generics(generics);
1467                     in_param_ty = visitor.found_anon_const_in_param_ty;
1468                     break;
1469                 }
1470             }
1471
1472             if in_param_ty {
1473                 // We do not allow generic parameters in anon consts if we are inside
1474                 // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
1475                 None
1476             } else if tcx.lazy_normalization() {
1477                 if let Some(param_id) = tcx.hir().opt_const_param_default_param_hir_id(hir_id) {
1478                     // If the def_id we are calling generics_of on is an anon ct default i.e:
1479                     //
1480                     // struct Foo<const N: usize = { .. }>;
1481                     //        ^^^       ^          ^^^^^^ def id of this anon const
1482                     //        ^         ^ param_id
1483                     //        ^ parent_def_id
1484                     //
1485                     // then we only want to return generics for params to the left of `N`. If we don't do that we
1486                     // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`.
1487                     //
1488                     // This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as
1489                     // we substitute the defaults with the partially built substs when we build the substs. Subst'ing
1490                     // the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building.
1491                     //
1492                     // We fix this by having this function return the parent's generics ourselves and truncating the
1493                     // generics to only include non-forward declared params (with the exception of the `Self` ty)
1494                     //
1495                     // For the above code example that means we want `substs: []`
1496                     // For the following struct def we want `substs: [N#0]` when generics_of is called on
1497                     // the def id of the `{ N + 1 }` anon const
1498                     // struct Foo<const N: usize, const M: usize = { N + 1 }>;
1499                     //
1500                     // This has some implications for how we get the predicates available to the anon const
1501                     // see `explicit_predicates_of` for more information on this
1502                     let generics = tcx.generics_of(parent_def_id.to_def_id());
1503                     let param_def = tcx.hir().local_def_id(param_id).to_def_id();
1504                     let param_def_idx = generics.param_def_id_to_index[&param_def];
1505                     // In the above example this would be .params[..N#0]
1506                     let params = generics.params[..param_def_idx as usize].to_owned();
1507                     let param_def_id_to_index =
1508                         params.iter().map(|param| (param.def_id, param.index)).collect();
1509
1510                     return ty::Generics {
1511                         // we set the parent of these generics to be our parent's parent so that we
1512                         // dont end up with substs: [N, M, N] for the const default on a struct like this:
1513                         // struct Foo<const N: usize, const M: usize = { ... }>;
1514                         parent: generics.parent,
1515                         parent_count: generics.parent_count,
1516                         params,
1517                         param_def_id_to_index,
1518                         has_self: generics.has_self,
1519                         has_late_bound_regions: generics.has_late_bound_regions,
1520                     };
1521                 }
1522
1523                 // HACK(eddyb) this provides the correct generics when
1524                 // `feature(generic_const_expressions)` is enabled, so that const expressions
1525                 // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
1526                 //
1527                 // Note that we do not supply the parent generics when using
1528                 // `min_const_generics`.
1529                 Some(parent_def_id.to_def_id())
1530             } else {
1531                 let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
1532                 match parent_node {
1533                     // HACK(eddyb) this provides the correct generics for repeat
1534                     // expressions' count (i.e. `N` in `[x; N]`), and explicit
1535                     // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
1536                     // as they shouldn't be able to cause query cycle errors.
1537                     Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
1538                         if constant.hir_id() == hir_id =>
1539                     {
1540                         Some(parent_def_id.to_def_id())
1541                     }
1542                     Node::Variant(Variant { disr_expr: Some(ref constant), .. })
1543                         if constant.hir_id == hir_id =>
1544                     {
1545                         Some(parent_def_id.to_def_id())
1546                     }
1547                     Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
1548                         Some(tcx.typeck_root_def_id(def_id))
1549                     }
1550                     // Exclude `GlobalAsm` here which cannot have generics.
1551                     Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
1552                         if asm.operands.iter().any(|(op, _op_sp)| match op {
1553                             hir::InlineAsmOperand::Const { anon_const }
1554                             | hir::InlineAsmOperand::SymFn { anon_const } => {
1555                                 anon_const.hir_id == hir_id
1556                             }
1557                             _ => false,
1558                         }) =>
1559                     {
1560                         Some(parent_def_id.to_def_id())
1561                     }
1562                     _ => None,
1563                 }
1564             }
1565         }
1566         Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
1567             Some(tcx.typeck_root_def_id(def_id))
1568         }
1569         Node::Item(item) => match item.kind {
1570             ItemKind::OpaqueTy(hir::OpaqueTy {
1571                 origin:
1572                     hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
1573                 ..
1574             }) => Some(fn_def_id.to_def_id()),
1575             ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
1576                 let parent_id = tcx.hir().get_parent_item(hir_id);
1577                 assert_ne!(parent_id, CRATE_DEF_ID);
1578                 debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
1579                 // Opaque types are always nested within another item, and
1580                 // inherit the generics of the item.
1581                 Some(parent_id.to_def_id())
1582             }
1583             _ => None,
1584         },
1585         _ => None,
1586     };
1587
1588     let no_generics = hir::Generics::empty();
1589     let ast_generics = node.generics().unwrap_or(&no_generics);
1590     let (opt_self, allow_defaults) = match node {
1591         Node::Item(item) => {
1592             match item.kind {
1593                 ItemKind::Trait(..) | ItemKind::TraitAlias(..) => {
1594                     // Add in the self type parameter.
1595                     //
1596                     // Something of a hack: use the node id for the trait, also as
1597                     // the node id for the Self type parameter.
1598                     let opt_self = Some(ty::GenericParamDef {
1599                         index: 0,
1600                         name: kw::SelfUpper,
1601                         def_id,
1602                         pure_wrt_drop: false,
1603                         kind: ty::GenericParamDefKind::Type {
1604                             has_default: false,
1605                             object_lifetime_default: rl::Set1::Empty,
1606                             synthetic: false,
1607                         },
1608                     });
1609
1610                     (opt_self, true)
1611                 }
1612                 ItemKind::TyAlias(..)
1613                 | ItemKind::Enum(..)
1614                 | ItemKind::Struct(..)
1615                 | ItemKind::OpaqueTy(..)
1616                 | ItemKind::Union(..) => (None, true),
1617                 _ => (None, false),
1618             }
1619         }
1620         _ => (None, false),
1621     };
1622
1623     let has_self = opt_self.is_some();
1624     let mut parent_has_self = false;
1625     let mut own_start = has_self as u32;
1626     let parent_count = parent_def_id.map_or(0, |def_id| {
1627         let generics = tcx.generics_of(def_id);
1628         assert!(!has_self);
1629         parent_has_self = generics.has_self;
1630         own_start = generics.count() as u32;
1631         generics.parent_count + generics.params.len()
1632     });
1633
1634     let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize);
1635
1636     if let Some(opt_self) = opt_self {
1637         params.push(opt_self);
1638     }
1639
1640     let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
1641     params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
1642         name: param.name.ident().name,
1643         index: own_start + i as u32,
1644         def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
1645         pure_wrt_drop: param.pure_wrt_drop,
1646         kind: ty::GenericParamDefKind::Lifetime,
1647     }));
1648
1649     let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner);
1650
1651     // Now create the real type and const parameters.
1652     let type_start = own_start - has_self as u32 + params.len() as u32;
1653     let mut i = 0;
1654
1655     params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
1656         GenericParamKind::Lifetime { .. } => None,
1657         GenericParamKind::Type { ref default, synthetic, .. } => {
1658             if !allow_defaults && default.is_some() {
1659                 if !tcx.features().default_type_parameter_fallback {
1660                     tcx.struct_span_lint_hir(
1661                         lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1662                         param.hir_id,
1663                         param.span,
1664                         |lint| {
1665                             lint.build(
1666                                 "defaults for type parameters are only allowed in \
1667                                  `struct`, `enum`, `type`, or `trait` definitions",
1668                             )
1669                             .emit();
1670                         },
1671                     );
1672                 }
1673             }
1674
1675             let kind = ty::GenericParamDefKind::Type {
1676                 has_default: default.is_some(),
1677                 object_lifetime_default: object_lifetime_defaults
1678                     .as_ref()
1679                     .map_or(rl::Set1::Empty, |o| o[i]),
1680                 synthetic,
1681             };
1682
1683             let param_def = ty::GenericParamDef {
1684                 index: type_start + i as u32,
1685                 name: param.name.ident().name,
1686                 def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
1687                 pure_wrt_drop: param.pure_wrt_drop,
1688                 kind,
1689             };
1690             i += 1;
1691             Some(param_def)
1692         }
1693         GenericParamKind::Const { default, .. } => {
1694             if !allow_defaults && default.is_some() {
1695                 tcx.sess.span_err(
1696                     param.span,
1697                     "defaults for const parameters are only allowed in \
1698                     `struct`, `enum`, `type`, or `trait` definitions",
1699                 );
1700             }
1701
1702             let param_def = ty::GenericParamDef {
1703                 index: type_start + i as u32,
1704                 name: param.name.ident().name,
1705                 def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
1706                 pure_wrt_drop: param.pure_wrt_drop,
1707                 kind: ty::GenericParamDefKind::Const { has_default: default.is_some() },
1708             };
1709             i += 1;
1710             Some(param_def)
1711         }
1712     }));
1713
1714     // provide junk type parameter defs - the only place that
1715     // cares about anything but the length is instantiation,
1716     // and we don't do that for closures.
1717     if let Node::Expr(&hir::Expr {
1718         kind: hir::ExprKind::Closure(hir::Closure { movability: gen, .. }),
1719         ..
1720     }) = node
1721     {
1722         let dummy_args = if gen.is_some() {
1723             &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
1724         } else {
1725             &["<closure_kind>", "<closure_signature>", "<upvars>"][..]
1726         };
1727
1728         params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef {
1729             index: type_start + i as u32,
1730             name: Symbol::intern(arg),
1731             def_id,
1732             pure_wrt_drop: false,
1733             kind: ty::GenericParamDefKind::Type {
1734                 has_default: false,
1735                 object_lifetime_default: rl::Set1::Empty,
1736                 synthetic: false,
1737             },
1738         }));
1739     }
1740
1741     // provide junk type parameter defs for const blocks.
1742     if let Node::AnonConst(_) = node {
1743         let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
1744         if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node {
1745             params.push(ty::GenericParamDef {
1746                 index: type_start,
1747                 name: Symbol::intern("<const_ty>"),
1748                 def_id,
1749                 pure_wrt_drop: false,
1750                 kind: ty::GenericParamDefKind::Type {
1751                     has_default: false,
1752                     object_lifetime_default: rl::Set1::Empty,
1753                     synthetic: false,
1754                 },
1755             });
1756         }
1757     }
1758
1759     let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect();
1760
1761     ty::Generics {
1762         parent: parent_def_id,
1763         parent_count,
1764         params,
1765         param_def_id_to_index,
1766         has_self: has_self || parent_has_self,
1767         has_late_bound_regions: has_late_bound_regions(tcx, node),
1768     }
1769 }
1770
1771 fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
1772     generic_args.iter().any(|arg| match arg {
1773         hir::GenericArg::Type(ty) => is_suggestable_infer_ty(ty),
1774         hir::GenericArg::Infer(_) => true,
1775         _ => false,
1776     })
1777 }
1778
1779 /// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
1780 /// use inference to provide suggestions for the appropriate type if possible.
1781 fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
1782     debug!(?ty);
1783     use hir::TyKind::*;
1784     match &ty.kind {
1785         Infer => true,
1786         Slice(ty) => is_suggestable_infer_ty(ty),
1787         Array(ty, length) => {
1788             is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
1789         }
1790         Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
1791         Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
1792         OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
1793         Path(hir::QPath::TypeRelative(ty, segment)) => {
1794             is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
1795         }
1796         Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => {
1797             ty_opt.map_or(false, is_suggestable_infer_ty)
1798                 || segments.iter().any(|segment| are_suggestable_generic_args(segment.args().args))
1799         }
1800         _ => false,
1801     }
1802 }
1803
1804 pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> {
1805     if let hir::FnRetTy::Return(ty) = output {
1806         if is_suggestable_infer_ty(ty) {
1807             return Some(&*ty);
1808         }
1809     }
1810     None
1811 }
1812
1813 fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
1814     use rustc_hir::Node::*;
1815     use rustc_hir::*;
1816
1817     let def_id = def_id.expect_local();
1818     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1819
1820     let icx = ItemCtxt::new(tcx, def_id.to_def_id());
1821
1822     match tcx.hir().get(hir_id) {
1823         TraitItem(hir::TraitItem {
1824             kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
1825             generics,
1826             ..
1827         })
1828         | Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), .. }) => {
1829             infer_return_ty_for_fn_sig(tcx, sig, generics, def_id, &icx)
1830         }
1831
1832         ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
1833             // Do not try to inference the return type for a impl method coming from a trait
1834             if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) =
1835                 tcx.hir().get(tcx.hir().get_parent_node(hir_id))
1836                 && i.of_trait.is_some()
1837             {
1838                 <dyn AstConv<'_>>::ty_of_fn(
1839                     &icx,
1840                     hir_id,
1841                     sig.header.unsafety,
1842                     sig.header.abi,
1843                     sig.decl,
1844                     Some(generics),
1845                     None,
1846                 )
1847             } else {
1848                 infer_return_ty_for_fn_sig(tcx, sig, generics, def_id, &icx)
1849             }
1850         }
1851
1852         TraitItem(hir::TraitItem {
1853             kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
1854             generics,
1855             ..
1856         }) => <dyn AstConv<'_>>::ty_of_fn(
1857             &icx,
1858             hir_id,
1859             header.unsafety,
1860             header.abi,
1861             decl,
1862             Some(generics),
1863             None,
1864         ),
1865
1866         ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
1867             let abi = tcx.hir().get_foreign_abi(hir_id);
1868             compute_sig_of_foreign_fn_decl(tcx, def_id.to_def_id(), fn_decl, abi)
1869         }
1870
1871         Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor_hir_id().is_some() => {
1872             let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id));
1873             let inputs =
1874                 data.fields().iter().map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id)));
1875             ty::Binder::dummy(tcx.mk_fn_sig(
1876                 inputs,
1877                 ty,
1878                 false,
1879                 hir::Unsafety::Normal,
1880                 abi::Abi::Rust,
1881             ))
1882         }
1883
1884         Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
1885             // Closure signatures are not like other function
1886             // signatures and cannot be accessed through `fn_sig`. For
1887             // example, a closure signature excludes the `self`
1888             // argument. In any case they are embedded within the
1889             // closure type as part of the `ClosureSubsts`.
1890             //
1891             // To get the signature of a closure, you should use the
1892             // `sig` method on the `ClosureSubsts`:
1893             //
1894             //    substs.as_closure().sig(def_id, tcx)
1895             bug!(
1896                 "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
1897             );
1898         }
1899
1900         x => {
1901             bug!("unexpected sort of node in fn_sig(): {:?}", x);
1902         }
1903     }
1904 }
1905
1906 fn infer_return_ty_for_fn_sig<'tcx>(
1907     tcx: TyCtxt<'tcx>,
1908     sig: &hir::FnSig<'_>,
1909     generics: &hir::Generics<'_>,
1910     def_id: LocalDefId,
1911     icx: &ItemCtxt<'tcx>,
1912 ) -> ty::PolyFnSig<'tcx> {
1913     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1914
1915     match get_infer_ret_ty(&sig.decl.output) {
1916         Some(ty) => {
1917             let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
1918             // Typeck doesn't expect erased regions to be returned from `type_of`.
1919             let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r {
1920                 ty::ReErased => tcx.lifetimes.re_static,
1921                 _ => r,
1922             });
1923             let fn_sig = ty::Binder::dummy(fn_sig);
1924
1925             let mut visitor = HirPlaceholderCollector::default();
1926             visitor.visit_ty(ty);
1927             let mut diag = bad_placeholder(tcx, visitor.0, "return type");
1928             let ret_ty = fn_sig.skip_binder().output();
1929             if ret_ty.is_suggestable(tcx, false) {
1930                 diag.span_suggestion(
1931                     ty.span,
1932                     "replace with the correct return type",
1933                     ret_ty,
1934                     Applicability::MachineApplicable,
1935                 );
1936             } else if matches!(ret_ty.kind(), ty::FnDef(..)) {
1937                 let fn_sig = ret_ty.fn_sig(tcx);
1938                 if fn_sig
1939                     .skip_binder()
1940                     .inputs_and_output
1941                     .iter()
1942                     .all(|t| t.is_suggestable(tcx, false))
1943                 {
1944                     diag.span_suggestion(
1945                         ty.span,
1946                         "replace with the correct return type",
1947                         fn_sig,
1948                         Applicability::MachineApplicable,
1949                     );
1950                 }
1951             } else if ret_ty.is_closure() {
1952                 // We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
1953                 // to prevent the user from getting a papercut while trying to use the unique closure
1954                 // syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
1955                 diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
1956                 diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
1957             }
1958             diag.emit();
1959
1960             fn_sig
1961         }
1962         None => <dyn AstConv<'_>>::ty_of_fn(
1963             icx,
1964             hir_id,
1965             sig.header.unsafety,
1966             sig.header.abi,
1967             sig.decl,
1968             Some(generics),
1969             None,
1970         ),
1971     }
1972 }
1973
1974 fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
1975     let icx = ItemCtxt::new(tcx, def_id);
1976     match tcx.hir().expect_item(def_id.expect_local()).kind {
1977         hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| {
1978             let selfty = tcx.type_of(def_id);
1979             <dyn AstConv<'_>>::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1980         }),
1981         _ => bug!(),
1982     }
1983 }
1984
1985 fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
1986     let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
1987     let item = tcx.hir().expect_item(def_id.expect_local());
1988     match &item.kind {
1989         hir::ItemKind::Impl(hir::Impl {
1990             polarity: hir::ImplPolarity::Negative(span),
1991             of_trait,
1992             ..
1993         }) => {
1994             if is_rustc_reservation {
1995                 let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span));
1996                 tcx.sess.span_err(span, "reservation impls can't be negative");
1997             }
1998             ty::ImplPolarity::Negative
1999         }
2000         hir::ItemKind::Impl(hir::Impl {
2001             polarity: hir::ImplPolarity::Positive,
2002             of_trait: None,
2003             ..
2004         }) => {
2005             if is_rustc_reservation {
2006                 tcx.sess.span_err(item.span, "reservation impls can't be inherent");
2007             }
2008             ty::ImplPolarity::Positive
2009         }
2010         hir::ItemKind::Impl(hir::Impl {
2011             polarity: hir::ImplPolarity::Positive,
2012             of_trait: Some(_),
2013             ..
2014         }) => {
2015             if is_rustc_reservation {
2016                 ty::ImplPolarity::Reservation
2017             } else {
2018                 ty::ImplPolarity::Positive
2019             }
2020         }
2021         item => bug!("impl_polarity: {:?} not an impl", item),
2022     }
2023 }
2024
2025 /// Returns the early-bound lifetimes declared in this generics
2026 /// listing. For anything other than fns/methods, this is just all
2027 /// the lifetimes that are declared. For fns or methods, we have to
2028 /// screen out those that do not appear in any where-clauses etc using
2029 /// `resolve_lifetime::early_bound_lifetimes`.
2030 fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
2031     tcx: TyCtxt<'tcx>,
2032     generics: &'a hir::Generics<'a>,
2033 ) -> impl Iterator<Item = &'a hir::GenericParam<'a>> + Captures<'tcx> {
2034     generics.params.iter().filter(move |param| match param.kind {
2035         GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
2036         _ => false,
2037     })
2038 }
2039
2040 /// Returns a list of type predicates for the definition with ID `def_id`, including inferred
2041 /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
2042 /// inferred constraints concerning which regions outlive other regions.
2043 fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
2044     debug!("predicates_defined_on({:?})", def_id);
2045     let mut result = tcx.explicit_predicates_of(def_id);
2046     debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result,);
2047     let inferred_outlives = tcx.inferred_outlives_of(def_id);
2048     if !inferred_outlives.is_empty() {
2049         debug!(
2050             "predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
2051             def_id, inferred_outlives,
2052         );
2053         if result.predicates.is_empty() {
2054             result.predicates = inferred_outlives;
2055         } else {
2056             result.predicates = tcx
2057                 .arena
2058                 .alloc_from_iter(result.predicates.iter().chain(inferred_outlives).copied());
2059         }
2060     }
2061
2062     debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
2063     result
2064 }
2065
2066 /// Returns a list of all type predicates (explicit and implicit) for the definition with
2067 /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
2068 /// `Self: Trait` predicates for traits.
2069 fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
2070     let mut result = tcx.predicates_defined_on(def_id);
2071
2072     if tcx.is_trait(def_id) {
2073         // For traits, add `Self: Trait` predicate. This is
2074         // not part of the predicates that a user writes, but it
2075         // is something that one must prove in order to invoke a
2076         // method or project an associated type.
2077         //
2078         // In the chalk setup, this predicate is not part of the
2079         // "predicates" for a trait item. But it is useful in
2080         // rustc because if you directly (e.g.) invoke a trait
2081         // method like `Trait::method(...)`, you must naturally
2082         // prove that the trait applies to the types that were
2083         // used, and adding the predicate into this list ensures
2084         // that this is done.
2085         //
2086         // We use a DUMMY_SP here as a way to signal trait bounds that come
2087         // from the trait itself that *shouldn't* be shown as the source of
2088         // an obligation and instead be skipped. Otherwise we'd use
2089         // `tcx.def_span(def_id);`
2090
2091         let constness = if tcx.has_attr(def_id, sym::const_trait) {
2092             ty::BoundConstness::ConstIfConst
2093         } else {
2094             ty::BoundConstness::NotConst
2095         };
2096
2097         let span = rustc_span::DUMMY_SP;
2098         result.predicates =
2099             tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
2100                 ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
2101                 span,
2102             ))));
2103     }
2104     debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
2105     result
2106 }
2107
2108 /// Returns a list of user-specified type predicates for the definition with ID `def_id`.
2109 /// N.B., this does not include any implied/inferred constraints.
2110 fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
2111     use rustc_hir::*;
2112
2113     debug!("explicit_predicates_of(def_id={:?})", def_id);
2114
2115     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
2116     let node = tcx.hir().get(hir_id);
2117
2118     let mut is_trait = None;
2119     let mut is_default_impl_trait = None;
2120
2121     let icx = ItemCtxt::new(tcx, def_id);
2122
2123     const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
2124
2125     // We use an `IndexSet` to preserves order of insertion.
2126     // Preserving the order of insertion is important here so as not to break UI tests.
2127     let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default();
2128
2129     let ast_generics = match node {
2130         Node::TraitItem(item) => item.generics,
2131
2132         Node::ImplItem(item) => item.generics,
2133
2134         Node::Item(item) => {
2135             match item.kind {
2136                 ItemKind::Impl(ref impl_) => {
2137                     if impl_.defaultness.is_default() {
2138                         is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy);
2139                     }
2140                     &impl_.generics
2141                 }
2142                 ItemKind::Fn(.., ref generics, _)
2143                 | ItemKind::TyAlias(_, ref generics)
2144                 | ItemKind::Enum(_, ref generics)
2145                 | ItemKind::Struct(_, ref generics)
2146                 | ItemKind::Union(_, ref generics) => *generics,
2147
2148                 ItemKind::Trait(_, _, ref generics, ..) => {
2149                     is_trait = Some(ty::TraitRef::identity(tcx, def_id));
2150                     *generics
2151                 }
2152                 ItemKind::TraitAlias(ref generics, _) => {
2153                     is_trait = Some(ty::TraitRef::identity(tcx, def_id));
2154                     *generics
2155                 }
2156                 ItemKind::OpaqueTy(OpaqueTy {
2157                     origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
2158                     ..
2159                 }) => {
2160                     // return-position impl trait
2161                     //
2162                     // We don't inherit predicates from the parent here:
2163                     // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
2164                     // then the return type is `f::<'static, T>::{{opaque}}`.
2165                     //
2166                     // If we inherited the predicates of `f` then we would
2167                     // require that `T: 'static` to show that the return
2168                     // type is well-formed.
2169                     //
2170                     // The only way to have something with this opaque type
2171                     // is from the return type of the containing function,
2172                     // which will ensure that the function's predicates
2173                     // hold.
2174                     return ty::GenericPredicates { parent: None, predicates: &[] };
2175                 }
2176                 ItemKind::OpaqueTy(OpaqueTy {
2177                     ref generics,
2178                     origin: hir::OpaqueTyOrigin::TyAlias,
2179                     ..
2180                 }) => {
2181                     // type-alias impl trait
2182                     generics
2183                 }
2184
2185                 _ => NO_GENERICS,
2186             }
2187         }
2188
2189         Node::ForeignItem(item) => match item.kind {
2190             ForeignItemKind::Static(..) => NO_GENERICS,
2191             ForeignItemKind::Fn(_, _, ref generics) => *generics,
2192             ForeignItemKind::Type => NO_GENERICS,
2193         },
2194
2195         _ => NO_GENERICS,
2196     };
2197
2198     let generics = tcx.generics_of(def_id);
2199     let parent_count = generics.parent_count as u32;
2200     let has_own_self = generics.has_self && parent_count == 0;
2201
2202     // Below we'll consider the bounds on the type parameters (including `Self`)
2203     // and the explicit where-clauses, but to get the full set of predicates
2204     // on a trait we need to add in the supertrait bounds and bounds found on
2205     // associated types.
2206     if let Some(_trait_ref) = is_trait {
2207         predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
2208     }
2209
2210     // In default impls, we can assume that the self type implements
2211     // the trait. So in:
2212     //
2213     //     default impl Foo for Bar { .. }
2214     //
2215     // we add a default where clause `Foo: Bar`. We do a similar thing for traits
2216     // (see below). Recall that a default impl is not itself an impl, but rather a
2217     // set of defaults that can be incorporated into another impl.
2218     if let Some(trait_ref) = is_default_impl_trait {
2219         predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
2220     }
2221
2222     // Collect the region predicates that were declared inline as
2223     // well. In the case of parameters declared on a fn or method, we
2224     // have to be careful to only iterate over early-bound regions.
2225     let mut index = parent_count
2226         + has_own_self as u32
2227         + early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
2228
2229     // Collect the predicates that were written inline by the user on each
2230     // type parameter (e.g., `<T: Foo>`).
2231     for param in ast_generics.params {
2232         match param.kind {
2233             // We already dealt with early bound lifetimes above.
2234             GenericParamKind::Lifetime { .. } => (),
2235             GenericParamKind::Type { .. } => {
2236                 let name = param.name.ident().name;
2237                 let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
2238                 index += 1;
2239
2240                 let mut bounds = Bounds::default();
2241                 // Params are implicitly sized unless a `?Sized` bound is found
2242                 <dyn AstConv<'_>>::add_implicitly_sized(
2243                     &icx,
2244                     &mut bounds,
2245                     &[],
2246                     Some((param.hir_id, ast_generics.predicates)),
2247                     param.span,
2248                 );
2249                 predicates.extend(bounds.predicates(tcx, param_ty));
2250             }
2251             GenericParamKind::Const { .. } => {
2252                 // Bounds on const parameters are currently not possible.
2253                 index += 1;
2254             }
2255         }
2256     }
2257
2258     // Add in the bounds that appear in the where-clause.
2259     for predicate in ast_generics.predicates {
2260         match predicate {
2261             hir::WherePredicate::BoundPredicate(bound_pred) => {
2262                 let ty = icx.to_ty(bound_pred.bounded_ty);
2263                 let bound_vars = icx.tcx.late_bound_vars(bound_pred.bounded_ty.hir_id);
2264
2265                 // Keep the type around in a dummy predicate, in case of no bounds.
2266                 // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
2267                 // is still checked for WF.
2268                 if bound_pred.bounds.is_empty() {
2269                     if let ty::Param(_) = ty.kind() {
2270                         // This is a `where T:`, which can be in the HIR from the
2271                         // transformation that moves `?Sized` to `T`'s declaration.
2272                         // We can skip the predicate because type parameters are
2273                         // trivially WF, but also we *should*, to avoid exposing
2274                         // users who never wrote `where Type:,` themselves, to
2275                         // compiler/tooling bugs from not handling WF predicates.
2276                     } else {
2277                         let span = bound_pred.bounded_ty.span;
2278                         let predicate = ty::Binder::bind_with_vars(
2279                             ty::PredicateKind::WellFormed(ty.into()),
2280                             bound_vars,
2281                         );
2282                         predicates.insert((predicate.to_predicate(tcx), span));
2283                     }
2284                 }
2285
2286                 let mut bounds = Bounds::default();
2287                 <dyn AstConv<'_>>::add_bounds(
2288                     &icx,
2289                     ty,
2290                     bound_pred.bounds.iter(),
2291                     &mut bounds,
2292                     bound_vars,
2293                 );
2294                 predicates.extend(bounds.predicates(tcx, ty));
2295             }
2296
2297             hir::WherePredicate::RegionPredicate(region_pred) => {
2298                 let r1 = <dyn AstConv<'_>>::ast_region_to_region(&icx, &region_pred.lifetime, None);
2299                 predicates.extend(region_pred.bounds.iter().map(|bound| {
2300                     let (r2, span) = match bound {
2301                         hir::GenericBound::Outlives(lt) => {
2302                             (<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.span)
2303                         }
2304                         _ => bug!(),
2305                     };
2306                     let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
2307                         ty::OutlivesPredicate(r1, r2),
2308                     ))
2309                     .to_predicate(icx.tcx);
2310
2311                     (pred, span)
2312                 }))
2313             }
2314
2315             hir::WherePredicate::EqPredicate(..) => {
2316                 // FIXME(#20041)
2317             }
2318         }
2319     }
2320
2321     if tcx.features().generic_const_exprs {
2322         predicates.extend(const_evaluatable_predicates_of(tcx, def_id.expect_local()));
2323     }
2324
2325     let mut predicates: Vec<_> = predicates.into_iter().collect();
2326
2327     // Subtle: before we store the predicates into the tcx, we
2328     // sort them so that predicates like `T: Foo<Item=U>` come
2329     // before uses of `U`.  This avoids false ambiguity errors
2330     // in trait checking. See `setup_constraining_predicates`
2331     // for details.
2332     if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
2333         let self_ty = tcx.type_of(def_id);
2334         let trait_ref = tcx.impl_trait_ref(def_id);
2335         cgp::setup_constraining_predicates(
2336             tcx,
2337             &mut predicates,
2338             trait_ref,
2339             &mut cgp::parameters_for_impl(self_ty, trait_ref),
2340         );
2341     }
2342
2343     let result = ty::GenericPredicates {
2344         parent: generics.parent,
2345         predicates: tcx.arena.alloc_from_iter(predicates),
2346     };
2347     debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result);
2348     result
2349 }
2350
2351 fn const_evaluatable_predicates_of<'tcx>(
2352     tcx: TyCtxt<'tcx>,
2353     def_id: LocalDefId,
2354 ) -> FxIndexSet<(ty::Predicate<'tcx>, Span)> {
2355     struct ConstCollector<'tcx> {
2356         tcx: TyCtxt<'tcx>,
2357         preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>,
2358     }
2359
2360     impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> {
2361         fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
2362             let def_id = self.tcx.hir().local_def_id(c.hir_id);
2363             let ct = ty::Const::from_anon_const(self.tcx, def_id);
2364             if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
2365                 assert_eq!(uv.promoted, None);
2366                 let span = self.tcx.hir().span(c.hir_id);
2367                 self.preds.insert((
2368                     ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
2369                         .to_predicate(self.tcx),
2370                     span,
2371                 ));
2372             }
2373         }
2374
2375         fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) {
2376             // Do not look into const param defaults,
2377             // these get checked when they are actually instantiated.
2378             //
2379             // We do not want the following to error:
2380             //
2381             //     struct Foo<const N: usize, const M: usize = { N + 1 }>;
2382             //     struct Bar<const N: usize>(Foo<N, 3>);
2383         }
2384     }
2385
2386     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2387     let node = tcx.hir().get(hir_id);
2388
2389     let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
2390     if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(ref impl_) = item.kind {
2391         if let Some(of_trait) = &impl_.of_trait {
2392             debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
2393             collector.visit_trait_ref(of_trait);
2394         }
2395
2396         debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id);
2397         collector.visit_ty(impl_.self_ty);
2398     }
2399
2400     if let Some(generics) = node.generics() {
2401         debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id);
2402         collector.visit_generics(generics);
2403     }
2404
2405     if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) {
2406         debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id);
2407         collector.visit_fn_decl(fn_sig.decl);
2408     }
2409     debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds);
2410
2411     collector.preds
2412 }
2413
2414 fn trait_explicit_predicates_and_bounds(
2415     tcx: TyCtxt<'_>,
2416     def_id: LocalDefId,
2417 ) -> ty::GenericPredicates<'_> {
2418     assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
2419     gather_explicit_predicates_of(tcx, def_id.to_def_id())
2420 }
2421
2422 fn explicit_predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2423     let def_kind = tcx.def_kind(def_id);
2424     if let DefKind::Trait = def_kind {
2425         // Remove bounds on associated types from the predicates, they will be
2426         // returned by `explicit_item_bounds`.
2427         let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local());
2428         let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
2429
2430         let is_assoc_item_ty = |ty: Ty<'tcx>| {
2431             // For a predicate from a where clause to become a bound on an
2432             // associated type:
2433             // * It must use the identity substs of the item.
2434             //     * Since any generic parameters on the item are not in scope,
2435             //       this means that the item is not a GAT, and its identity
2436             //       substs are the same as the trait's.
2437             // * It must be an associated type for this trait (*not* a
2438             //   supertrait).
2439             if let ty::Projection(projection) = ty.kind() {
2440                 projection.substs == trait_identity_substs
2441                     && tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id
2442             } else {
2443                 false
2444             }
2445         };
2446
2447         let predicates: Vec<_> = predicates_and_bounds
2448             .predicates
2449             .iter()
2450             .copied()
2451             .filter(|(pred, _)| match pred.kind().skip_binder() {
2452                 ty::PredicateKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
2453                 ty::PredicateKind::Projection(proj) => {
2454                     !is_assoc_item_ty(proj.projection_ty.self_ty())
2455                 }
2456                 ty::PredicateKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
2457                 _ => true,
2458             })
2459             .collect();
2460         if predicates.len() == predicates_and_bounds.predicates.len() {
2461             predicates_and_bounds
2462         } else {
2463             ty::GenericPredicates {
2464                 parent: predicates_and_bounds.parent,
2465                 predicates: tcx.arena.alloc_slice(&predicates),
2466             }
2467         }
2468     } else {
2469         if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
2470             let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
2471             if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() {
2472                 // In `generics_of` we set the generics' parent to be our parent's parent which means that
2473                 // we lose out on the predicates of our actual parent if we dont return those predicates here.
2474                 // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
2475                 //
2476                 // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
2477                 //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
2478                 //        ^^^                                             explicit_predicates_of on
2479                 //        parent item we dont have set as the
2480                 //        parent of generics returned by `generics_of`
2481                 //
2482                 // In the above code we want the anon const to have predicates in its param env for `T: Trait`
2483                 let item_def_id = tcx.hir().get_parent_item(hir_id);
2484                 // In the above code example we would be calling `explicit_predicates_of(Foo)` here
2485                 return tcx.explicit_predicates_of(item_def_id);
2486             }
2487         }
2488         gather_explicit_predicates_of(tcx, def_id)
2489     }
2490 }
2491
2492 /// Converts a specific `GenericBound` from the AST into a set of
2493 /// predicates that apply to the self type. A vector is returned
2494 /// because this can be anywhere from zero predicates (`T: ?Sized` adds no
2495 /// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar`
2496 /// and `<T as Bar>::X == i32`).
2497 fn predicates_from_bound<'tcx>(
2498     astconv: &dyn AstConv<'tcx>,
2499     param_ty: Ty<'tcx>,
2500     bound: &'tcx hir::GenericBound<'tcx>,
2501     bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
2502 ) -> Vec<(ty::Predicate<'tcx>, Span)> {
2503     let mut bounds = Bounds::default();
2504     astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
2505     bounds.predicates(astconv.tcx(), param_ty).collect()
2506 }
2507
2508 fn compute_sig_of_foreign_fn_decl<'tcx>(
2509     tcx: TyCtxt<'tcx>,
2510     def_id: DefId,
2511     decl: &'tcx hir::FnDecl<'tcx>,
2512     abi: abi::Abi,
2513 ) -> ty::PolyFnSig<'tcx> {
2514     let unsafety = if abi == abi::Abi::RustIntrinsic {
2515         intrinsic_operation_unsafety(tcx.item_name(def_id))
2516     } else {
2517         hir::Unsafety::Unsafe
2518     };
2519     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
2520     let fty = <dyn AstConv<'_>>::ty_of_fn(
2521         &ItemCtxt::new(tcx, def_id),
2522         hir_id,
2523         unsafety,
2524         abi,
2525         decl,
2526         None,
2527         None,
2528     );
2529
2530     // Feature gate SIMD types in FFI, since I am not sure that the
2531     // ABIs are handled at all correctly. -huonw
2532     if abi != abi::Abi::RustIntrinsic
2533         && abi != abi::Abi::PlatformIntrinsic
2534         && !tcx.features().simd_ffi
2535     {
2536         let check = |ast_ty: &hir::Ty<'_>, ty: Ty<'_>| {
2537             if ty.is_simd() {
2538                 let snip = tcx
2539                     .sess
2540                     .source_map()
2541                     .span_to_snippet(ast_ty.span)
2542                     .map_or_else(|_| String::new(), |s| format!(" `{}`", s));
2543                 tcx.sess
2544                     .struct_span_err(
2545                         ast_ty.span,
2546                         &format!(
2547                             "use of SIMD type{} in FFI is highly experimental and \
2548                              may result in invalid code",
2549                             snip
2550                         ),
2551                     )
2552                     .help("add `#![feature(simd_ffi)]` to the crate attributes to enable")
2553                     .emit();
2554             }
2555         };
2556         for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
2557             check(input, *ty)
2558         }
2559         if let hir::FnRetTy::Return(ref ty) = decl.output {
2560             check(ty, fty.output().skip_binder())
2561         }
2562     }
2563
2564     fty
2565 }
2566
2567 fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
2568     match tcx.hir().get_if_local(def_id) {
2569         Some(Node::ForeignItem(..)) => true,
2570         Some(_) => false,
2571         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id),
2572     }
2573 }
2574
2575 fn generator_kind(tcx: TyCtxt<'_>, def_id: DefId) -> Option<hir::GeneratorKind> {
2576     match tcx.hir().get_if_local(def_id) {
2577         Some(Node::Expr(&rustc_hir::Expr {
2578             kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }),
2579             ..
2580         })) => tcx.hir().body(body).generator_kind(),
2581         Some(_) => None,
2582         _ => bug!("generator_kind applied to non-local def-id {:?}", def_id),
2583     }
2584 }
2585
2586 fn from_target_feature(
2587     tcx: TyCtxt<'_>,
2588     attr: &ast::Attribute,
2589     supported_target_features: &FxHashMap<String, Option<Symbol>>,
2590     target_features: &mut Vec<Symbol>,
2591 ) {
2592     let Some(list) = attr.meta_item_list() else { return };
2593     let bad_item = |span| {
2594         let msg = "malformed `target_feature` attribute input";
2595         let code = "enable = \"..\"";
2596         tcx.sess
2597             .struct_span_err(span, msg)
2598             .span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders)
2599             .emit();
2600     };
2601     let rust_features = tcx.features();
2602     for item in list {
2603         // Only `enable = ...` is accepted in the meta-item list.
2604         if !item.has_name(sym::enable) {
2605             bad_item(item.span());
2606             continue;
2607         }
2608
2609         // Must be of the form `enable = "..."` (a string).
2610         let Some(value) = item.value_str() else {
2611             bad_item(item.span());
2612             continue;
2613         };
2614
2615         // We allow comma separation to enable multiple features.
2616         target_features.extend(value.as_str().split(',').filter_map(|feature| {
2617             let Some(feature_gate) = supported_target_features.get(feature) else {
2618                 let msg =
2619                     format!("the feature named `{}` is not valid for this target", feature);
2620                 let mut err = tcx.sess.struct_span_err(item.span(), &msg);
2621                 err.span_label(
2622                     item.span(),
2623                     format!("`{}` is not valid for this target", feature),
2624                 );
2625                 if let Some(stripped) = feature.strip_prefix('+') {
2626                     let valid = supported_target_features.contains_key(stripped);
2627                     if valid {
2628                         err.help("consider removing the leading `+` in the feature name");
2629                     }
2630                 }
2631                 err.emit();
2632                 return None;
2633             };
2634
2635             // Only allow features whose feature gates have been enabled.
2636             let allowed = match feature_gate.as_ref().copied() {
2637                 Some(sym::arm_target_feature) => rust_features.arm_target_feature,
2638                 Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature,
2639                 Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature,
2640                 Some(sym::mips_target_feature) => rust_features.mips_target_feature,
2641                 Some(sym::riscv_target_feature) => rust_features.riscv_target_feature,
2642                 Some(sym::avx512_target_feature) => rust_features.avx512_target_feature,
2643                 Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature,
2644                 Some(sym::tbm_target_feature) => rust_features.tbm_target_feature,
2645                 Some(sym::wasm_target_feature) => rust_features.wasm_target_feature,
2646                 Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature,
2647                 Some(sym::movbe_target_feature) => rust_features.movbe_target_feature,
2648                 Some(sym::rtm_target_feature) => rust_features.rtm_target_feature,
2649                 Some(sym::f16c_target_feature) => rust_features.f16c_target_feature,
2650                 Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature,
2651                 Some(sym::bpf_target_feature) => rust_features.bpf_target_feature,
2652                 Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature,
2653                 Some(name) => bug!("unknown target feature gate {}", name),
2654                 None => true,
2655             };
2656             if !allowed {
2657                 feature_err(
2658                     &tcx.sess.parse_sess,
2659                     feature_gate.unwrap(),
2660                     item.span(),
2661                     &format!("the target feature `{}` is currently unstable", feature),
2662                 )
2663                 .emit();
2664             }
2665             Some(Symbol::intern(feature))
2666         }));
2667     }
2668 }
2669
2670 fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
2671     use rustc_middle::mir::mono::Linkage::*;
2672
2673     // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
2674     // applicable to variable declarations and may not really make sense for
2675     // Rust code in the first place but allow them anyway and trust that the
2676     // user knows what they're doing. Who knows, unanticipated use cases may pop
2677     // up in the future.
2678     //
2679     // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
2680     // and don't have to be, LLVM treats them as no-ops.
2681     match name {
2682         "appending" => Appending,
2683         "available_externally" => AvailableExternally,
2684         "common" => Common,
2685         "extern_weak" => ExternalWeak,
2686         "external" => External,
2687         "internal" => Internal,
2688         "linkonce" => LinkOnceAny,
2689         "linkonce_odr" => LinkOnceODR,
2690         "private" => Private,
2691         "weak" => WeakAny,
2692         "weak_odr" => WeakODR,
2693         _ => tcx.sess.span_fatal(tcx.def_span(def_id), "invalid linkage specified"),
2694     }
2695 }
2696
2697 fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
2698     if cfg!(debug_assertions) {
2699         let def_kind = tcx.def_kind(did);
2700         assert!(
2701             def_kind.has_codegen_attrs(),
2702             "unexpected `def_kind` in `codegen_fn_attrs`: {def_kind:?}",
2703         );
2704     }
2705
2706     let did = did.expect_local();
2707     let attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(did));
2708     let mut codegen_fn_attrs = CodegenFnAttrs::new();
2709     if tcx.should_inherit_track_caller(did) {
2710         codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
2711     }
2712
2713     // The panic_no_unwind function called by TerminatorKind::Abort will never
2714     // unwind. If the panic handler that it invokes unwind then it will simply
2715     // call the panic handler again.
2716     if Some(did.to_def_id()) == tcx.lang_items().panic_no_unwind() {
2717         codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
2718     }
2719
2720     let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
2721
2722     let mut inline_span = None;
2723     let mut link_ordinal_span = None;
2724     let mut no_sanitize_span = None;
2725     for attr in attrs.iter() {
2726         if attr.has_name(sym::cold) {
2727             codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
2728         } else if attr.has_name(sym::rustc_allocator) {
2729             codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
2730         } else if attr.has_name(sym::ffi_returns_twice) {
2731             if tcx.is_foreign_item(did) {
2732                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE;
2733             } else {
2734                 // `#[ffi_returns_twice]` is only allowed `extern fn`s.
2735                 struct_span_err!(
2736                     tcx.sess,
2737                     attr.span,
2738                     E0724,
2739                     "`#[ffi_returns_twice]` may only be used on foreign functions"
2740                 )
2741                 .emit();
2742             }
2743         } else if attr.has_name(sym::ffi_pure) {
2744             if tcx.is_foreign_item(did) {
2745                 if attrs.iter().any(|a| a.has_name(sym::ffi_const)) {
2746                     // `#[ffi_const]` functions cannot be `#[ffi_pure]`
2747                     struct_span_err!(
2748                         tcx.sess,
2749                         attr.span,
2750                         E0757,
2751                         "`#[ffi_const]` function cannot be `#[ffi_pure]`"
2752                     )
2753                     .emit();
2754                 } else {
2755                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE;
2756                 }
2757             } else {
2758                 // `#[ffi_pure]` is only allowed on foreign functions
2759                 struct_span_err!(
2760                     tcx.sess,
2761                     attr.span,
2762                     E0755,
2763                     "`#[ffi_pure]` may only be used on foreign functions"
2764                 )
2765                 .emit();
2766             }
2767         } else if attr.has_name(sym::ffi_const) {
2768             if tcx.is_foreign_item(did) {
2769                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST;
2770             } else {
2771                 // `#[ffi_const]` is only allowed on foreign functions
2772                 struct_span_err!(
2773                     tcx.sess,
2774                     attr.span,
2775                     E0756,
2776                     "`#[ffi_const]` may only be used on foreign functions"
2777                 )
2778                 .emit();
2779             }
2780         } else if attr.has_name(sym::rustc_allocator_nounwind) {
2781             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
2782         } else if attr.has_name(sym::rustc_reallocator) {
2783             codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR;
2784         } else if attr.has_name(sym::rustc_deallocator) {
2785             codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR;
2786         } else if attr.has_name(sym::rustc_allocator_zeroed) {
2787             codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED;
2788         } else if attr.has_name(sym::naked) {
2789             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
2790         } else if attr.has_name(sym::no_mangle) {
2791             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
2792         } else if attr.has_name(sym::no_coverage) {
2793             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
2794         } else if attr.has_name(sym::rustc_std_internal_symbol) {
2795             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
2796         } else if attr.has_name(sym::used) {
2797             let inner = attr.meta_item_list();
2798             match inner.as_deref() {
2799                 Some([item]) if item.has_name(sym::linker) => {
2800                     if !tcx.features().used_with_arg {
2801                         feature_err(
2802                             &tcx.sess.parse_sess,
2803                             sym::used_with_arg,
2804                             attr.span,
2805                             "`#[used(linker)]` is currently unstable",
2806                         )
2807                         .emit();
2808                     }
2809                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER;
2810                 }
2811                 Some([item]) if item.has_name(sym::compiler) => {
2812                     if !tcx.features().used_with_arg {
2813                         feature_err(
2814                             &tcx.sess.parse_sess,
2815                             sym::used_with_arg,
2816                             attr.span,
2817                             "`#[used(compiler)]` is currently unstable",
2818                         )
2819                         .emit();
2820                     }
2821                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
2822                 }
2823                 Some(_) => {
2824                     tcx.sess
2825                         .struct_span_err(
2826                             attr.span,
2827                             "expected `used`, `used(compiler)` or `used(linker)`",
2828                         )
2829                         .emit();
2830                 }
2831                 None => {
2832                     // Unfortunately, unconditionally using `llvm.used` causes
2833                     // issues in handling `.init_array` with the gold linker,
2834                     // but using `llvm.compiler.used` caused a nontrival amount
2835                     // of unintentional ecosystem breakage -- particularly on
2836                     // Mach-O targets.
2837                     //
2838                     // As a result, we emit `llvm.compiler.used` only on ELF
2839                     // targets. This is somewhat ad-hoc, but actually follows
2840                     // our pre-LLVM 13 behavior (prior to the ecosystem
2841                     // breakage), and seems to match `clang`'s behavior as well
2842                     // (both before and after LLVM 13), possibly because they
2843                     // have similar compatibility concerns to us. See
2844                     // https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146
2845                     // and following comments for some discussion of this, as
2846                     // well as the comments in `rustc_codegen_llvm` where these
2847                     // flags are handled.
2848                     //
2849                     // Anyway, to be clear: this is still up in the air
2850                     // somewhat, and is subject to change in the future (which
2851                     // is a good thing, because this would ideally be a bit
2852                     // more firmed up).
2853                     let is_like_elf = !(tcx.sess.target.is_like_osx
2854                         || tcx.sess.target.is_like_windows
2855                         || tcx.sess.target.is_like_wasm);
2856                     codegen_fn_attrs.flags |= if is_like_elf {
2857                         CodegenFnAttrFlags::USED
2858                     } else {
2859                         CodegenFnAttrFlags::USED_LINKER
2860                     };
2861                 }
2862             }
2863         } else if attr.has_name(sym::cmse_nonsecure_entry) {
2864             if !matches!(tcx.fn_sig(did).abi(), abi::Abi::C { .. }) {
2865                 struct_span_err!(
2866                     tcx.sess,
2867                     attr.span,
2868                     E0776,
2869                     "`#[cmse_nonsecure_entry]` requires C ABI"
2870                 )
2871                 .emit();
2872             }
2873             if !tcx.sess.target.llvm_target.contains("thumbv8m") {
2874                 struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension")
2875                     .emit();
2876             }
2877             codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY;
2878         } else if attr.has_name(sym::thread_local) {
2879             codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
2880         } else if attr.has_name(sym::track_caller) {
2881             if !tcx.is_closure(did.to_def_id()) && tcx.fn_sig(did).abi() != abi::Abi::Rust {
2882                 struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
2883                     .emit();
2884             }
2885             if tcx.is_closure(did.to_def_id()) && !tcx.features().closure_track_caller {
2886                 feature_err(
2887                     &tcx.sess.parse_sess,
2888                     sym::closure_track_caller,
2889                     attr.span,
2890                     "`#[track_caller]` on closures is currently unstable",
2891                 )
2892                 .emit();
2893             }
2894             codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
2895         } else if attr.has_name(sym::export_name) {
2896             if let Some(s) = attr.value_str() {
2897                 if s.as_str().contains('\0') {
2898                     // `#[export_name = ...]` will be converted to a null-terminated string,
2899                     // so it may not contain any null characters.
2900                     struct_span_err!(
2901                         tcx.sess,
2902                         attr.span,
2903                         E0648,
2904                         "`export_name` may not contain null characters"
2905                     )
2906                     .emit();
2907                 }
2908                 codegen_fn_attrs.export_name = Some(s);
2909             }
2910         } else if attr.has_name(sym::target_feature) {
2911             if !tcx.is_closure(did.to_def_id())
2912                 && tcx.fn_sig(did).unsafety() == hir::Unsafety::Normal
2913             {
2914                 if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
2915                     // The `#[target_feature]` attribute is allowed on
2916                     // WebAssembly targets on all functions, including safe
2917                     // ones. Other targets require that `#[target_feature]` is
2918                     // only applied to unsafe functions (pending the
2919                     // `target_feature_11` feature) because on most targets
2920                     // execution of instructions that are not supported is
2921                     // considered undefined behavior. For WebAssembly which is a
2922                     // 100% safe target at execution time it's not possible to
2923                     // execute undefined instructions, and even if a future
2924                     // feature was added in some form for this it would be a
2925                     // deterministic trap. There is no undefined behavior when
2926                     // executing WebAssembly so `#[target_feature]` is allowed
2927                     // on safe functions (but again, only for WebAssembly)
2928                     //
2929                     // Note that this is also allowed if `actually_rustdoc` so
2930                     // if a target is documenting some wasm-specific code then
2931                     // it's not spuriously denied.
2932                 } else if !tcx.features().target_feature_11 {
2933                     let mut err = feature_err(
2934                         &tcx.sess.parse_sess,
2935                         sym::target_feature_11,
2936                         attr.span,
2937                         "`#[target_feature(..)]` can only be applied to `unsafe` functions",
2938                     );
2939                     err.span_label(tcx.def_span(did), "not an `unsafe` function");
2940                     err.emit();
2941                 } else {
2942                     check_target_feature_trait_unsafe(tcx, did, attr.span);
2943                 }
2944             }
2945             from_target_feature(
2946                 tcx,
2947                 attr,
2948                 supported_target_features,
2949                 &mut codegen_fn_attrs.target_features,
2950             );
2951         } else if attr.has_name(sym::linkage) {
2952             if let Some(val) = attr.value_str() {
2953                 codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, did, val.as_str()));
2954             }
2955         } else if attr.has_name(sym::link_section) {
2956             if let Some(val) = attr.value_str() {
2957                 if val.as_str().bytes().any(|b| b == 0) {
2958                     let msg = format!(
2959                         "illegal null byte in link_section \
2960                          value: `{}`",
2961                         &val
2962                     );
2963                     tcx.sess.span_err(attr.span, &msg);
2964                 } else {
2965                     codegen_fn_attrs.link_section = Some(val);
2966                 }
2967             }
2968         } else if attr.has_name(sym::link_name) {
2969             codegen_fn_attrs.link_name = attr.value_str();
2970         } else if attr.has_name(sym::link_ordinal) {
2971             link_ordinal_span = Some(attr.span);
2972             if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
2973                 codegen_fn_attrs.link_ordinal = ordinal;
2974             }
2975         } else if attr.has_name(sym::no_sanitize) {
2976             no_sanitize_span = Some(attr.span);
2977             if let Some(list) = attr.meta_item_list() {
2978                 for item in list.iter() {
2979                     if item.has_name(sym::address) {
2980                         codegen_fn_attrs.no_sanitize |= SanitizerSet::ADDRESS;
2981                     } else if item.has_name(sym::cfi) {
2982                         codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI;
2983                     } else if item.has_name(sym::memory) {
2984                         codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY;
2985                     } else if item.has_name(sym::memtag) {
2986                         codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG;
2987                     } else if item.has_name(sym::shadow_call_stack) {
2988                         codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK;
2989                     } else if item.has_name(sym::thread) {
2990                         codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD;
2991                     } else if item.has_name(sym::hwaddress) {
2992                         codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS;
2993                     } else {
2994                         tcx.sess
2995                             .struct_span_err(item.span(), "invalid argument for `no_sanitize`")
2996                             .note("expected one of: `address`, `cfi`, `hwaddress`, `memory`, `memtag`, `shadow-call-stack`, or `thread`")
2997                             .emit();
2998                     }
2999                 }
3000             }
3001         } else if attr.has_name(sym::instruction_set) {
3002             codegen_fn_attrs.instruction_set = match attr.meta_kind() {
3003                 Some(MetaItemKind::List(ref items)) => match items.as_slice() {
3004                     [NestedMetaItem::MetaItem(set)] => {
3005                         let segments =
3006                             set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
3007                         match segments.as_slice() {
3008                             [sym::arm, sym::a32] | [sym::arm, sym::t32] => {
3009                                 if !tcx.sess.target.has_thumb_interworking {
3010                                     struct_span_err!(
3011                                         tcx.sess.diagnostic(),
3012                                         attr.span,
3013                                         E0779,
3014                                         "target does not support `#[instruction_set]`"
3015                                     )
3016                                     .emit();
3017                                     None
3018                                 } else if segments[1] == sym::a32 {
3019                                     Some(InstructionSetAttr::ArmA32)
3020                                 } else if segments[1] == sym::t32 {
3021                                     Some(InstructionSetAttr::ArmT32)
3022                                 } else {
3023                                     unreachable!()
3024                                 }
3025                             }
3026                             _ => {
3027                                 struct_span_err!(
3028                                     tcx.sess.diagnostic(),
3029                                     attr.span,
3030                                     E0779,
3031                                     "invalid instruction set specified",
3032                                 )
3033                                 .emit();
3034                                 None
3035                             }
3036                         }
3037                     }
3038                     [] => {
3039                         struct_span_err!(
3040                             tcx.sess.diagnostic(),
3041                             attr.span,
3042                             E0778,
3043                             "`#[instruction_set]` requires an argument"
3044                         )
3045                         .emit();
3046                         None
3047                     }
3048                     _ => {
3049                         struct_span_err!(
3050                             tcx.sess.diagnostic(),
3051                             attr.span,
3052                             E0779,
3053                             "cannot specify more than one instruction set"
3054                         )
3055                         .emit();
3056                         None
3057                     }
3058                 },
3059                 _ => {
3060                     struct_span_err!(
3061                         tcx.sess.diagnostic(),
3062                         attr.span,
3063                         E0778,
3064                         "must specify an instruction set"
3065                     )
3066                     .emit();
3067                     None
3068                 }
3069             };
3070         } else if attr.has_name(sym::repr) {
3071             codegen_fn_attrs.alignment = match attr.meta_item_list() {
3072                 Some(items) => match items.as_slice() {
3073                     [item] => match item.name_value_literal() {
3074                         Some((sym::align, literal)) => {
3075                             let alignment = rustc_attr::parse_alignment(&literal.kind);
3076
3077                             match alignment {
3078                                 Ok(align) => Some(align),
3079                                 Err(msg) => {
3080                                     struct_span_err!(
3081                                         tcx.sess.diagnostic(),
3082                                         attr.span,
3083                                         E0589,
3084                                         "invalid `repr(align)` attribute: {}",
3085                                         msg
3086                                     )
3087                                     .emit();
3088
3089                                     None
3090                                 }
3091                             }
3092                         }
3093                         _ => None,
3094                     },
3095                     [] => None,
3096                     _ => None,
3097                 },
3098                 None => None,
3099             };
3100         }
3101     }
3102
3103     codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
3104         if !attr.has_name(sym::inline) {
3105             return ia;
3106         }
3107         match attr.meta_kind() {
3108             Some(MetaItemKind::Word) => InlineAttr::Hint,
3109             Some(MetaItemKind::List(ref items)) => {
3110                 inline_span = Some(attr.span);
3111                 if items.len() != 1 {
3112                     struct_span_err!(
3113                         tcx.sess.diagnostic(),
3114                         attr.span,
3115                         E0534,
3116                         "expected one argument"
3117                     )
3118                     .emit();
3119                     InlineAttr::None
3120                 } else if list_contains_name(&items, sym::always) {
3121                     InlineAttr::Always
3122                 } else if list_contains_name(&items, sym::never) {
3123                     InlineAttr::Never
3124                 } else {
3125                     struct_span_err!(
3126                         tcx.sess.diagnostic(),
3127                         items[0].span(),
3128                         E0535,
3129                         "invalid argument"
3130                     )
3131                     .emit();
3132
3133                     InlineAttr::None
3134                 }
3135             }
3136             Some(MetaItemKind::NameValue(_)) => ia,
3137             None => ia,
3138         }
3139     });
3140
3141     codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
3142         if !attr.has_name(sym::optimize) {
3143             return ia;
3144         }
3145         let err = |sp, s| struct_span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s).emit();
3146         match attr.meta_kind() {
3147             Some(MetaItemKind::Word) => {
3148                 err(attr.span, "expected one argument");
3149                 ia
3150             }
3151             Some(MetaItemKind::List(ref items)) => {
3152                 inline_span = Some(attr.span);
3153                 if items.len() != 1 {
3154                     err(attr.span, "expected one argument");
3155                     OptimizeAttr::None
3156                 } else if list_contains_name(&items, sym::size) {
3157                     OptimizeAttr::Size
3158                 } else if list_contains_name(&items, sym::speed) {
3159                     OptimizeAttr::Speed
3160                 } else {
3161                     err(items[0].span(), "invalid argument");
3162                     OptimizeAttr::None
3163                 }
3164             }
3165             Some(MetaItemKind::NameValue(_)) => ia,
3166             None => ia,
3167         }
3168     });
3169
3170     // #73631: closures inherit `#[target_feature]` annotations
3171     if tcx.features().target_feature_11 && tcx.is_closure(did.to_def_id()) {
3172         let owner_id = tcx.parent(did.to_def_id());
3173         if tcx.def_kind(owner_id).has_codegen_attrs() {
3174             codegen_fn_attrs
3175                 .target_features
3176                 .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied());
3177         }
3178     }
3179
3180     // If a function uses #[target_feature] it can't be inlined into general
3181     // purpose functions as they wouldn't have the right target features
3182     // enabled. For that reason we also forbid #[inline(always)] as it can't be
3183     // respected.
3184     if !codegen_fn_attrs.target_features.is_empty() {
3185         if codegen_fn_attrs.inline == InlineAttr::Always {
3186             if let Some(span) = inline_span {
3187                 tcx.sess.span_err(
3188                     span,
3189                     "cannot use `#[inline(always)]` with \
3190                      `#[target_feature]`",
3191                 );
3192             }
3193         }
3194     }
3195
3196     if !codegen_fn_attrs.no_sanitize.is_empty() {
3197         if codegen_fn_attrs.inline == InlineAttr::Always {
3198             if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
3199                 let hir_id = tcx.hir().local_def_id_to_hir_id(did);
3200                 tcx.struct_span_lint_hir(
3201                     lint::builtin::INLINE_NO_SANITIZE,
3202                     hir_id,
3203                     no_sanitize_span,
3204                     |lint| {
3205                         lint.build("`no_sanitize` will have no effect after inlining")
3206                             .span_note(inline_span, "inlining requested here")
3207                             .emit();
3208                     },
3209                 )
3210             }
3211         }
3212     }
3213
3214     // Weak lang items have the same semantics as "std internal" symbols in the
3215     // sense that they're preserved through all our LTO passes and only
3216     // strippable by the linker.
3217     //
3218     // Additionally weak lang items have predetermined symbol names.
3219     if tcx.is_weak_lang_item(did.to_def_id()) {
3220         codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
3221     }
3222     if let Some(name) = weak_lang_items::link_name(attrs) {
3223         codegen_fn_attrs.export_name = Some(name);
3224         codegen_fn_attrs.link_name = Some(name);
3225     }
3226     check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span);
3227
3228     // Internal symbols to the standard library all have no_mangle semantics in
3229     // that they have defined symbol names present in the function name. This
3230     // also applies to weak symbols where they all have known symbol names.
3231     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
3232         codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
3233     }
3234
3235     // Any linkage to LLVM intrinsics for now forcibly marks them all as never
3236     // unwinds since LLVM sometimes can't handle codegen which `invoke`s
3237     // intrinsic functions.
3238     if let Some(name) = &codegen_fn_attrs.link_name {
3239         if name.as_str().starts_with("llvm.") {
3240             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
3241         }
3242     }
3243
3244     codegen_fn_attrs
3245 }
3246
3247 /// Computes the set of target features used in a function for the purposes of
3248 /// inline assembly.
3249 fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx FxHashSet<Symbol> {
3250     let mut target_features = tcx.sess.unstable_target_features.clone();
3251     if tcx.def_kind(did).has_codegen_attrs() {
3252         let attrs = tcx.codegen_fn_attrs(did);
3253         target_features.extend(&attrs.target_features);
3254         match attrs.instruction_set {
3255             None => {}
3256             Some(InstructionSetAttr::ArmA32) => {
3257                 target_features.remove(&sym::thumb_mode);
3258             }
3259             Some(InstructionSetAttr::ArmT32) => {
3260                 target_features.insert(sym::thumb_mode);
3261             }
3262         }
3263     }
3264
3265     tcx.arena.alloc(target_features)
3266 }
3267
3268 /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
3269 /// applied to the method prototype.
3270 fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
3271     if let Some(impl_item) = tcx.opt_associated_item(def_id)
3272         && let ty::AssocItemContainer::ImplContainer = impl_item.container
3273         && let Some(trait_item) = impl_item.trait_item_def_id
3274     {
3275         return tcx
3276             .codegen_fn_attrs(trait_item)
3277             .flags
3278             .intersects(CodegenFnAttrFlags::TRACK_CALLER);
3279     }
3280
3281     false
3282 }
3283
3284 fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
3285     use rustc_ast::{Lit, LitIntType, LitKind};
3286     let meta_item_list = attr.meta_item_list();
3287     let meta_item_list: Option<&[ast::NestedMetaItem]> = meta_item_list.as_ref().map(Vec::as_ref);
3288     let sole_meta_list = match meta_item_list {
3289         Some([item]) => item.literal(),
3290         Some(_) => {
3291             tcx.sess
3292                 .struct_span_err(attr.span, "incorrect number of arguments to `#[link_ordinal]`")
3293                 .note("the attribute requires exactly one argument")
3294                 .emit();
3295             return None;
3296         }
3297         _ => None,
3298     };
3299     if let Some(Lit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = sole_meta_list {
3300         // According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
3301         // the ordinal must fit into 16 bits.  Similarly, the Ordinal field in COFFShortExport (defined
3302         // in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
3303         // to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
3304         //
3305         // FIXME: should we allow an ordinal of 0?  The MSVC toolchain has inconsistent support for this:
3306         // both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies
3307         // a zero ordinal.  However, llvm-dlltool is perfectly happy to generate an import library
3308         // for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import
3309         // library produced by LLVM with an ordinal of 0, and it generates an .EXE.  (I don't know yet
3310         // if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
3311         // about LINK.EXE failing.)
3312         if *ordinal <= u16::MAX as u128 {
3313             Some(*ordinal as u16)
3314         } else {
3315             let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
3316             tcx.sess
3317                 .struct_span_err(attr.span, &msg)
3318                 .note("the value may not exceed `u16::MAX`")
3319                 .emit();
3320             None
3321         }
3322     } else {
3323         tcx.sess
3324             .struct_span_err(attr.span, "illegal ordinal format in `link_ordinal`")
3325             .note("an unsuffixed integer value, e.g., `1`, is expected")
3326             .emit();
3327         None
3328     }
3329 }
3330
3331 fn check_link_name_xor_ordinal(
3332     tcx: TyCtxt<'_>,
3333     codegen_fn_attrs: &CodegenFnAttrs,
3334     inline_span: Option<Span>,
3335 ) {
3336     if codegen_fn_attrs.link_name.is_none() || codegen_fn_attrs.link_ordinal.is_none() {
3337         return;
3338     }
3339     let msg = "cannot use `#[link_name]` with `#[link_ordinal]`";
3340     if let Some(span) = inline_span {
3341         tcx.sess.span_err(span, msg);
3342     } else {
3343         tcx.sess.err(msg);
3344     }
3345 }
3346
3347 /// Checks the function annotated with `#[target_feature]` is not a safe
3348 /// trait method implementation, reporting an error if it is.
3349 fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
3350     let hir_id = tcx.hir().local_def_id_to_hir_id(id);
3351     let node = tcx.hir().get(hir_id);
3352     if let Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) = node {
3353         let parent_id = tcx.hir().get_parent_item(hir_id);
3354         let parent_item = tcx.hir().expect_item(parent_id);
3355         if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = parent_item.kind {
3356             tcx.sess
3357                 .struct_span_err(
3358                     attr_span,
3359                     "`#[target_feature(..)]` cannot be applied to safe trait method",
3360                 )
3361                 .span_label(attr_span, "cannot be applied to safe trait method")
3362                 .span_label(tcx.def_span(id), "not an `unsafe` function")
3363                 .emit();
3364         }
3365     }
3366 }