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