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