]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/collect.rs
Store `Ident` rather than just `Name` in HIR types `Item` and `ForeignItem`.
[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 *interprocedural* 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 astconv::{AstConv, Bounds};
18 use constrained_type_params as ctp;
19 use lint;
20 use middle::lang_items::SizedTraitLangItem;
21 use middle::resolve_lifetime as rl;
22 use middle::weak_lang_items;
23 use rustc::mir::mono::Linkage;
24 use rustc::ty::query::Providers;
25 use rustc::ty::subst::Substs;
26 use rustc::ty::util::Discr;
27 use rustc::ty::util::IntTypeExt;
28 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
29 use rustc::ty::{ReprOptions, ToPredicate};
30 use rustc::util::captures::Captures;
31 use rustc::util::nodemap::FxHashMap;
32 use rustc_data_structures::sync::Lrc;
33 use rustc_target::spec::abi;
34
35 use syntax::ast;
36 use syntax::ast::{Ident, MetaItemKind};
37 use syntax::attr::{InlineAttr, list_contains_name, mark_used};
38 use syntax::source_map::Spanned;
39 use syntax::feature_gate;
40 use syntax::symbol::{keywords, Symbol};
41 use syntax_pos::{Span, DUMMY_SP};
42
43 use rustc::hir::def::{CtorKind, Def};
44 use rustc::hir::Node;
45 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
46 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
47 use rustc::hir::GenericParamKind;
48 use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
49
50 use std::iter;
51
52 struct OnlySelfBounds(bool);
53
54 ///////////////////////////////////////////////////////////////////////////
55 // Main entry point
56
57 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
58     let mut visitor = CollectItemTypesVisitor { tcx };
59     tcx.hir()
60        .krate()
61        .visit_all_item_likes(&mut visitor.as_deep_visitor());
62 }
63
64 pub fn provide(providers: &mut Providers) {
65     *providers = Providers {
66         type_of,
67         generics_of,
68         predicates_of,
69         predicates_defined_on,
70         explicit_predicates_of,
71         super_predicates_of,
72         type_param_predicates,
73         trait_def,
74         adt_def,
75         fn_sig,
76         impl_trait_ref,
77         impl_polarity,
78         is_foreign_item,
79         codegen_fn_attrs,
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<'a, 'tcx: 'a> {
96     tcx: TyCtxt<'a, 'tcx, 'tcx>,
97     item_def_id: DefId,
98 }
99
100 ///////////////////////////////////////////////////////////////////////////
101
102 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
103     tcx: TyCtxt<'a, 'tcx, 'tcx>,
104 }
105
106 impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
107     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
108         NestedVisitorMap::OnlyBodies(&self.tcx.hir())
109     }
110
111     fn visit_item(&mut self, item: &'tcx hir::Item) {
112         convert_item(self.tcx, item.id);
113         intravisit::walk_item(self, item);
114     }
115
116     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
117         for param in &generics.params {
118             match param.kind {
119                 hir::GenericParamKind::Lifetime { .. } => {}
120                 hir::GenericParamKind::Type {
121                     default: Some(_), ..
122                 } => {
123                     let def_id = self.tcx.hir().local_def_id(param.id);
124                     self.tcx.type_of(def_id);
125                 }
126                 hir::GenericParamKind::Type { .. } => {}
127             }
128         }
129         intravisit::walk_generics(self, generics);
130     }
131
132     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
133         if let hir::ExprKind::Closure(..) = expr.node {
134             let def_id = self.tcx.hir().local_def_id(expr.id);
135             self.tcx.generics_of(def_id);
136             self.tcx.type_of(def_id);
137         }
138         intravisit::walk_expr(self, expr);
139     }
140
141     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
142         convert_trait_item(self.tcx, trait_item.id);
143         intravisit::walk_trait_item(self, trait_item);
144     }
145
146     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
147         convert_impl_item(self.tcx, impl_item.id);
148         intravisit::walk_impl_item(self, impl_item);
149     }
150 }
151
152 ///////////////////////////////////////////////////////////////////////////
153 // Utility types and common code for the above passes.
154
155 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
156     pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) -> ItemCtxt<'a, 'tcx> {
157         ItemCtxt { tcx, item_def_id }
158     }
159 }
160
161 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
162     pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
163         AstConv::ast_ty_to_ty(self, ast_ty)
164     }
165 }
166
167 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
168     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
169         self.tcx
170     }
171
172     fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
173                                  -> Lrc<ty::GenericPredicates<'tcx>> {
174         self.tcx
175             .at(span)
176             .type_param_predicates((self.item_def_id, def_id))
177     }
178
179     fn re_infer(
180         &self,
181         _span: Span,
182         _def: Option<&ty::GenericParamDef>,
183     ) -> Option<ty::Region<'tcx>> {
184         None
185     }
186
187     fn ty_infer(&self, span: Span) -> Ty<'tcx> {
188         struct_span_err!(
189             self.tcx().sess,
190             span,
191             E0121,
192             "the type placeholder `_` is not allowed within types on item signatures"
193         ).span_label(span, "not allowed in type signatures")
194          .emit();
195
196         self.tcx().types.err
197     }
198
199     fn projected_ty_from_poly_trait_ref(
200         &self,
201         span: Span,
202         item_def_id: DefId,
203         poly_trait_ref: ty::PolyTraitRef<'tcx>,
204     ) -> Ty<'tcx> {
205         if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
206             self.tcx().mk_projection(item_def_id, trait_ref.substs)
207         } else {
208             // no late-bound regions, we can just ignore the binder
209             span_err!(
210                 self.tcx().sess,
211                 span,
212                 E0212,
213                 "cannot extract an associated type from a higher-ranked trait bound \
214                  in this context"
215             );
216             self.tcx().types.err
217         }
218     }
219
220     fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
221         // types in item signatures are not normalized, to avoid undue
222         // dependencies.
223         ty
224     }
225
226     fn set_tainted_by_errors(&self) {
227         // no obvious place to track this, just let it go
228     }
229
230     fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
231         // no place to record types from signatures?
232     }
233 }
234
235 fn type_param_predicates<'a, 'tcx>(
236     tcx: TyCtxt<'a, 'tcx, 'tcx>,
237     (item_def_id, def_id): (DefId, DefId),
238 ) -> Lrc<ty::GenericPredicates<'tcx>> {
239     use rustc::hir::*;
240
241     // In the AST, bounds can derive from two places. Either
242     // written inline like `<T : Foo>` or in a where clause like
243     // `where T : Foo`.
244
245     let param_id = tcx.hir().as_local_node_id(def_id).unwrap();
246     let param_owner = tcx.hir().ty_param_owner(param_id);
247     let param_owner_def_id = tcx.hir().local_def_id(param_owner);
248     let generics = tcx.generics_of(param_owner_def_id);
249     let index = generics.param_def_id_to_index[&def_id];
250     let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id).as_interned_str());
251
252     // Don't look for bounds where the type parameter isn't in scope.
253     let parent = if item_def_id == param_owner_def_id {
254         None
255     } else {
256         tcx.generics_of(item_def_id).parent
257     };
258
259     let mut result = parent.map_or_else(
260         || Lrc::new(ty::GenericPredicates {
261             parent: None,
262             predicates: vec![],
263         }),
264         |parent| {
265             let icx = ItemCtxt::new(tcx, parent);
266             icx.get_type_parameter_bounds(DUMMY_SP, def_id)
267         },
268     );
269
270     let item_node_id = tcx.hir().as_local_node_id(item_def_id).unwrap();
271     let ast_generics = match tcx.hir().get(item_node_id) {
272         Node::TraitItem(item) => &item.generics,
273
274         Node::ImplItem(item) => &item.generics,
275
276         Node::Item(item) => {
277             match item.node {
278                 ItemKind::Fn(.., ref generics, _)
279                 | ItemKind::Impl(_, _, _, ref generics, ..)
280                 | ItemKind::Ty(_, ref generics)
281                 | ItemKind::Existential(ExistTy {
282                     ref generics,
283                     impl_trait_fn: None,
284                     ..
285                 })
286                 | ItemKind::Enum(_, ref generics)
287                 | ItemKind::Struct(_, ref generics)
288                 | ItemKind::Union(_, ref generics) => generics,
289                 ItemKind::Trait(_, _, ref generics, ..) => {
290                     // Implied `Self: Trait` and supertrait bounds.
291                     if param_id == item_node_id {
292                         let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
293                         Lrc::make_mut(&mut result)
294                             .predicates
295                             .push((identity_trait_ref.to_predicate(), item.span));
296                     }
297                     generics
298                 }
299                 _ => return result,
300             }
301         }
302
303         Node::ForeignItem(item) => match item.node {
304             ForeignItemKind::Fn(_, _, ref generics) => generics,
305             _ => return result,
306         },
307
308         _ => return result,
309     };
310
311     let icx = ItemCtxt::new(tcx, item_def_id);
312     Lrc::make_mut(&mut result)
313         .predicates
314         .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty,
315             OnlySelfBounds(true)));
316     result
317 }
318
319 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
320     /// Find bounds from `hir::Generics`. This requires scanning through the
321     /// AST. We do this to avoid having to convert *all* the bounds, which
322     /// would create artificial cycles. Instead we can only convert the
323     /// bounds for a type parameter `X` if `X::Foo` is used.
324     fn type_parameter_bounds_in_generics(
325         &self,
326         ast_generics: &hir::Generics,
327         param_id: ast::NodeId,
328         ty: Ty<'tcx>,
329         only_self_bounds: OnlySelfBounds,
330     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
331         let from_ty_params = ast_generics
332             .params
333             .iter()
334             .filter_map(|param| match param.kind {
335                 GenericParamKind::Type { .. } if param.id == param_id => Some(&param.bounds),
336                 _ => None,
337             })
338             .flat_map(|bounds| bounds.iter())
339             .flat_map(|b| predicates_from_bound(self, ty, b));
340
341         let from_where_clauses = ast_generics
342             .where_clause
343             .predicates
344             .iter()
345             .filter_map(|wp| match *wp {
346                 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
347                 _ => None,
348             })
349             .flat_map(|bp| {
350                 let bt = if is_param(self.tcx, &bp.bounded_ty, param_id) {
351                     Some(ty)
352                 } else if !only_self_bounds.0 {
353                     Some(self.to_ty(&bp.bounded_ty))
354                 } else {
355                     None
356                 };
357                 bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b)))
358             })
359             .flat_map(|(bt, b)| predicates_from_bound(self, bt, b));
360
361         from_ty_params.chain(from_where_clauses).collect()
362     }
363 }
364
365 /// Tests whether this is the AST for a reference to the type
366 /// parameter with id `param_id`. We use this so as to avoid running
367 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
368 /// conversion of the type to avoid inducing unnecessary cycles.
369 fn is_param<'a, 'tcx>(
370     tcx: TyCtxt<'a, 'tcx, 'tcx>,
371     ast_ty: &hir::Ty,
372     param_id: ast::NodeId,
373 ) -> bool {
374     if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
375         match path.def {
376             Def::SelfTy(Some(def_id), None) | Def::TyParam(def_id) => {
377                 def_id == tcx.hir().local_def_id(param_id)
378             }
379             _ => false,
380         }
381     } else {
382         false
383     }
384 }
385
386 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
387     let it = tcx.hir().expect_item(item_id);
388     debug!("convert: item {} with id {}", it.ident, it.id);
389     let def_id = tcx.hir().local_def_id(item_id);
390     match it.node {
391         // These don't define types.
392         hir::ItemKind::ExternCrate(_)
393         | hir::ItemKind::Use(..)
394         | hir::ItemKind::Mod(_)
395         | hir::ItemKind::GlobalAsm(_) => {}
396         hir::ItemKind::ForeignMod(ref foreign_mod) => {
397             for item in &foreign_mod.items {
398                 let def_id = tcx.hir().local_def_id(item.id);
399                 tcx.generics_of(def_id);
400                 tcx.type_of(def_id);
401                 tcx.predicates_of(def_id);
402                 if let hir::ForeignItemKind::Fn(..) = item.node {
403                     tcx.fn_sig(def_id);
404                 }
405             }
406         }
407         hir::ItemKind::Enum(ref enum_definition, _) => {
408             tcx.generics_of(def_id);
409             tcx.type_of(def_id);
410             tcx.predicates_of(def_id);
411             convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
412         }
413         hir::ItemKind::Impl(..) => {
414             tcx.generics_of(def_id);
415             tcx.type_of(def_id);
416             tcx.impl_trait_ref(def_id);
417             tcx.predicates_of(def_id);
418         }
419         hir::ItemKind::Trait(..) => {
420             tcx.generics_of(def_id);
421             tcx.trait_def(def_id);
422             tcx.at(it.span).super_predicates_of(def_id);
423             tcx.predicates_of(def_id);
424         }
425         hir::ItemKind::TraitAlias(..) => {
426             tcx.generics_of(def_id);
427             tcx.at(it.span).super_predicates_of(def_id);
428             tcx.predicates_of(def_id);
429         }
430         hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
431             tcx.generics_of(def_id);
432             tcx.type_of(def_id);
433             tcx.predicates_of(def_id);
434
435             for f in struct_def.fields() {
436                 let def_id = tcx.hir().local_def_id(f.id);
437                 tcx.generics_of(def_id);
438                 tcx.type_of(def_id);
439                 tcx.predicates_of(def_id);
440             }
441
442             if !struct_def.is_struct() {
443                 convert_variant_ctor(tcx, struct_def.id());
444             }
445         }
446
447         // Desugared from `impl Trait` -> visited by the function's return type
448         hir::ItemKind::Existential(hir::ExistTy {
449             impl_trait_fn: Some(_),
450             ..
451         }) => {}
452
453         hir::ItemKind::Existential(..)
454         | hir::ItemKind::Ty(..)
455         | hir::ItemKind::Static(..)
456         | hir::ItemKind::Const(..)
457         | hir::ItemKind::Fn(..) => {
458             tcx.generics_of(def_id);
459             tcx.type_of(def_id);
460             tcx.predicates_of(def_id);
461             if let hir::ItemKind::Fn(..) = it.node {
462                 tcx.fn_sig(def_id);
463             }
464         }
465     }
466 }
467
468 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
469     let trait_item = tcx.hir().expect_trait_item(trait_item_id);
470     let def_id = tcx.hir().local_def_id(trait_item.id);
471     tcx.generics_of(def_id);
472
473     match trait_item.node {
474         hir::TraitItemKind::Const(..)
475         | hir::TraitItemKind::Type(_, Some(_))
476         | hir::TraitItemKind::Method(..) => {
477             tcx.type_of(def_id);
478             if let hir::TraitItemKind::Method(..) = trait_item.node {
479                 tcx.fn_sig(def_id);
480             }
481         }
482
483         hir::TraitItemKind::Type(_, None) => {}
484     };
485
486     tcx.predicates_of(def_id);
487 }
488
489 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
490     let def_id = tcx.hir().local_def_id(impl_item_id);
491     tcx.generics_of(def_id);
492     tcx.type_of(def_id);
493     tcx.predicates_of(def_id);
494     if let hir::ImplItemKind::Method(..) = tcx.hir().expect_impl_item(impl_item_id).node {
495         tcx.fn_sig(def_id);
496     }
497 }
498
499 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ctor_id: ast::NodeId) {
500     let def_id = tcx.hir().local_def_id(ctor_id);
501     tcx.generics_of(def_id);
502     tcx.type_of(def_id);
503     tcx.predicates_of(def_id);
504 }
505
506 fn convert_enum_variant_types<'a, 'tcx>(
507     tcx: TyCtxt<'a, 'tcx, 'tcx>,
508     def_id: DefId,
509     variants: &[hir::Variant],
510 ) {
511     let def = tcx.adt_def(def_id);
512     let repr_type = def.repr.discr_type();
513     let initial = repr_type.initial_discriminant(tcx);
514     let mut prev_discr = None::<Discr<'tcx>>;
515
516     // fill the discriminant values and field types
517     for variant in variants {
518         let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
519         prev_discr = Some(
520             if let Some(ref e) = variant.node.disr_expr {
521                 let expr_did = tcx.hir().local_def_id(e.id);
522                 def.eval_explicit_discr(tcx, expr_did)
523             } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
524                 Some(discr)
525             } else {
526                 struct_span_err!(
527                     tcx.sess,
528                     variant.span,
529                     E0370,
530                     "enum discriminant overflowed"
531                 ).span_label(
532                     variant.span,
533                     format!("overflowed on value after {}", prev_discr.unwrap()),
534                 ).note(&format!(
535                     "explicitly set `{} = {}` if that is desired outcome",
536                     variant.node.ident, wrapped_discr
537                 ))
538                 .emit();
539                 None
540             }.unwrap_or(wrapped_discr),
541         );
542
543         for f in variant.node.data.fields() {
544             let def_id = tcx.hir().local_def_id(f.id);
545             tcx.generics_of(def_id);
546             tcx.type_of(def_id);
547             tcx.predicates_of(def_id);
548         }
549
550         // Convert the ctor, if any. This also registers the variant as
551         // an item.
552         convert_variant_ctor(tcx, variant.node.data.id());
553     }
554 }
555
556 fn convert_variant<'a, 'tcx>(
557     tcx: TyCtxt<'a, 'tcx, 'tcx>,
558     did: DefId,
559     ident: Ident,
560     discr: ty::VariantDiscr,
561     def: &hir::VariantData,
562     adt_kind: ty::AdtKind,
563     attribute_def_id: DefId
564 ) -> ty::VariantDef {
565     let mut seen_fields: FxHashMap<ast::Ident, Span> = Default::default();
566     let node_id = tcx.hir().as_local_node_id(did).unwrap();
567     let fields = def
568         .fields()
569         .iter()
570         .map(|f| {
571             let fid = tcx.hir().local_def_id(f.id);
572             let dup_span = seen_fields.get(&f.ident.modern()).cloned();
573             if let Some(prev_span) = dup_span {
574                 struct_span_err!(
575                     tcx.sess,
576                     f.span,
577                     E0124,
578                     "field `{}` is already declared",
579                     f.ident
580                 ).span_label(f.span, "field already declared")
581                  .span_label(prev_span, format!("`{}` first declared here", f.ident))
582                  .emit();
583             } else {
584                 seen_fields.insert(f.ident.modern(), f.span);
585             }
586
587             ty::FieldDef {
588                 did: fid,
589                 ident: f.ident,
590                 vis: ty::Visibility::from_hir(&f.vis, node_id, tcx),
591             }
592         })
593         .collect();
594     ty::VariantDef::new(tcx,
595         did,
596         ident,
597         discr,
598         fields,
599         adt_kind,
600         CtorKind::from_hir(def),
601         attribute_def_id
602     )
603 }
604
605 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
606     use rustc::hir::*;
607
608     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
609     let item = match tcx.hir().get(node_id) {
610         Node::Item(item) => item,
611         _ => bug!(),
612     };
613
614     let repr = ReprOptions::new(tcx, def_id);
615     let (kind, variants) = match item.node {
616         ItemKind::Enum(ref def, _) => {
617             let mut distance_from_explicit = 0;
618             (
619                 AdtKind::Enum,
620                 def.variants
621                     .iter()
622                     .map(|v| {
623                         let did = tcx.hir().local_def_id(v.node.data.id());
624                         let discr = if let Some(ref e) = v.node.disr_expr {
625                             distance_from_explicit = 0;
626                             ty::VariantDiscr::Explicit(tcx.hir().local_def_id(e.id))
627                         } else {
628                             ty::VariantDiscr::Relative(distance_from_explicit)
629                         };
630                         distance_from_explicit += 1;
631
632                         convert_variant(tcx, did, v.node.ident, discr, &v.node.data, AdtKind::Enum,
633                                         did)
634                     })
635                     .collect(),
636             )
637         }
638         ItemKind::Struct(ref def, _) => {
639             // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
640             let ctor_id = if !def.is_struct() {
641                 Some(tcx.hir().local_def_id(def.id()))
642             } else {
643                 None
644             };
645             (
646                 AdtKind::Struct,
647                 std::iter::once(convert_variant(
648                     tcx,
649                     ctor_id.unwrap_or(def_id),
650                     item.ident,
651                     ty::VariantDiscr::Relative(0),
652                     def,
653                     AdtKind::Struct,
654                     def_id
655                 )).collect(),
656             )
657         }
658         ItemKind::Union(ref def, _) => (
659             AdtKind::Union,
660             std::iter::once(convert_variant(
661                 tcx,
662                 def_id,
663                 item.ident,
664                 ty::VariantDiscr::Relative(0),
665                 def,
666                 AdtKind::Union,
667                 def_id
668             )).collect(),
669         ),
670         _ => bug!(),
671     };
672     tcx.alloc_adt_def(def_id, kind, variants, repr)
673 }
674
675 /// Ensures that the super-predicates of the trait with def-id
676 /// trait_def_id are converted and stored. This also ensures that
677 /// the transitive super-predicates are converted;
678 fn super_predicates_of<'a, 'tcx>(
679     tcx: TyCtxt<'a, 'tcx, 'tcx>,
680     trait_def_id: DefId,
681 ) -> Lrc<ty::GenericPredicates<'tcx>> {
682     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
683     let trait_node_id = tcx.hir().as_local_node_id(trait_def_id).unwrap();
684
685     let item = match tcx.hir().get(trait_node_id) {
686         Node::Item(item) => item,
687         _ => bug!("trait_node_id {} is not an item", trait_node_id),
688     };
689
690     let (generics, bounds) = match item.node {
691         hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
692         hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
693         _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
694     };
695
696     let icx = ItemCtxt::new(tcx, trait_def_id);
697
698     // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo : Bar + Zed`.
699     let self_param_ty = tcx.mk_self_type();
700     let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
701
702     let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
703
704     // Convert any explicit superbounds in the where clause,
705     // e.g., `trait Foo where Self : Bar`.
706     // In the case of trait aliases, however, we include all bounds in the where clause,
707     // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
708     // as one of its "superpredicates".
709     let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id);
710     let superbounds2 = icx.type_parameter_bounds_in_generics(
711         generics, item.id, self_param_ty, OnlySelfBounds(!is_trait_alias));
712
713     // Combine the two lists to form the complete set of superbounds:
714     let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
715
716     // Now require that immediate supertraits are converted,
717     // which will, in turn, reach indirect supertraits.
718     for &(pred, span) in &superbounds {
719         debug!("superbound: {:?}", pred);
720         if let ty::Predicate::Trait(bound) = pred {
721             tcx.at(span).super_predicates_of(bound.def_id());
722         }
723     }
724
725     Lrc::new(ty::GenericPredicates {
726         parent: None,
727         predicates: superbounds,
728     })
729 }
730
731 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::TraitDef {
732     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
733     let item = tcx.hir().expect_item(node_id);
734
735     let (is_auto, unsafety) = match item.node {
736         hir::ItemKind::Trait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
737         hir::ItemKind::TraitAlias(..) => (false, hir::Unsafety::Normal),
738         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
739     };
740
741     let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
742     if paren_sugar && !tcx.features().unboxed_closures {
743         let mut err = tcx.sess.struct_span_err(
744             item.span,
745             "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
746              which traits can use parenthetical notation",
747         );
748         help!(
749             &mut err,
750             "add `#![feature(unboxed_closures)]` to \
751              the crate attributes to use it"
752         );
753         err.emit();
754     }
755
756     let is_marker = tcx.has_attr(def_id, "marker");
757     let def_path_hash = tcx.def_path_hash(def_id);
758     let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, def_path_hash);
759     tcx.alloc_trait_def(def)
760 }
761
762 fn has_late_bound_regions<'a, 'tcx>(
763     tcx: TyCtxt<'a, 'tcx, 'tcx>,
764     node: Node<'tcx>,
765 ) -> Option<Span> {
766     struct LateBoundRegionsDetector<'a, 'tcx: 'a> {
767         tcx: TyCtxt<'a, 'tcx, 'tcx>,
768         outer_index: ty::DebruijnIndex,
769         has_late_bound_regions: Option<Span>,
770     }
771
772     impl<'a, 'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'a, 'tcx> {
773         fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
774             NestedVisitorMap::None
775         }
776
777         fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
778             if self.has_late_bound_regions.is_some() {
779                 return;
780             }
781             match ty.node {
782                 hir::TyKind::BareFn(..) => {
783                     self.outer_index.shift_in(1);
784                     intravisit::walk_ty(self, ty);
785                     self.outer_index.shift_out(1);
786                 }
787                 _ => intravisit::walk_ty(self, ty),
788             }
789         }
790
791         fn visit_poly_trait_ref(
792             &mut self,
793             tr: &'tcx hir::PolyTraitRef,
794             m: hir::TraitBoundModifier,
795         ) {
796             if self.has_late_bound_regions.is_some() {
797                 return;
798             }
799             self.outer_index.shift_in(1);
800             intravisit::walk_poly_trait_ref(self, tr, m);
801             self.outer_index.shift_out(1);
802         }
803
804         fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
805             if self.has_late_bound_regions.is_some() {
806                 return;
807             }
808
809             let hir_id = self.tcx.hir().node_to_hir_id(lt.id);
810             match self.tcx.named_region(hir_id) {
811                 Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {}
812                 Some(rl::Region::LateBound(debruijn, _, _))
813                 | Some(rl::Region::LateBoundAnon(debruijn, _)) if debruijn < self.outer_index => {}
814                 Some(rl::Region::LateBound(..))
815                 | Some(rl::Region::LateBoundAnon(..))
816                 | Some(rl::Region::Free(..))
817                 | None => {
818                     self.has_late_bound_regions = Some(lt.span);
819                 }
820             }
821         }
822     }
823
824     fn has_late_bound_regions<'a, 'tcx>(
825         tcx: TyCtxt<'a, 'tcx, 'tcx>,
826         generics: &'tcx hir::Generics,
827         decl: &'tcx hir::FnDecl,
828     ) -> Option<Span> {
829         let mut visitor = LateBoundRegionsDetector {
830             tcx,
831             outer_index: ty::INNERMOST,
832             has_late_bound_regions: None,
833         };
834         for param in &generics.params {
835             if let GenericParamKind::Lifetime { .. } = param.kind {
836                 let hir_id = tcx.hir().node_to_hir_id(param.id);
837                 if tcx.is_late_bound(hir_id) {
838                     return Some(param.span);
839                 }
840             }
841         }
842         visitor.visit_fn_decl(decl);
843         visitor.has_late_bound_regions
844     }
845
846     match node {
847         Node::TraitItem(item) => match item.node {
848             hir::TraitItemKind::Method(ref sig, _) => {
849                 has_late_bound_regions(tcx, &item.generics, &sig.decl)
850             }
851             _ => None,
852         },
853         Node::ImplItem(item) => match item.node {
854             hir::ImplItemKind::Method(ref sig, _) => {
855                 has_late_bound_regions(tcx, &item.generics, &sig.decl)
856             }
857             _ => None,
858         },
859         Node::ForeignItem(item) => match item.node {
860             hir::ForeignItemKind::Fn(ref fn_decl, _, ref generics) => {
861                 has_late_bound_regions(tcx, generics, fn_decl)
862             }
863             _ => None,
864         },
865         Node::Item(item) => match item.node {
866             hir::ItemKind::Fn(ref fn_decl, .., ref generics, _) => {
867                 has_late_bound_regions(tcx, generics, fn_decl)
868             }
869             _ => None,
870         },
871         _ => None,
872     }
873 }
874
875 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Generics {
876     use rustc::hir::*;
877
878     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
879
880     let node = tcx.hir().get(node_id);
881     let parent_def_id = match node {
882         Node::ImplItem(_) | Node::TraitItem(_) | Node::Variant(_)
883         | Node::StructCtor(_) | Node::Field(_) => {
884             let parent_id = tcx.hir().get_parent(node_id);
885             Some(tcx.hir().local_def_id(parent_id))
886         }
887         Node::Expr(&hir::Expr {
888             node: hir::ExprKind::Closure(..),
889             ..
890         }) => Some(tcx.closure_base_def_id(def_id)),
891         Node::Item(item) => match item.node {
892             ItemKind::Existential(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn,
893             _ => None,
894         },
895         _ => None,
896     };
897
898     let mut opt_self = None;
899     let mut allow_defaults = false;
900
901     let no_generics = hir::Generics::empty();
902     let ast_generics = match node {
903         Node::TraitItem(item) => &item.generics,
904
905         Node::ImplItem(item) => &item.generics,
906
907         Node::Item(item) => {
908             match item.node {
909                 ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => {
910                     generics
911                 }
912
913                 ItemKind::Ty(_, ref generics)
914                 | ItemKind::Enum(_, ref generics)
915                 | ItemKind::Struct(_, ref generics)
916                 | ItemKind::Existential(hir::ExistTy { ref generics, .. })
917                 | ItemKind::Union(_, ref generics) => {
918                     allow_defaults = true;
919                     generics
920                 }
921
922                 ItemKind::Trait(_, _, ref generics, ..)
923                 | ItemKind::TraitAlias(ref generics, ..) => {
924                     // Add in the self type parameter.
925                     //
926                     // Something of a hack: use the node id for the trait, also as
927                     // the node id for the Self type parameter.
928                     let param_id = item.id;
929
930                     opt_self = Some(ty::GenericParamDef {
931                         index: 0,
932                         name: keywords::SelfUpper.name().as_interned_str(),
933                         def_id: tcx.hir().local_def_id(param_id),
934                         pure_wrt_drop: false,
935                         kind: ty::GenericParamDefKind::Type {
936                             has_default: false,
937                             object_lifetime_default: rl::Set1::Empty,
938                             synthetic: None,
939                         },
940                     });
941
942                     allow_defaults = true;
943                     generics
944                 }
945
946                 _ => &no_generics,
947             }
948         }
949
950         Node::ForeignItem(item) => match item.node {
951             ForeignItemKind::Static(..) => &no_generics,
952             ForeignItemKind::Fn(_, _, ref generics) => generics,
953             ForeignItemKind::Type => &no_generics,
954         },
955
956         _ => &no_generics,
957     };
958
959     let has_self = opt_self.is_some();
960     let mut parent_has_self = false;
961     let mut own_start = has_self as u32;
962     let parent_count = parent_def_id.map_or(0, |def_id| {
963         let generics = tcx.generics_of(def_id);
964         assert_eq!(has_self, false);
965         parent_has_self = generics.has_self;
966         own_start = generics.count() as u32;
967         generics.parent_count + generics.params.len()
968     });
969
970     let mut params: Vec<_> = opt_self.into_iter().collect();
971
972     let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
973     params.extend(
974         early_lifetimes
975             .enumerate()
976             .map(|(i, param)| ty::GenericParamDef {
977                 name: param.name.ident().as_interned_str(),
978                 index: own_start + i as u32,
979                 def_id: tcx.hir().local_def_id(param.id),
980                 pure_wrt_drop: param.pure_wrt_drop,
981                 kind: ty::GenericParamDefKind::Lifetime,
982             }),
983     );
984
985     let hir_id = tcx.hir().node_to_hir_id(node_id);
986     let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id);
987
988     // Now create the real type parameters.
989     let type_start = own_start - has_self as u32 + params.len() as u32;
990     let mut i = 0;
991     params.extend(
992         ast_generics
993             .params
994             .iter()
995             .filter_map(|param| match param.kind {
996                 GenericParamKind::Type {
997                     ref default,
998                     synthetic,
999                     ..
1000                 } => {
1001                     if param.name.ident().name == keywords::SelfUpper.name() {
1002                         span_bug!(
1003                             param.span,
1004                             "`Self` should not be the name of a regular parameter"
1005                         );
1006                     }
1007
1008                     if !allow_defaults && default.is_some() {
1009                         if !tcx.features().default_type_parameter_fallback {
1010                             tcx.lint_node(
1011                                 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1012                                 param.id,
1013                                 param.span,
1014                                 &format!(
1015                                     "defaults for type parameters are only allowed in \
1016                                      `struct`, `enum`, `type`, or `trait` definitions."
1017                                 ),
1018                             );
1019                         }
1020                     }
1021
1022                     let ty_param = ty::GenericParamDef {
1023                         index: type_start + i as u32,
1024                         name: param.name.ident().as_interned_str(),
1025                         def_id: tcx.hir().local_def_id(param.id),
1026                         pure_wrt_drop: param.pure_wrt_drop,
1027                         kind: ty::GenericParamDefKind::Type {
1028                             has_default: default.is_some(),
1029                             object_lifetime_default: object_lifetime_defaults
1030                                 .as_ref()
1031                                 .map_or(rl::Set1::Empty, |o| o[i]),
1032                             synthetic,
1033                         },
1034                     };
1035                     i += 1;
1036                     Some(ty_param)
1037                 }
1038                 _ => None,
1039             }),
1040     );
1041
1042     // provide junk type parameter defs - the only place that
1043     // cares about anything but the length is instantiation,
1044     // and we don't do that for closures.
1045     if let Node::Expr(&hir::Expr {
1046         node: hir::ExprKind::Closure(.., gen),
1047         ..
1048     }) = node
1049     {
1050         let dummy_args = if gen.is_some() {
1051             &["<yield_ty>", "<return_ty>", "<witness>"][..]
1052         } else {
1053             &["<closure_kind>", "<closure_signature>"][..]
1054         };
1055
1056         params.extend(
1057             dummy_args
1058                 .iter()
1059                 .enumerate()
1060                 .map(|(i, &arg)| ty::GenericParamDef {
1061                     index: type_start + i as u32,
1062                     name: Symbol::intern(arg).as_interned_str(),
1063                     def_id,
1064                     pure_wrt_drop: false,
1065                     kind: ty::GenericParamDefKind::Type {
1066                         has_default: false,
1067                         object_lifetime_default: rl::Set1::Empty,
1068                         synthetic: None,
1069                     },
1070                 }),
1071         );
1072
1073         tcx.with_freevars(node_id, |fv| {
1074             params.extend(fv.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
1075                 ty::GenericParamDef {
1076                     index: type_start + i,
1077                     name: Symbol::intern("<upvar>").as_interned_str(),
1078                     def_id,
1079                     pure_wrt_drop: false,
1080                     kind: ty::GenericParamDefKind::Type {
1081                         has_default: false,
1082                         object_lifetime_default: rl::Set1::Empty,
1083                         synthetic: None,
1084                     },
1085                 }
1086             }));
1087         });
1088     }
1089
1090     let param_def_id_to_index = params
1091         .iter()
1092         .map(|param| (param.def_id, param.index))
1093         .collect();
1094
1095     tcx.alloc_generics(ty::Generics {
1096         parent: parent_def_id,
1097         parent_count,
1098         params,
1099         param_def_id_to_index,
1100         has_self: has_self || parent_has_self,
1101         has_late_bound_regions: has_late_bound_regions(tcx, node),
1102     })
1103 }
1104
1105 fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span) {
1106     span_err!(
1107         tcx.sess,
1108         span,
1109         E0202,
1110         "associated types are not allowed in inherent impls"
1111     );
1112 }
1113
1114 fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
1115     use rustc::hir::*;
1116
1117     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1118
1119     let icx = ItemCtxt::new(tcx, def_id);
1120
1121     match tcx.hir().get(node_id) {
1122         Node::TraitItem(item) => match item.node {
1123             TraitItemKind::Method(..) => {
1124                 let substs = Substs::identity_for_item(tcx, def_id);
1125                 tcx.mk_fn_def(def_id, substs)
1126             }
1127             TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
1128             TraitItemKind::Type(_, None) => {
1129                 span_bug!(item.span, "associated type missing default");
1130             }
1131         },
1132
1133         Node::ImplItem(item) => match item.node {
1134             ImplItemKind::Method(..) => {
1135                 let substs = Substs::identity_for_item(tcx, def_id);
1136                 tcx.mk_fn_def(def_id, substs)
1137             }
1138             ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
1139             ImplItemKind::Existential(_) => {
1140                 if tcx
1141                     .impl_trait_ref(tcx.hir().get_parent_did(node_id))
1142                     .is_none()
1143                 {
1144                     report_assoc_ty_on_inherent_impl(tcx, item.span);
1145                 }
1146
1147                 find_existential_constraints(tcx, def_id)
1148             }
1149             ImplItemKind::Type(ref ty) => {
1150                 if tcx
1151                     .impl_trait_ref(tcx.hir().get_parent_did(node_id))
1152                     .is_none()
1153                 {
1154                     report_assoc_ty_on_inherent_impl(tcx, item.span);
1155                 }
1156
1157                 icx.to_ty(ty)
1158             }
1159         },
1160
1161         Node::Item(item) => {
1162             match item.node {
1163                 ItemKind::Static(ref t, ..)
1164                 | ItemKind::Const(ref t, _)
1165                 | ItemKind::Ty(ref t, _)
1166                 | ItemKind::Impl(.., ref t, _) => icx.to_ty(t),
1167                 ItemKind::Fn(..) => {
1168                     let substs = Substs::identity_for_item(tcx, def_id);
1169                     tcx.mk_fn_def(def_id, substs)
1170                 }
1171                 ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
1172                     let def = tcx.adt_def(def_id);
1173                     let substs = Substs::identity_for_item(tcx, def_id);
1174                     tcx.mk_adt(def, substs)
1175                 }
1176                 ItemKind::Existential(hir::ExistTy {
1177                     impl_trait_fn: None,
1178                     ..
1179                 }) => find_existential_constraints(tcx, def_id),
1180                 // existential types desugared from impl Trait
1181                 ItemKind::Existential(hir::ExistTy {
1182                     impl_trait_fn: Some(owner),
1183                     ..
1184                 }) => {
1185                     tcx.typeck_tables_of(owner)
1186                         .concrete_existential_types
1187                         .get(&def_id)
1188                         .cloned()
1189                         .unwrap_or_else(|| {
1190                             // This can occur if some error in the
1191                             // owner fn prevented us from populating
1192                             // the `concrete_existential_types` table.
1193                             tcx.sess.delay_span_bug(
1194                                 DUMMY_SP,
1195                                 &format!(
1196                                     "owner {:?} has no existential type for {:?} in its tables",
1197                                     owner, def_id,
1198                                 ),
1199                             );
1200                             tcx.types.err
1201                         })
1202                 }
1203                 ItemKind::Trait(..)
1204                 | ItemKind::TraitAlias(..)
1205                 | ItemKind::Mod(..)
1206                 | ItemKind::ForeignMod(..)
1207                 | ItemKind::GlobalAsm(..)
1208                 | ItemKind::ExternCrate(..)
1209                 | ItemKind::Use(..) => {
1210                     span_bug!(
1211                         item.span,
1212                         "compute_type_of_item: unexpected item type: {:?}",
1213                         item.node
1214                     );
1215                 }
1216             }
1217         }
1218
1219         Node::ForeignItem(foreign_item) => match foreign_item.node {
1220             ForeignItemKind::Fn(..) => {
1221                 let substs = Substs::identity_for_item(tcx, def_id);
1222                 tcx.mk_fn_def(def_id, substs)
1223             }
1224             ForeignItemKind::Static(ref t, _) => icx.to_ty(t),
1225             ForeignItemKind::Type => tcx.mk_foreign(def_id),
1226         },
1227
1228         Node::StructCtor(&ref def)
1229         | Node::Variant(&Spanned {
1230             node: hir::VariantKind { data: ref def, .. },
1231             ..
1232         }) => match *def {
1233             VariantData::Unit(..) | VariantData::Struct(..) => {
1234                 tcx.type_of(tcx.hir().get_parent_did(node_id))
1235             }
1236             VariantData::Tuple(..) => {
1237                 let substs = Substs::identity_for_item(tcx, def_id);
1238                 tcx.mk_fn_def(def_id, substs)
1239             }
1240         },
1241
1242         Node::Field(field) => icx.to_ty(&field.ty),
1243
1244         Node::Expr(&hir::Expr {
1245             node: hir::ExprKind::Closure(.., gen),
1246             ..
1247         }) => {
1248             if gen.is_some() {
1249                 let hir_id = tcx.hir().node_to_hir_id(node_id);
1250                 return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id);
1251             }
1252
1253             let substs = ty::ClosureSubsts {
1254                 substs: Substs::identity_for_item(tcx, def_id),
1255             };
1256
1257             tcx.mk_closure(def_id, substs)
1258         }
1259
1260         Node::AnonConst(_) => match tcx.hir().get(tcx.hir().get_parent_node(node_id)) {
1261             Node::Ty(&hir::Ty {
1262                 node: hir::TyKind::Array(_, ref constant),
1263                 ..
1264             })
1265             | Node::Ty(&hir::Ty {
1266                 node: hir::TyKind::Typeof(ref constant),
1267                 ..
1268             })
1269             | Node::Expr(&hir::Expr {
1270                 node: ExprKind::Repeat(_, ref constant),
1271                 ..
1272             }) if constant.id == node_id =>
1273             {
1274                 tcx.types.usize
1275             }
1276
1277             Node::Variant(&Spanned {
1278                 node:
1279                     VariantKind {
1280                         disr_expr: Some(ref e),
1281                         ..
1282                     },
1283                 ..
1284             }) if e.id == node_id =>
1285             {
1286                 tcx.adt_def(tcx.hir().get_parent_did(node_id))
1287                     .repr
1288                     .discr_type()
1289                     .to_ty(tcx)
1290             }
1291
1292             x => {
1293                 bug!("unexpected const parent in type_of_def_id(): {:?}", x);
1294             }
1295         },
1296
1297         Node::GenericParam(param) => match param.kind {
1298             hir::GenericParamKind::Type {
1299                 default: Some(ref ty),
1300                 ..
1301             } => icx.to_ty(ty),
1302             _ => bug!("unexpected non-type NodeGenericParam"),
1303         },
1304
1305         x => {
1306             bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1307         }
1308     }
1309 }
1310
1311 fn find_existential_constraints<'a, 'tcx>(
1312     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1313     def_id: DefId,
1314 ) -> ty::Ty<'tcx> {
1315     use rustc::hir::*;
1316
1317     struct ConstraintLocator<'a, 'tcx: 'a> {
1318         tcx: TyCtxt<'a, 'tcx, 'tcx>,
1319         def_id: DefId,
1320         found: Option<(Span, ty::Ty<'tcx>)>,
1321     }
1322
1323     impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> {
1324         fn check(&mut self, def_id: DefId) {
1325             trace!("checking {:?}", def_id);
1326             // don't try to check items that cannot possibly constrain the type
1327             if !self.tcx.has_typeck_tables(def_id) {
1328                 trace!("no typeck tables for {:?}", def_id);
1329                 return;
1330             }
1331             let ty = self
1332                 .tcx
1333                 .typeck_tables_of(def_id)
1334                 .concrete_existential_types
1335                 .get(&self.def_id)
1336                 .cloned();
1337             if let Some(ty) = ty {
1338                 // FIXME(oli-obk): trace the actual span from inference to improve errors
1339                 let span = self.tcx.def_span(def_id);
1340                 if let Some((prev_span, prev_ty)) = self.found {
1341                     if ty != prev_ty {
1342                         // found different concrete types for the existential type
1343                         let mut err = self.tcx.sess.struct_span_err(
1344                             span,
1345                             "defining existential type use differs from previous",
1346                         );
1347                         err.span_note(prev_span, "previous use here");
1348                         err.emit();
1349                     }
1350                 } else {
1351                     self.found = Some((span, ty));
1352                 }
1353             }
1354         }
1355     }
1356
1357     impl<'a, 'tcx> intravisit::Visitor<'tcx> for ConstraintLocator<'a, 'tcx> {
1358         fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
1359             intravisit::NestedVisitorMap::All(&self.tcx.hir())
1360         }
1361         fn visit_item(&mut self, it: &'tcx Item) {
1362             let def_id = self.tcx.hir().local_def_id(it.id);
1363             // the existential type itself or its children are not within its reveal scope
1364             if def_id != self.def_id {
1365                 self.check(def_id);
1366                 intravisit::walk_item(self, it);
1367             }
1368         }
1369         fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
1370             let def_id = self.tcx.hir().local_def_id(it.id);
1371             // the existential type itself or its children are not within its reveal scope
1372             if def_id != self.def_id {
1373                 self.check(def_id);
1374                 intravisit::walk_impl_item(self, it);
1375             }
1376         }
1377         fn visit_trait_item(&mut self, it: &'tcx TraitItem) {
1378             let def_id = self.tcx.hir().local_def_id(it.id);
1379             self.check(def_id);
1380             intravisit::walk_trait_item(self, it);
1381         }
1382     }
1383
1384     let mut locator = ConstraintLocator {
1385         def_id,
1386         tcx,
1387         found: None,
1388     };
1389     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1390     let parent = tcx.hir().get_parent(node_id);
1391
1392     trace!("parent_id: {:?}", parent);
1393
1394     if parent == ast::CRATE_NODE_ID {
1395         intravisit::walk_crate(&mut locator, tcx.hir().krate());
1396     } else {
1397         trace!("parent: {:?}", tcx.hir().get(parent));
1398         match tcx.hir().get(parent) {
1399             Node::Item(ref it) => intravisit::walk_item(&mut locator, it),
1400             Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
1401             Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it),
1402             other => bug!(
1403                 "{:?} is not a valid parent of an existential type item",
1404                 other
1405             ),
1406         }
1407     }
1408
1409     match locator.found {
1410         Some((_, ty)) => ty,
1411         None => {
1412             let span = tcx.def_span(def_id);
1413             tcx.sess.span_err(span, "could not find defining uses");
1414             tcx.types.err
1415         }
1416     }
1417 }
1418
1419 fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> {
1420     use rustc::hir::*;
1421     use rustc::hir::Node::*;
1422
1423     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1424
1425     let icx = ItemCtxt::new(tcx, def_id);
1426
1427     match tcx.hir().get(node_id) {
1428         TraitItem(hir::TraitItem {
1429             node: TraitItemKind::Method(sig, _),
1430             ..
1431         })
1432         | ImplItem(hir::ImplItem {
1433             node: ImplItemKind::Method(sig, _),
1434             ..
1435         }) => AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl),
1436
1437         Item(hir::Item {
1438             node: ItemKind::Fn(decl, header, _, _),
1439             ..
1440         }) => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl),
1441
1442         ForeignItem(&hir::ForeignItem {
1443             node: ForeignItemKind::Fn(ref fn_decl, _, _),
1444             ..
1445         }) => {
1446             let abi = tcx.hir().get_foreign_abi(node_id);
1447             compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1448         }
1449
1450         StructCtor(&VariantData::Tuple(ref fields, _))
1451         | Variant(&Spanned {
1452             node:
1453                 hir::VariantKind {
1454                     data: VariantData::Tuple(ref fields, _),
1455                     ..
1456                 },
1457             ..
1458         }) => {
1459             let ty = tcx.type_of(tcx.hir().get_parent_did(node_id));
1460             let inputs = fields
1461                 .iter()
1462                 .map(|f| tcx.type_of(tcx.hir().local_def_id(f.id)));
1463             ty::Binder::bind(tcx.mk_fn_sig(
1464                 inputs,
1465                 ty,
1466                 false,
1467                 hir::Unsafety::Normal,
1468                 abi::Abi::Rust,
1469             ))
1470         }
1471
1472         Expr(&hir::Expr {
1473             node: hir::ExprKind::Closure(..),
1474             ..
1475         }) => {
1476             // Closure signatures are not like other function
1477             // signatures and cannot be accessed through `fn_sig`. For
1478             // example, a closure signature excludes the `self`
1479             // argument. In any case they are embedded within the
1480             // closure type as part of the `ClosureSubsts`.
1481             //
1482             // To get
1483             // the signature of a closure, you should use the
1484             // `closure_sig` method on the `ClosureSubsts`:
1485             //
1486             //    closure_substs.closure_sig(def_id, tcx)
1487             //
1488             // or, inside of an inference context, you can use
1489             //
1490             //    infcx.closure_sig(def_id, closure_substs)
1491             bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`");
1492         }
1493
1494         x => {
1495             bug!("unexpected sort of node in fn_sig(): {:?}", x);
1496         }
1497     }
1498 }
1499
1500 fn impl_trait_ref<'a, 'tcx>(
1501     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1502     def_id: DefId,
1503 ) -> Option<ty::TraitRef<'tcx>> {
1504     let icx = ItemCtxt::new(tcx, def_id);
1505
1506     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1507     match tcx.hir().expect_item(node_id).node {
1508         hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => {
1509             opt_trait_ref.as_ref().map(|ast_trait_ref| {
1510                 let selfty = tcx.type_of(def_id);
1511                 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1512             })
1513         }
1514         _ => bug!(),
1515     }
1516 }
1517
1518 fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> hir::ImplPolarity {
1519     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1520     match tcx.hir().expect_item(node_id).node {
1521         hir::ItemKind::Impl(_, polarity, ..) => polarity,
1522         ref item => bug!("impl_polarity: {:?} not an impl", item),
1523     }
1524 }
1525
1526 // Is it marked with ?Sized
1527 fn is_unsized<'gcx: 'tcx, 'tcx>(
1528     astconv: &dyn AstConv<'gcx, 'tcx>,
1529     ast_bounds: &[hir::GenericBound],
1530     span: Span,
1531 ) -> bool {
1532     let tcx = astconv.tcx();
1533
1534     // Try to find an unbound in bounds.
1535     let mut unbound = None;
1536     for ab in ast_bounds {
1537         if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1538             if unbound.is_none() {
1539                 unbound = Some(ptr.trait_ref.clone());
1540             } else {
1541                 span_err!(
1542                     tcx.sess,
1543                     span,
1544                     E0203,
1545                     "type parameter has more than one relaxed default \
1546                      bound, only one is supported"
1547                 );
1548             }
1549         }
1550     }
1551
1552     let kind_id = tcx.lang_items().require(SizedTraitLangItem);
1553     match unbound {
1554         Some(ref tpb) => {
1555             // FIXME(#8559) currently requires the unbound to be built-in.
1556             if let Ok(kind_id) = kind_id {
1557                 if tpb.path.def != Def::Trait(kind_id) {
1558                     tcx.sess.span_warn(
1559                         span,
1560                         "default bound relaxed for a type parameter, but \
1561                          this does nothing because the given bound is not \
1562                          a default. Only `?Sized` is supported",
1563                     );
1564                 }
1565             }
1566         }
1567         _ if kind_id.is_ok() => {
1568             return false;
1569         }
1570         // No lang item for Sized, so we can't add it as a bound.
1571         None => {}
1572     }
1573
1574     true
1575 }
1576
1577 /// Returns the early-bound lifetimes declared in this generics
1578 /// listing.  For anything other than fns/methods, this is just all
1579 /// the lifetimes that are declared. For fns or methods, we have to
1580 /// screen out those that do not appear in any where-clauses etc using
1581 /// `resolve_lifetime::early_bound_lifetimes`.
1582 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1583     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1584     generics: &'a hir::Generics,
1585 ) -> impl Iterator<Item = &'a hir::GenericParam> + Captures<'tcx> {
1586     generics
1587         .params
1588         .iter()
1589         .filter(move |param| match param.kind {
1590             GenericParamKind::Lifetime { .. } => {
1591                 let hir_id = tcx.hir().node_to_hir_id(param.id);
1592                 !tcx.is_late_bound(hir_id)
1593             }
1594             _ => false,
1595         })
1596 }
1597
1598 fn predicates_defined_on<'a, 'tcx>(
1599     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1600     def_id: DefId,
1601 ) -> Lrc<ty::GenericPredicates<'tcx>> {
1602     debug!("predicates_defined_on({:?})", def_id);
1603     let mut result = tcx.explicit_predicates_of(def_id);
1604     debug!(
1605         "predicates_defined_on: explicit_predicates_of({:?}) = {:?}",
1606         def_id,
1607         result,
1608     );
1609     let inferred_outlives = tcx.inferred_outlives_of(def_id);
1610     if !inferred_outlives.is_empty() {
1611         let span = tcx.def_span(def_id);
1612         debug!(
1613             "predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
1614             def_id,
1615             inferred_outlives,
1616         );
1617         Lrc::make_mut(&mut result)
1618             .predicates
1619             .extend(inferred_outlives.iter().map(|&p| (p, span)));
1620     }
1621     result
1622 }
1623
1624 fn predicates_of<'a, 'tcx>(
1625     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1626     def_id: DefId,
1627 ) -> Lrc<ty::GenericPredicates<'tcx>> {
1628     let mut result = tcx.predicates_defined_on(def_id);
1629
1630     if tcx.is_trait(def_id) {
1631         // For traits, add `Self: Trait` predicate. This is
1632         // not part of the predicates that a user writes, but it
1633         // is something that one must prove in order to invoke a
1634         // method or project an associated type.
1635         //
1636         // In the chalk setup, this predicate is not part of the
1637         // "predicates" for a trait item. But it is useful in
1638         // rustc because if you directly (e.g.) invoke a trait
1639         // method like `Trait::method(...)`, you must naturally
1640         // prove that the trait applies to the types that were
1641         // used, and adding the predicate into this list ensures
1642         // that this is done.
1643         let span = tcx.def_span(def_id);
1644         Lrc::make_mut(&mut result)
1645             .predicates
1646             .push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
1647     }
1648     result
1649 }
1650
1651 fn explicit_predicates_of<'a, 'tcx>(
1652     tcx: TyCtxt<'a, 'tcx, 'tcx>,
1653     def_id: DefId,
1654 ) -> Lrc<ty::GenericPredicates<'tcx>> {
1655     use rustc::hir::*;
1656     use rustc_data_structures::fx::FxHashSet;
1657
1658     debug!("explicit_predicates_of(def_id={:?})", def_id);
1659
1660     /// A data structure with unique elements, which preserves order of insertion.
1661     /// Preserving the order of insertion is important here so as not to break
1662     /// compile-fail UI tests.
1663     struct UniquePredicates<'tcx> {
1664         predicates: Vec<(ty::Predicate<'tcx>, Span)>,
1665         uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>,
1666     }
1667
1668     impl<'tcx> UniquePredicates<'tcx> {
1669         fn new() -> Self {
1670             UniquePredicates {
1671                 predicates: vec![],
1672                 uniques: FxHashSet::default(),
1673             }
1674         }
1675
1676         fn push(&mut self, value: (ty::Predicate<'tcx>, Span)) {
1677             if self.uniques.insert(value) {
1678                 self.predicates.push(value);
1679             }
1680         }
1681
1682         fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter: I) {
1683             for value in iter {
1684                 self.push(value);
1685             }
1686         }
1687     }
1688
1689     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1690     let node = tcx.hir().get(node_id);
1691
1692     let mut is_trait = None;
1693     let mut is_default_impl_trait = None;
1694
1695     let icx = ItemCtxt::new(tcx, def_id);
1696     let no_generics = hir::Generics::empty();
1697     let empty_trait_items = HirVec::new();
1698
1699     let mut predicates = UniquePredicates::new();
1700
1701     let ast_generics = match node {
1702         Node::TraitItem(item) => &item.generics,
1703
1704         Node::ImplItem(item) => match item.node {
1705             ImplItemKind::Existential(ref bounds) => {
1706                 let substs = Substs::identity_for_item(tcx, def_id);
1707                 let opaque_ty = tcx.mk_opaque(def_id, substs);
1708
1709                 // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`.
1710                 let bounds = compute_bounds(
1711                     &icx,
1712                     opaque_ty,
1713                     bounds,
1714                     SizedByDefault::Yes,
1715                     tcx.def_span(def_id),
1716                 );
1717
1718                 predicates.extend(bounds.predicates(tcx, opaque_ty));
1719                 &item.generics
1720             }
1721             _ => &item.generics,
1722         },
1723
1724         Node::Item(item) => {
1725             match item.node {
1726                 ItemKind::Impl(_, _, defaultness, ref generics, ..) => {
1727                     if defaultness.is_default() {
1728                         is_default_impl_trait = tcx.impl_trait_ref(def_id);
1729                     }
1730                     generics
1731                 }
1732                 ItemKind::Fn(.., ref generics, _)
1733                 | ItemKind::Ty(_, ref generics)
1734                 | ItemKind::Enum(_, ref generics)
1735                 | ItemKind::Struct(_, ref generics)
1736                 | ItemKind::Union(_, ref generics) => generics,
1737
1738                 ItemKind::Trait(_, _, ref generics, .., ref items) => {
1739                     is_trait = Some((ty::TraitRef::identity(tcx, def_id), items));
1740                     generics
1741                 }
1742                 ItemKind::TraitAlias(ref generics, _) => {
1743                     is_trait = Some((ty::TraitRef::identity(tcx, def_id), &empty_trait_items));
1744                     generics
1745                 }
1746                 ItemKind::Existential(ExistTy {
1747                     ref bounds,
1748                     impl_trait_fn,
1749                     ref generics,
1750                 }) => {
1751                     let substs = Substs::identity_for_item(tcx, def_id);
1752                     let opaque_ty = tcx.mk_opaque(def_id, substs);
1753
1754                     // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`.
1755                     let bounds = compute_bounds(
1756                         &icx,
1757                         opaque_ty,
1758                         bounds,
1759                         SizedByDefault::Yes,
1760                         tcx.def_span(def_id),
1761                     );
1762
1763                     if impl_trait_fn.is_some() {
1764                         // impl Trait
1765                         return Lrc::new(ty::GenericPredicates {
1766                             parent: None,
1767                             predicates: bounds.predicates(tcx, opaque_ty),
1768                         });
1769                     } else {
1770                         // named existential types
1771                         predicates.extend(bounds.predicates(tcx, opaque_ty));
1772                         generics
1773                     }
1774                 }
1775
1776                 _ => &no_generics,
1777             }
1778         }
1779
1780         Node::ForeignItem(item) => match item.node {
1781             ForeignItemKind::Static(..) => &no_generics,
1782             ForeignItemKind::Fn(_, _, ref generics) => generics,
1783             ForeignItemKind::Type => &no_generics,
1784         },
1785
1786         _ => &no_generics,
1787     };
1788
1789     let generics = tcx.generics_of(def_id);
1790     let parent_count = generics.parent_count as u32;
1791     let has_own_self = generics.has_self && parent_count == 0;
1792
1793     // Below we'll consider the bounds on the type parameters (including `Self`)
1794     // and the explicit where-clauses, but to get the full set of predicates
1795     // on a trait we need to add in the supertrait bounds and bounds found on
1796     // associated types.
1797     if let Some((_trait_ref, _)) = is_trait {
1798         predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
1799     }
1800
1801     // In default impls, we can assume that the self type implements
1802     // the trait. So in:
1803     //
1804     //     default impl Foo for Bar { .. }
1805     //
1806     // we add a default where clause `Foo: Bar`. We do a similar thing for traits
1807     // (see below). Recall that a default impl is not itself an impl, but rather a
1808     // set of defaults that can be incorporated into another impl.
1809     if let Some(trait_ref) = is_default_impl_trait {
1810         predicates.push((trait_ref.to_poly_trait_ref().to_predicate(), tcx.def_span(def_id)));
1811     }
1812
1813     // Collect the region predicates that were declared inline as
1814     // well. In the case of parameters declared on a fn or method, we
1815     // have to be careful to only iterate over early-bound regions.
1816     let mut index = parent_count + has_own_self as u32;
1817     for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1818         let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1819             def_id: tcx.hir().local_def_id(param.id),
1820             index,
1821             name: param.name.ident().as_interned_str(),
1822         }));
1823         index += 1;
1824
1825         match param.kind {
1826             GenericParamKind::Lifetime { .. } => {
1827                 param.bounds.iter().for_each(|bound| match bound {
1828                     hir::GenericBound::Outlives(lt) => {
1829                         let bound = AstConv::ast_region_to_region(&icx, &lt, None);
1830                         let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound));
1831                         predicates.push((outlives.to_predicate(), lt.span));
1832                     }
1833                     _ => bug!(),
1834                 });
1835             }
1836             _ => bug!(),
1837         }
1838     }
1839
1840     // Collect the predicates that were written inline by the user on each
1841     // type parameter (e.g., `<T:Foo>`).
1842     for param in &ast_generics.params {
1843         if let GenericParamKind::Type { .. } = param.kind {
1844             let name = param.name.ident().as_interned_str();
1845             let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
1846             index += 1;
1847
1848             let sized = SizedByDefault::Yes;
1849             let bounds = compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
1850             predicates.extend(bounds.predicates(tcx, param_ty));
1851         }
1852     }
1853
1854     // Add in the bounds that appear in the where-clause
1855     let where_clause = &ast_generics.where_clause;
1856     for predicate in &where_clause.predicates {
1857         match predicate {
1858             &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1859                 let ty = icx.to_ty(&bound_pred.bounded_ty);
1860
1861                 // Keep the type around in a dummy predicate, in case of no bounds.
1862                 // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
1863                 // is still checked for WF.
1864                 if bound_pred.bounds.is_empty() {
1865                     if let ty::Param(_) = ty.sty {
1866                         // This is a `where T:`, which can be in the HIR from the
1867                         // transformation that moves `?Sized` to `T`'s declaration.
1868                         // We can skip the predicate because type parameters are
1869                         // trivially WF, but also we *should*, to avoid exposing
1870                         // users who never wrote `where Type:,` themselves, to
1871                         // compiler/tooling bugs from not handling WF predicates.
1872                     } else {
1873                         let span = bound_pred.bounded_ty.span;
1874                         let predicate = ty::OutlivesPredicate(ty, tcx.mk_region(ty::ReEmpty));
1875                         predicates.push(
1876                             (ty::Predicate::TypeOutlives(ty::Binder::dummy(predicate)), span)
1877                         );
1878                     }
1879                 }
1880
1881                 for bound in bound_pred.bounds.iter() {
1882                     match bound {
1883                         &hir::GenericBound::Trait(ref poly_trait_ref, _) => {
1884                             let mut projections = Vec::new();
1885
1886                             let (trait_ref, _) = AstConv::instantiate_poly_trait_ref(
1887                                 &icx,
1888                                 poly_trait_ref,
1889                                 ty,
1890                                 &mut projections,
1891                             );
1892
1893                             predicates.extend(
1894                                 iter::once((trait_ref.to_predicate(), poly_trait_ref.span)).chain(
1895                                     projections.iter().map(|&(p, span)| (p.to_predicate(), span)
1896                             )));
1897                         }
1898
1899                         &hir::GenericBound::Outlives(ref lifetime) => {
1900                             let region = AstConv::ast_region_to_region(&icx, lifetime, None);
1901                             let pred = ty::Binder::bind(ty::OutlivesPredicate(ty, region));
1902                             predicates.push((ty::Predicate::TypeOutlives(pred), lifetime.span))
1903                         }
1904                     }
1905                 }
1906             }
1907
1908             &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1909                 let r1 = AstConv::ast_region_to_region(&icx, &region_pred.lifetime, None);
1910                 predicates.extend(region_pred.bounds.iter().map(|bound| {
1911                     let (r2, span) = match bound {
1912                         hir::GenericBound::Outlives(lt) => {
1913                             (AstConv::ast_region_to_region(&icx, lt, None), lt.span)
1914                         }
1915                         _ => bug!(),
1916                     };
1917                     let pred = ty::Binder::bind(ty::OutlivesPredicate(r1, r2));
1918
1919                     (ty::Predicate::RegionOutlives(pred), span)
1920                 }))
1921             }
1922
1923             &hir::WherePredicate::EqPredicate(..) => {
1924                 // FIXME(#20041)
1925             }
1926         }
1927     }
1928
1929     // Add predicates from associated type bounds.
1930     if let Some((self_trait_ref, trait_items)) = is_trait {
1931         predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1932             let trait_item = tcx.hir().trait_item(trait_item_ref.id);
1933             let bounds = match trait_item.node {
1934                 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1935                 _ => return vec![].into_iter()
1936             };
1937
1938             let assoc_ty =
1939                 tcx.mk_projection(tcx.hir().local_def_id(trait_item.id), self_trait_ref.substs);
1940
1941             let bounds = compute_bounds(
1942                 &ItemCtxt::new(tcx, def_id),
1943                 assoc_ty,
1944                 bounds,
1945                 SizedByDefault::Yes,
1946                 trait_item.span,
1947             );
1948
1949             bounds.predicates(tcx, assoc_ty).into_iter()
1950         }))
1951     }
1952
1953     let mut predicates = predicates.predicates;
1954
1955     // Subtle: before we store the predicates into the tcx, we
1956     // sort them so that predicates like `T: Foo<Item=U>` come
1957     // before uses of `U`.  This avoids false ambiguity errors
1958     // in trait checking. See `setup_constraining_predicates`
1959     // for details.
1960     if let Node::Item(&Item {
1961         node: ItemKind::Impl(..),
1962         ..
1963     }) = node
1964     {
1965         let self_ty = tcx.type_of(def_id);
1966         let trait_ref = tcx.impl_trait_ref(def_id);
1967         ctp::setup_constraining_predicates(
1968             tcx,
1969             &mut predicates,
1970             trait_ref,
1971             &mut ctp::parameters_for_impl(self_ty, trait_ref),
1972         );
1973     }
1974
1975     Lrc::new(ty::GenericPredicates {
1976         parent: generics.parent,
1977         predicates,
1978     })
1979 }
1980
1981 pub enum SizedByDefault {
1982     Yes,
1983     No,
1984 }
1985
1986 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty`
1987 /// or a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1988 /// built-in trait `Send`.
1989 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
1990     astconv: &dyn AstConv<'gcx, 'tcx>,
1991     param_ty: Ty<'tcx>,
1992     ast_bounds: &[hir::GenericBound],
1993     sized_by_default: SizedByDefault,
1994     span: Span,
1995 ) -> Bounds<'tcx> {
1996     let mut region_bounds = Vec::new();
1997     let mut trait_bounds = Vec::new();
1998
1999     for ast_bound in ast_bounds {
2000         match *ast_bound {
2001             hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => trait_bounds.push(b),
2002             hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
2003             hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
2004         }
2005     }
2006
2007     let mut projection_bounds = Vec::new();
2008
2009     let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
2010         let (poly_trait_ref, _) = astconv.instantiate_poly_trait_ref(
2011             bound,
2012             param_ty,
2013             &mut projection_bounds,
2014         );
2015         (poly_trait_ref, bound.span)
2016     }).collect();
2017
2018     let region_bounds = region_bounds
2019         .into_iter()
2020         .map(|r| (astconv.ast_region_to_region(r, None), r.span))
2021         .collect();
2022
2023     trait_bounds.sort_by_key(|(t, _)| t.def_id());
2024
2025     let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
2026         if !is_unsized(astconv, ast_bounds, span) {
2027             Some(span)
2028         } else {
2029             None
2030         }
2031     } else {
2032         None
2033     };
2034
2035     Bounds {
2036         region_bounds,
2037         implicitly_sized,
2038         trait_bounds,
2039         projection_bounds,
2040     }
2041 }
2042
2043 /// Converts a specific `GenericBound` from the AST into a set of
2044 /// predicates that apply to the self-type. A vector is returned
2045 /// because this can be anywhere from zero predicates (`T : ?Sized` adds no
2046 /// predicates) to one (`T : Foo`) to many (`T : Bar<X=i32>` adds `T : Bar`
2047 /// and `<T as Bar>::X == i32`).
2048 fn predicates_from_bound<'tcx>(
2049     astconv: &dyn AstConv<'tcx, 'tcx>,
2050     param_ty: Ty<'tcx>,
2051     bound: &hir::GenericBound,
2052 ) -> Vec<(ty::Predicate<'tcx>, Span)> {
2053     match *bound {
2054         hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
2055             let mut projections = Vec::new();
2056             let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections);
2057             iter::once((pred.to_predicate(), tr.span)).chain(
2058                 projections
2059                     .into_iter()
2060                     .map(|(p, span)| (p.to_predicate(), span))
2061             ).collect()
2062         }
2063         hir::GenericBound::Outlives(ref lifetime) => {
2064             let region = astconv.ast_region_to_region(lifetime, None);
2065             let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region));
2066             vec![(ty::Predicate::TypeOutlives(pred), lifetime.span)]
2067         }
2068         hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![],
2069     }
2070 }
2071
2072 fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
2073     tcx: TyCtxt<'a, 'tcx, 'tcx>,
2074     def_id: DefId,
2075     decl: &hir::FnDecl,
2076     abi: abi::Abi,
2077 ) -> ty::PolyFnSig<'tcx> {
2078     let unsafety = if abi == abi::Abi::RustIntrinsic {
2079         match &*tcx.item_name(def_id).as_str() {
2080             "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
2081             _ => hir::Unsafety::Unsafe,
2082         }
2083     } else {
2084         hir::Unsafety::Unsafe
2085     };
2086     let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl);
2087
2088     // feature gate SIMD types in FFI, since I (huonw) am not sure the
2089     // ABIs are handled at all correctly.
2090     if abi != abi::Abi::RustIntrinsic
2091         && abi != abi::Abi::PlatformIntrinsic
2092         && !tcx.features().simd_ffi
2093     {
2094         let check = |ast_ty: &hir::Ty, ty: Ty| {
2095             if ty.is_simd() {
2096                 tcx.sess
2097                    .struct_span_err(
2098                        ast_ty.span,
2099                        &format!(
2100                            "use of SIMD type `{}` in FFI is highly experimental and \
2101                             may result in invalid code",
2102                            tcx.hir().node_to_pretty_string(ast_ty.id)
2103                        ),
2104                    )
2105                    .help("add #![feature(simd_ffi)] to the crate attributes to enable")
2106                    .emit();
2107             }
2108         };
2109         for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
2110             check(&input, ty)
2111         }
2112         if let hir::Return(ref ty) = decl.output {
2113             check(&ty, *fty.output().skip_binder())
2114         }
2115     }
2116
2117     fty
2118 }
2119
2120 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
2121     match tcx.hir().get_if_local(def_id) {
2122         Some(Node::ForeignItem(..)) => true,
2123         Some(_) => false,
2124         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id),
2125     }
2126 }
2127
2128 fn from_target_feature(
2129     tcx: TyCtxt,
2130     id: DefId,
2131     attr: &ast::Attribute,
2132     whitelist: &FxHashMap<String, Option<String>>,
2133     target_features: &mut Vec<Symbol>,
2134 ) {
2135     let list = match attr.meta_item_list() {
2136         Some(list) => list,
2137         None => {
2138             let msg = "#[target_feature] attribute must be of the form \
2139                        #[target_feature(..)]";
2140             tcx.sess.span_err(attr.span, &msg);
2141             return;
2142         }
2143     };
2144     let rust_features = tcx.features();
2145     for item in list {
2146         // Only `enable = ...` is accepted in the meta item list
2147         if !item.check_name("enable") {
2148             let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
2149                        currently";
2150             tcx.sess.span_err(item.span, &msg);
2151             continue;
2152         }
2153
2154         // Must be of the form `enable = "..."` ( a string)
2155         let value = match item.value_str() {
2156             Some(value) => value,
2157             None => {
2158                 let msg = "#[target_feature] attribute must be of the form \
2159                            #[target_feature(enable = \"..\")]";
2160                 tcx.sess.span_err(item.span, &msg);
2161                 continue;
2162             }
2163         };
2164
2165         // We allow comma separation to enable multiple features
2166         target_features.extend(value.as_str().split(',').filter_map(|feature| {
2167             // Only allow whitelisted features per platform
2168             let feature_gate = match whitelist.get(feature) {
2169                 Some(g) => g,
2170                 None => {
2171                     let msg = format!(
2172                         "the feature named `{}` is not valid for \
2173                          this target",
2174                         feature
2175                     );
2176                     let mut err = tcx.sess.struct_span_err(item.span, &msg);
2177
2178                     if feature.starts_with("+") {
2179                         let valid = whitelist.contains_key(&feature[1..]);
2180                         if valid {
2181                             err.help("consider removing the leading `+` in the feature name");
2182                         }
2183                     }
2184                     err.emit();
2185                     return None;
2186                 }
2187             };
2188
2189             // Only allow features whose feature gates have been enabled
2190             let allowed = match feature_gate.as_ref().map(|s| &**s) {
2191                 Some("arm_target_feature") => rust_features.arm_target_feature,
2192                 Some("aarch64_target_feature") => rust_features.aarch64_target_feature,
2193                 Some("hexagon_target_feature") => rust_features.hexagon_target_feature,
2194                 Some("powerpc_target_feature") => rust_features.powerpc_target_feature,
2195                 Some("mips_target_feature") => rust_features.mips_target_feature,
2196                 Some("avx512_target_feature") => rust_features.avx512_target_feature,
2197                 Some("mmx_target_feature") => rust_features.mmx_target_feature,
2198                 Some("sse4a_target_feature") => rust_features.sse4a_target_feature,
2199                 Some("tbm_target_feature") => rust_features.tbm_target_feature,
2200                 Some("wasm_target_feature") => rust_features.wasm_target_feature,
2201                 Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature,
2202                 Some("adx_target_feature") => rust_features.adx_target_feature,
2203                 Some(name) => bug!("unknown target feature gate {}", name),
2204                 None => true,
2205             };
2206             if !allowed && id.is_local() {
2207                 feature_gate::emit_feature_err(
2208                     &tcx.sess.parse_sess,
2209                     feature_gate.as_ref().unwrap(),
2210                     item.span,
2211                     feature_gate::GateIssue::Language,
2212                     &format!("the target feature `{}` is currently unstable", feature),
2213                 );
2214                 return None;
2215             }
2216             Some(Symbol::intern(feature))
2217         }));
2218     }
2219 }
2220
2221 fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: &str) -> Linkage {
2222     use rustc::mir::mono::Linkage::*;
2223
2224     // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
2225     // applicable to variable declarations and may not really make sense for
2226     // Rust code in the first place but whitelist them anyway and trust that
2227     // the user knows what s/he's doing. Who knows, unanticipated use cases
2228     // may pop up in the future.
2229     //
2230     // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
2231     // and don't have to be, LLVM treats them as no-ops.
2232     match name {
2233         "appending" => Appending,
2234         "available_externally" => AvailableExternally,
2235         "common" => Common,
2236         "extern_weak" => ExternalWeak,
2237         "external" => External,
2238         "internal" => Internal,
2239         "linkonce" => LinkOnceAny,
2240         "linkonce_odr" => LinkOnceODR,
2241         "private" => Private,
2242         "weak" => WeakAny,
2243         "weak_odr" => WeakODR,
2244         _ => {
2245             let span = tcx.hir().span_if_local(def_id);
2246             if let Some(span) = span {
2247                 tcx.sess.span_fatal(span, "invalid linkage specified")
2248             } else {
2249                 tcx.sess
2250                    .fatal(&format!("invalid linkage specified: {}", name))
2251             }
2252         }
2253     }
2254 }
2255
2256 fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> CodegenFnAttrs {
2257     let attrs = tcx.get_attrs(id);
2258
2259     let mut codegen_fn_attrs = CodegenFnAttrs::new();
2260
2261     let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
2262
2263     let mut inline_span = None;
2264     for attr in attrs.iter() {
2265         if attr.check_name("cold") {
2266             codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
2267         } else if attr.check_name("allocator") {
2268             codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
2269         } else if attr.check_name("unwind") {
2270             codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND;
2271         } else if attr.check_name("rustc_allocator_nounwind") {
2272             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
2273         } else if attr.check_name("naked") {
2274             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
2275         } else if attr.check_name("no_mangle") {
2276             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
2277         } else if attr.check_name("rustc_std_internal_symbol") {
2278             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
2279         } else if attr.check_name("no_debug") {
2280             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_DEBUG;
2281         } else if attr.check_name("used") {
2282             codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
2283         } else if attr.check_name("thread_local") {
2284             codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
2285         } else if attr.check_name("inline") {
2286             codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
2287                 if attr.path != "inline" {
2288                     return ia;
2289                 }
2290                 let meta = match attr.meta() {
2291                     Some(meta) => meta.node,
2292                     None => return ia,
2293                 };
2294                 match meta {
2295                     MetaItemKind::Word => {
2296                         mark_used(attr);
2297                         InlineAttr::Hint
2298                     }
2299                     MetaItemKind::List(ref items) => {
2300                         mark_used(attr);
2301                         inline_span = Some(attr.span);
2302                         if items.len() != 1 {
2303                             span_err!(
2304                                 tcx.sess.diagnostic(),
2305                                 attr.span,
2306                                 E0534,
2307                                 "expected one argument"
2308                             );
2309                             InlineAttr::None
2310                         } else if list_contains_name(&items[..], "always") {
2311                             InlineAttr::Always
2312                         } else if list_contains_name(&items[..], "never") {
2313                             InlineAttr::Never
2314                         } else {
2315                             span_err!(
2316                                 tcx.sess.diagnostic(),
2317                                 items[0].span,
2318                                 E0535,
2319                                 "invalid argument"
2320                             );
2321
2322                             InlineAttr::None
2323                         }
2324                     }
2325                     _ => ia,
2326                 }
2327             });
2328         } else if attr.check_name("export_name") {
2329             if let Some(s) = attr.value_str() {
2330                 if s.as_str().contains("\0") {
2331                     // `#[export_name = ...]` will be converted to a null-terminated string,
2332                     // so it may not contain any null characters.
2333                     struct_span_err!(
2334                         tcx.sess,
2335                         attr.span,
2336                         E0648,
2337                         "`export_name` may not contain null characters"
2338                     ).emit();
2339                 }
2340                 codegen_fn_attrs.export_name = Some(s);
2341             } else {
2342                 struct_span_err!(
2343                     tcx.sess,
2344                     attr.span,
2345                     E0558,
2346                     "`export_name` attribute has invalid format"
2347                 ).span_label(attr.span, "did you mean #[export_name=\"*\"]?")
2348                  .emit();
2349             }
2350         } else if attr.check_name("target_feature") {
2351             if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
2352                 let msg = "#[target_feature(..)] can only be applied to \
2353                            `unsafe` function";
2354                 tcx.sess.span_err(attr.span, msg);
2355             }
2356             from_target_feature(
2357                 tcx,
2358                 id,
2359                 attr,
2360                 &whitelist,
2361                 &mut codegen_fn_attrs.target_features,
2362             );
2363         } else if attr.check_name("linkage") {
2364             if let Some(val) = attr.value_str() {
2365                 codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
2366             }
2367         } else if attr.check_name("link_section") {
2368             if let Some(val) = attr.value_str() {
2369                 if val.as_str().bytes().any(|b| b == 0) {
2370                     let msg = format!(
2371                         "illegal null byte in link_section \
2372                          value: `{}`",
2373                         &val
2374                     );
2375                     tcx.sess.span_err(attr.span, &msg);
2376                 } else {
2377                     codegen_fn_attrs.link_section = Some(val);
2378                 }
2379             }
2380         } else if attr.check_name("link_name") {
2381             codegen_fn_attrs.link_name = attr.value_str();
2382         }
2383     }
2384
2385     // If a function uses #[target_feature] it can't be inlined into general
2386     // purpose functions as they wouldn't have the right target features
2387     // enabled. For that reason we also forbid #[inline(always)] as it can't be
2388     // respected.
2389     if codegen_fn_attrs.target_features.len() > 0 {
2390         if codegen_fn_attrs.inline == InlineAttr::Always {
2391             if let Some(span) = inline_span {
2392                 tcx.sess.span_err(
2393                     span,
2394                     "cannot use #[inline(always)] with \
2395                      #[target_feature]",
2396                 );
2397             }
2398         }
2399     }
2400
2401     // Weak lang items have the same semantics as "std internal" symbols in the
2402     // sense that they're preserved through all our LTO passes and only
2403     // strippable by the linker.
2404     //
2405     // Additionally weak lang items have predetermined symbol names.
2406     if tcx.is_weak_lang_item(id) {
2407         codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
2408     }
2409     if let Some(name) = weak_lang_items::link_name(&attrs) {
2410         codegen_fn_attrs.export_name = Some(name);
2411         codegen_fn_attrs.link_name = Some(name);
2412     }
2413
2414     // Internal symbols to the standard library all have no_mangle semantics in
2415     // that they have defined symbol names present in the function name. This
2416     // also applies to weak symbols where they all have known symbol names.
2417     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
2418         codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
2419     }
2420
2421     codegen_fn_attrs
2422 }