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