1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 The collect phase of type check has the job of visiting all items,
16 determining their type, and writing that type into the `tcx.types`
17 table. Despite its name, this table does not really operate as a
18 *cache*, at least not for the types of items defined within the
19 current crate: we assume that after the collect phase, the types of
20 all local items will be present in the table.
22 Unlike most of the types that are present in Rust, the types computed
23 for each item are in fact type schemes. This means that they are
24 generic types that may have type parameters. TypeSchemes are
25 represented by a pair of `Generics` and `Ty`. Type
26 parameters themselves are represented as `ty_param()` instances.
28 The phasing of type conversion is somewhat complicated. There is no
29 clear set of phases we can enforce (e.g., converting traits first,
30 then types, or something like that) because the user can introduce
31 arbitrary interdependencies. So instead we generally convert things
32 lazilly and on demand, and include logic that checks for cycles.
33 Demand is driven by calls to `AstConv::get_item_type_scheme` or
34 `AstConv::lookup_trait_def`.
36 Currently, we "convert" types and traits in two phases (note that
37 conversion only affects the types of items / enum variants / methods;
38 it does not e.g. compute the types of individual expressions):
41 1. Trait/Type definitions
43 Conversion itself is done by simply walking each of the items in turn
44 and invoking an appropriate function (e.g., `trait_def_of_item` or
45 `convert_item`). However, it is possible that while converting an
46 item, we may need to compute the *type scheme* or *trait definition*
49 There are some shortcomings in this design:
50 - Because the item generics include defaults, cycles through type
51 parameter defaults are illegal even if those defaults are never
52 employed. This is not necessarily a bug.
56 use astconv::{AstConv, Bounds};
58 use constrained_type_params as ctp;
59 use middle::lang_items::SizedTraitLangItem;
60 use middle::const_val::ConstVal;
61 use middle::resolve_lifetime as rl;
62 use rustc_const_eval::{ConstContext, report_const_eval_err};
63 use rustc::ty::subst::Substs;
64 use rustc::ty::{ToPredicate, ReprOptions};
65 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
66 use rustc::ty::maps::Providers;
67 use rustc::ty::util::IntTypeExt;
68 use rustc::dep_graph::DepNode;
69 use util::common::MemoizationMap;
70 use util::nodemap::{NodeMap, FxHashMap};
72 use rustc_const_math::ConstInt;
74 use std::cell::RefCell;
75 use std::collections::BTreeMap;
77 use syntax::{abi, ast};
78 use syntax::codemap::Spanned;
79 use syntax::symbol::{Symbol, keywords};
80 use syntax_pos::{Span, DUMMY_SP};
82 use rustc::hir::{self, map as hir_map};
83 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
84 use rustc::hir::def::{Def, CtorKind};
85 use rustc::hir::def_id::DefId;
87 ///////////////////////////////////////////////////////////////////////////
90 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
91 let mut visitor = CollectItemTypesVisitor { tcx: tcx };
92 tcx.visit_all_item_likes_in_krate(DepNode::CollectItem, &mut visitor.as_deep_visitor());
95 pub fn provide(providers: &mut Providers) {
96 *providers = Providers {
101 type_param_predicates,
109 ///////////////////////////////////////////////////////////////////////////
111 /// Context specific to some particular item. This is what implements
112 /// AstConv. It has information about the predicates that are defined
113 /// on the trait. Unfortunately, this predicate information is
114 /// available in various different forms at various points in the
115 /// process. So we can't just store a pointer to e.g. the AST or the
116 /// parsed ty form, we have to be more flexible. To this end, the
117 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
118 /// `get_type_parameter_bounds` requests, drawing the information from
119 /// the AST (`hir::Generics`), recursively.
120 struct ItemCtxt<'a,'tcx:'a> {
121 tcx: TyCtxt<'a, 'tcx, 'tcx>,
125 ///////////////////////////////////////////////////////////////////////////
127 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
128 tcx: TyCtxt<'a, 'tcx, 'tcx>
131 impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> {
132 /// Collect item types is structured into two tasks. The outer
133 /// task, `CollectItem`, walks the entire content of an item-like
134 /// thing, including its body. It also spawns an inner task,
135 /// `CollectItemSig`, which walks only the signature. This inner
136 /// task is the one that writes the item-type into the various
137 /// maps. This setup ensures that the item body is never
138 /// accessible to the task that computes its signature, so that
139 /// changes to the body don't affect the signature.
141 /// Consider an example function `foo` that also has a closure in its body:
146 /// let bar = || ...; // we'll label this closure as "bar" below
150 /// This results in a dep-graph like so. I've labeled the edges to
151 /// document where they arise.
154 /// [HirBody(foo)] -2--> [CollectItem(foo)] -4-> [ItemSignature(bar)]
157 /// [Hir(foo)] -----------+-6-> [CollectItemSig(foo)] -5-> [ItemSignature(foo)]
160 /// 1. This is added by the `visit_all_item_likes_in_krate`.
161 /// 2. This is added when we fetch the item body.
162 /// 3. This is added because `CollectItem` launches `CollectItemSig`.
163 /// - it is arguably false; if we refactor the `with_task` system;
164 /// we could get probably rid of it, but it is also harmless enough.
165 /// 4. This is added by the code in `visit_expr` when we write to `item_types`.
166 /// 5. This is added by the code in `convert_item` when we write to `item_types`;
167 /// note that this write occurs inside the `CollectItemSig` task.
168 /// 6. Added by reads from within `op`.
169 fn with_collect_item_sig(&self, id: ast::NodeId, op: fn(TyCtxt<'a, 'tcx, 'tcx>, ast::NodeId)) {
170 let def_id = self.tcx.hir.local_def_id(id);
171 self.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), self.tcx, id, op);
175 impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
176 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
177 NestedVisitorMap::OnlyBodies(&self.tcx.hir)
180 fn visit_item(&mut self, item: &'tcx hir::Item) {
181 self.with_collect_item_sig(item.id, convert_item);
182 intravisit::walk_item(self, item);
185 fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
186 for param in &generics.ty_params {
187 if param.default.is_some() {
188 let def_id = self.tcx.hir.local_def_id(param.id);
189 self.tcx.item_type(def_id);
192 intravisit::walk_generics(self, generics);
195 fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
196 if let hir::ExprClosure(..) = expr.node {
197 let def_id = self.tcx.hir.local_def_id(expr.id);
198 self.tcx.item_generics(def_id);
199 self.tcx.item_type(def_id);
201 intravisit::walk_expr(self, expr);
204 fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
205 if let hir::TyImplTrait(..) = ty.node {
206 let def_id = self.tcx.hir.local_def_id(ty.id);
207 self.tcx.item_generics(def_id);
208 self.tcx.item_predicates(def_id);
210 intravisit::walk_ty(self, ty);
213 fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
214 self.with_collect_item_sig(trait_item.id, convert_trait_item);
215 intravisit::walk_trait_item(self, trait_item);
218 fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
219 self.with_collect_item_sig(impl_item.id, convert_impl_item);
220 intravisit::walk_impl_item(self, impl_item);
224 ///////////////////////////////////////////////////////////////////////////
225 // Utility types and common code for the above passes.
227 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
228 fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
229 -> ItemCtxt<'a,'tcx> {
232 item_def_id: item_def_id,
237 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
238 fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
239 AstConv::ast_ty_to_ty(self, ast_ty)
243 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
244 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx }
246 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
247 &self.tcx.ast_ty_to_ty_cache
250 fn get_type_parameter_bounds(&self,
253 -> ty::GenericPredicates<'tcx>
255 ty::queries::type_param_predicates::get(self.tcx, span, (self.item_def_id, def_id))
258 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
262 fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
263 -> Option<&'tcx ty::Region> {
267 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
272 "the type placeholder `_` is not allowed within types on item signatures"
273 ).span_label(span, &format!("not allowed in type signatures"))
278 fn projected_ty_from_poly_trait_ref(&self,
280 poly_trait_ref: ty::PolyTraitRef<'tcx>,
281 item_name: ast::Name)
284 if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
285 self.tcx().mk_projection(trait_ref, item_name)
287 // no late-bound regions, we can just ignore the binder
288 span_err!(self.tcx().sess, span, E0212,
289 "cannot extract an associated type from a higher-ranked trait bound \
295 fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
296 // types in item signatures are not normalized, to avoid undue
301 fn set_tainted_by_errors(&self) {
302 // no obvious place to track this, just let it go
306 fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
307 (item_def_id, def_id): (DefId, DefId))
308 -> ty::GenericPredicates<'tcx> {
309 use rustc::hir::map::*;
312 // In the AST, bounds can derive from two places. Either
313 // written inline like `<T:Foo>` or in a where clause like
316 let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
317 let param_owner = tcx.hir.ty_param_owner(param_id);
318 let param_owner_def_id = tcx.hir.local_def_id(param_owner);
319 let generics = tcx.item_generics(param_owner_def_id);
320 let index = generics.type_param_to_index[&def_id.index];
321 let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id));
323 // Don't look for bounds where the type parameter isn't in scope.
324 let parent = if item_def_id == param_owner_def_id {
327 tcx.item_generics(item_def_id).parent
330 let mut result = parent.map_or(ty::GenericPredicates {
334 let icx = ItemCtxt::new(tcx, parent);
335 icx.get_type_parameter_bounds(DUMMY_SP, def_id)
338 let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
339 let ast_generics = match tcx.hir.get(item_node_id) {
340 NodeTraitItem(item) => {
342 TraitItemKind::Method(ref sig, _) => &sig.generics,
347 NodeImplItem(item) => {
349 ImplItemKind::Method(ref sig, _) => &sig.generics,
356 ItemFn(.., ref generics, _) |
357 ItemImpl(_, _, ref generics, ..) |
358 ItemTy(_, ref generics) |
359 ItemEnum(_, ref generics) |
360 ItemStruct(_, ref generics) |
361 ItemUnion(_, ref generics) => generics,
362 ItemTrait(_, ref generics, ..) => {
363 // Implied `Self: Trait` and supertrait bounds.
364 if param_id == item_node_id {
365 result.predicates.push(ty::TraitRef {
367 substs: Substs::identity_for_item(tcx, item_def_id)
376 NodeForeignItem(item) => {
378 ForeignItemFn(_, _, ref generics) => generics,
386 let icx = ItemCtxt::new(tcx, item_def_id);
387 result.predicates.extend(
388 icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty));
392 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
393 /// Find bounds from hir::Generics. This requires scanning through the
394 /// AST. We do this to avoid having to convert *all* the bounds, which
395 /// would create artificial cycles. Instead we can only convert the
396 /// bounds for a type parameter `X` if `X::Foo` is used.
397 fn type_parameter_bounds_in_generics(&self,
398 ast_generics: &hir::Generics,
399 param_id: ast::NodeId,
401 -> Vec<ty::Predicate<'tcx>>
404 ast_generics.ty_params
406 .filter(|p| p.id == param_id)
407 .flat_map(|p| p.bounds.iter())
408 .flat_map(|b| predicates_from_bound(self, ty, b));
410 let from_where_clauses =
411 ast_generics.where_clause
414 .filter_map(|wp| match *wp {
415 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
418 .filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id))
419 .flat_map(|bp| bp.bounds.iter())
420 .flat_map(|b| predicates_from_bound(self, ty, b));
422 from_ty_params.chain(from_where_clauses).collect()
426 /// Tests whether this is the AST for a reference to the type
427 /// parameter with id `param_id`. We use this so as to avoid running
428 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
429 /// conversion of the type to avoid inducing unnecessary cycles.
430 fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
432 param_id: ast::NodeId)
435 if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
437 Def::SelfTy(Some(def_id), None) |
438 Def::TyParam(def_id) => {
439 def_id == tcx.hir.local_def_id(param_id)
448 fn ensure_no_ty_param_bounds(tcx: TyCtxt,
450 generics: &hir::Generics,
451 thing: &'static str) {
452 let mut warn = false;
454 for ty_param in generics.ty_params.iter() {
455 for bound in ty_param.bounds.iter() {
457 hir::TraitTyParamBound(..) => {
460 hir::RegionTyParamBound(..) => { }
465 for predicate in generics.where_clause.predicates.iter() {
467 hir::WherePredicate::BoundPredicate(..) => {
470 hir::WherePredicate::RegionPredicate(..) => { }
471 hir::WherePredicate::EqPredicate(..) => { }
476 // According to accepted RFC #XXX, we should
477 // eventually accept these, but it will not be
478 // part of this PR. Still, convert to warning to
479 // make bootstrapping easier.
480 span_warn!(tcx.sess, span, E0122,
481 "trait bounds are not (yet) enforced \
487 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
488 let it = tcx.hir.expect_item(item_id);
489 debug!("convert: item {} with id {}", it.name, it.id);
490 let def_id = tcx.hir.local_def_id(item_id);
492 // These don't define types.
493 hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
495 hir::ItemForeignMod(ref foreign_mod) => {
496 for item in &foreign_mod.items {
497 let def_id = tcx.hir.local_def_id(item.id);
498 tcx.item_generics(def_id);
499 tcx.item_type(def_id);
500 tcx.item_predicates(def_id);
503 hir::ItemEnum(ref enum_definition, _) => {
504 tcx.item_generics(def_id);
505 tcx.item_type(def_id);
506 tcx.item_predicates(def_id);
507 convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
509 hir::ItemDefaultImpl(..) => {
510 tcx.impl_trait_ref(def_id);
512 hir::ItemImpl(..) => {
513 tcx.item_generics(def_id);
514 tcx.item_type(def_id);
515 tcx.impl_trait_ref(def_id);
516 tcx.item_predicates(def_id);
518 hir::ItemTrait(..) => {
519 tcx.item_generics(def_id);
520 tcx.lookup_trait_def(def_id);
521 ty::queries::super_predicates::get(tcx, it.span, def_id);
522 tcx.item_predicates(def_id);
524 hir::ItemStruct(ref struct_def, _) |
525 hir::ItemUnion(ref struct_def, _) => {
526 tcx.item_generics(def_id);
527 tcx.item_type(def_id);
528 tcx.item_predicates(def_id);
530 for f in struct_def.fields() {
531 let def_id = tcx.hir.local_def_id(f.id);
532 tcx.item_generics(def_id);
533 tcx.item_type(def_id);
534 tcx.item_predicates(def_id);
537 if !struct_def.is_struct() {
538 convert_variant_ctor(tcx, struct_def.id());
541 hir::ItemTy(_, ref generics) => {
542 ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
543 tcx.item_generics(def_id);
544 tcx.item_type(def_id);
545 tcx.item_predicates(def_id);
548 tcx.item_generics(def_id);
549 tcx.item_type(def_id);
550 tcx.item_predicates(def_id);
555 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
556 let trait_item = tcx.hir.expect_trait_item(trait_item_id);
557 let def_id = tcx.hir.local_def_id(trait_item.id);
558 tcx.item_generics(def_id);
560 match trait_item.node {
561 hir::TraitItemKind::Const(..) |
562 hir::TraitItemKind::Type(_, Some(_)) |
563 hir::TraitItemKind::Method(..) => {
564 tcx.item_type(def_id);
567 hir::TraitItemKind::Type(_, None) => {}
570 tcx.item_predicates(def_id);
573 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
574 let def_id = tcx.hir.local_def_id(impl_item_id);
575 tcx.item_generics(def_id);
576 tcx.item_type(def_id);
577 tcx.item_predicates(def_id);
580 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
581 ctor_id: ast::NodeId) {
582 let def_id = tcx.hir.local_def_id(ctor_id);
583 tcx.item_generics(def_id);
584 tcx.item_type(def_id);
585 tcx.item_predicates(def_id);
588 fn evaluate_disr_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
590 -> Result<ConstVal<'tcx>, ()> {
591 let e = &tcx.hir.body(body).value;
592 ConstContext::new(tcx, body).eval(e).map_err(|err| {
593 // enum variant evaluation happens before the global constant check
594 // so we need to report the real error
595 report_const_eval_err(tcx, &err, e.span, "enum discriminant");
599 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
601 variants: &[hir::Variant]) {
602 let def = tcx.lookup_adt_def(def_id);
603 let repr_type = def.repr.discr_type();
604 let initial = repr_type.initial_discriminant(tcx);
605 let mut prev_discr = None::<ConstInt>;
607 // fill the discriminant values and field types
608 for variant in variants {
609 let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr());
610 prev_discr = Some(if let Some(e) = variant.node.disr_expr {
611 let expr_did = tcx.hir.local_def_id(e.node_id);
612 let result = tcx.maps.monomorphic_const_eval.memoize(expr_did, || {
613 evaluate_disr_expr(tcx, e)
617 Ok(ConstVal::Integral(x)) => Some(x),
620 } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
623 struct_span_err!(tcx.sess, variant.span, E0370,
624 "enum discriminant overflowed")
625 .span_label(variant.span, &format!("overflowed on value after {}",
626 prev_discr.unwrap()))
627 .note(&format!("explicitly set `{} = {}` if that is desired outcome",
628 variant.node.name, wrapped_discr))
631 }.unwrap_or(wrapped_discr));
633 for f in variant.node.data.fields() {
634 let def_id = tcx.hir.local_def_id(f.id);
635 tcx.item_generics(def_id);
636 tcx.item_type(def_id);
637 tcx.item_predicates(def_id);
640 // Convert the ctor, if any. This also registers the variant as
642 convert_variant_ctor(tcx, variant.node.data.id());
646 fn convert_struct_variant<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
649 discr: ty::VariantDiscr,
650 def: &hir::VariantData)
652 let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
653 let node_id = tcx.hir.as_local_node_id(did).unwrap();
654 let fields = def.fields().iter().map(|f| {
655 let fid = tcx.hir.local_def_id(f.id);
656 let dup_span = seen_fields.get(&f.name).cloned();
657 if let Some(prev_span) = dup_span {
658 struct_span_err!(tcx.sess, f.span, E0124,
659 "field `{}` is already declared",
661 .span_label(f.span, &"field already declared")
662 .span_label(prev_span, &format!("`{}` first declared here", f.name))
665 seen_fields.insert(f.name, f.span);
671 vis: ty::Visibility::from_hir(&f.vis, node_id, tcx)
679 ctor_kind: CtorKind::from_hir(def),
683 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
685 -> &'tcx ty::AdtDef {
686 use rustc::hir::map::*;
689 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
690 let item = match tcx.hir.get(node_id) {
691 NodeItem(item) => item,
695 let repr = ReprOptions::new(tcx, def_id);
696 let (kind, variants) = match item.node {
697 ItemEnum(ref def, _) => {
698 let mut distance_from_explicit = 0;
699 (AdtKind::Enum, def.variants.iter().map(|v| {
700 let did = tcx.hir.local_def_id(v.node.data.id());
701 let discr = if let Some(e) = v.node.disr_expr {
702 distance_from_explicit = 0;
703 ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
705 ty::VariantDiscr::Relative(distance_from_explicit)
707 distance_from_explicit += 1;
709 convert_struct_variant(tcx, did, v.node.name, discr, &v.node.data)
712 ItemStruct(ref def, _) => {
713 // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
714 let ctor_id = if !def.is_struct() {
715 Some(tcx.hir.local_def_id(def.id()))
719 (AdtKind::Struct, vec![
720 convert_struct_variant(tcx, ctor_id.unwrap_or(def_id), item.name,
721 ty::VariantDiscr::Relative(0), def)
724 ItemUnion(ref def, _) => {
725 (AdtKind::Union, vec![
726 convert_struct_variant(tcx, def_id, item.name,
727 ty::VariantDiscr::Relative(0), def)
732 tcx.alloc_adt_def(def_id, kind, variants, repr)
735 /// Ensures that the super-predicates of the trait with def-id
736 /// trait_def_id are converted and stored. This also ensures that
737 /// the transitive super-predicates are converted;
738 fn super_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
740 -> ty::GenericPredicates<'tcx> {
741 debug!("super_predicates(trait_def_id={:?})", trait_def_id);
742 let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
744 let item = match tcx.hir.get(trait_node_id) {
745 hir_map::NodeItem(item) => item,
746 _ => bug!("trait_node_id {} is not an item", trait_node_id)
749 let (generics, bounds) = match item.node {
750 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
751 _ => span_bug!(item.span,
752 "super_predicates invoked on non-trait"),
755 let icx = ItemCtxt::new(tcx, trait_def_id);
757 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
758 let self_param_ty = tcx.mk_self_type();
759 let superbounds1 = compute_bounds(&icx,
765 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
767 // Convert any explicit superbounds in the where clause,
768 // e.g. `trait Foo where Self : Bar`:
769 let superbounds2 = icx.type_parameter_bounds_in_generics(generics, item.id, self_param_ty);
771 // Combine the two lists to form the complete set of superbounds:
772 let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
774 // Now require that immediate supertraits are converted,
775 // which will, in turn, reach indirect supertraits.
776 for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) {
777 ty::queries::super_predicates::get(tcx, item.span, bound.def_id());
780 ty::GenericPredicates {
782 predicates: superbounds
786 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
788 -> &'tcx ty::TraitDef {
789 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
790 let item = tcx.hir.expect_item(node_id);
792 let unsafety = match item.node {
793 hir::ItemTrait(unsafety, ..) => unsafety,
794 _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
797 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
798 if paren_sugar && !tcx.sess.features.borrow().unboxed_closures {
799 let mut err = tcx.sess.struct_span_err(
801 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
802 which traits can use parenthetical notation");
804 "add `#![feature(unboxed_closures)]` to \
805 the crate attributes to use it");
809 let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
810 let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash);
812 if tcx.hir.trait_is_auto(def_id) {
813 def.record_has_default_impl();
816 tcx.alloc_trait_def(def)
819 fn generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
821 -> &'tcx ty::Generics {
822 use rustc::hir::map::*;
825 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
827 let node = tcx.hir.get(node_id);
828 let parent_def_id = match node {
834 let parent_id = tcx.hir.get_parent(node_id);
835 Some(tcx.hir.local_def_id(parent_id))
837 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
838 Some(tcx.closure_base_def_id(def_id))
840 NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
841 let mut parent_id = node_id;
843 match tcx.hir.get(parent_id) {
844 NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
846 parent_id = tcx.hir.get_parent_node(parent_id);
850 Some(tcx.hir.local_def_id(parent_id))
855 let mut opt_self = None;
856 let mut allow_defaults = false;
858 let no_generics = hir::Generics::empty();
859 let ast_generics = match node {
860 NodeTraitItem(item) => {
862 TraitItemKind::Method(ref sig, _) => &sig.generics,
867 NodeImplItem(item) => {
869 ImplItemKind::Method(ref sig, _) => &sig.generics,
876 ItemFn(.., ref generics, _) |
877 ItemImpl(_, _, ref generics, ..) => generics,
879 ItemTy(_, ref generics) |
880 ItemEnum(_, ref generics) |
881 ItemStruct(_, ref generics) |
882 ItemUnion(_, ref generics) => {
883 allow_defaults = true;
887 ItemTrait(_, ref generics, ..) => {
888 // Add in the self type parameter.
890 // Something of a hack: use the node id for the trait, also as
891 // the node id for the Self type parameter.
892 let param_id = item.id;
894 opt_self = Some(ty::TypeParameterDef {
896 name: keywords::SelfType.name(),
897 def_id: tcx.hir.local_def_id(param_id),
899 object_lifetime_default: rl::Set1::Empty,
900 pure_wrt_drop: false,
903 allow_defaults = true;
911 NodeForeignItem(item) => {
913 ForeignItemStatic(..) => &no_generics,
914 ForeignItemFn(_, _, ref generics) => generics
921 let has_self = opt_self.is_some();
922 let mut parent_has_self = false;
923 let mut own_start = has_self as u32;
924 let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
925 let generics = tcx.item_generics(def_id);
926 assert_eq!(has_self, false);
927 parent_has_self = generics.has_self;
928 own_start = generics.count() as u32;
929 (generics.parent_regions + generics.regions.len() as u32,
930 generics.parent_types + generics.types.len() as u32)
933 let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
934 let regions = early_lifetimes.enumerate().map(|(i, l)| {
935 let issue_32330 = tcx.named_region_map.issue_32330.get(&l.lifetime.id).cloned();
936 ty::RegionParameterDef {
937 name: l.lifetime.name,
938 index: own_start + i as u32,
939 def_id: tcx.hir.local_def_id(l.lifetime.id),
940 pure_wrt_drop: l.pure_wrt_drop,
941 issue_32330: issue_32330,
943 }).collect::<Vec<_>>();
945 let object_lifetime_defaults =
946 tcx.named_region_map.object_lifetime_defaults.get(&node_id);
948 // Now create the real type parameters.
949 let type_start = own_start + regions.len() as u32;
950 let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
951 if p.name == keywords::SelfType.name() {
952 span_bug!(p.span, "`Self` should not be the name of a regular parameter");
955 if !allow_defaults && p.default.is_some() {
956 if !tcx.sess.features.borrow().default_type_parameter_fallback {
958 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
961 format!("defaults for type parameters are only allowed in `struct`, \
962 `enum`, `type`, or `trait` definitions."));
966 ty::TypeParameterDef {
967 index: type_start + i as u32,
969 def_id: tcx.hir.local_def_id(p.id),
970 has_default: p.default.is_some(),
971 object_lifetime_default:
972 object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
973 pure_wrt_drop: p.pure_wrt_drop,
976 let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
978 // provide junk type parameter defs - the only place that
979 // cares about anything but the length is instantiation,
980 // and we don't do that for closures.
981 if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node {
982 tcx.with_freevars(node_id, |fv| {
983 types.extend(fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
984 index: type_start + i as u32,
985 name: Symbol::intern("<upvar>"),
988 object_lifetime_default: rl::Set1::Empty,
989 pure_wrt_drop: false,
994 let mut type_param_to_index = BTreeMap::new();
995 for param in &types {
996 type_param_to_index.insert(param.def_id.index, param.index);
999 tcx.alloc_generics(ty::Generics {
1000 parent: parent_def_id,
1001 parent_regions: parent_regions,
1002 parent_types: parent_types,
1005 type_param_to_index: type_param_to_index,
1006 has_self: has_self || parent_has_self
1010 fn ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1013 use rustc::hir::map::*;
1016 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1018 let icx = ItemCtxt::new(tcx, def_id);
1020 match tcx.hir.get(node_id) {
1021 NodeTraitItem(item) => {
1023 TraitItemKind::Method(ref sig, _) => {
1024 let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
1025 let substs = Substs::identity_for_item(tcx, def_id);
1026 tcx.mk_fn_def(def_id, substs, fty)
1028 TraitItemKind::Const(ref ty, _) |
1029 TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
1030 TraitItemKind::Type(_, None) => {
1031 span_bug!(item.span, "associated type missing default");
1036 NodeImplItem(item) => {
1038 ImplItemKind::Method(ref sig, _) => {
1039 let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
1040 let substs = Substs::identity_for_item(tcx, def_id);
1041 tcx.mk_fn_def(def_id, substs, fty)
1043 ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
1044 ImplItemKind::Type(ref ty) => {
1045 if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
1046 span_err!(tcx.sess, item.span, E0202,
1047 "associated types are not allowed in inherent impls");
1057 ItemStatic(ref t, ..) | ItemConst(ref t, _) |
1058 ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
1061 ItemFn(ref decl, unsafety, _, abi, _, _) => {
1062 let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl);
1063 let substs = Substs::identity_for_item(tcx, def_id);
1064 tcx.mk_fn_def(def_id, substs, tofd)
1069 let def = tcx.lookup_adt_def(def_id);
1070 let substs = Substs::identity_for_item(tcx, def_id);
1071 tcx.mk_adt(def, substs)
1073 ItemDefaultImpl(..) |
1076 ItemForeignMod(..) |
1077 ItemExternCrate(..) |
1081 "compute_type_of_item: unexpected item type: {:?}",
1087 NodeForeignItem(foreign_item) => {
1088 let abi = tcx.hir.get_foreign_abi(node_id);
1090 match foreign_item.node {
1091 ForeignItemFn(ref fn_decl, _, _) => {
1092 compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1094 ForeignItemStatic(ref t, _) => icx.to_ty(t)
1098 NodeStructCtor(&ref def) |
1099 NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
1100 let ty = tcx.item_type(tcx.hir.get_parent_did(node_id));
1102 VariantData::Unit(..) | VariantData::Struct(..) => ty,
1103 VariantData::Tuple(ref fields, _) => {
1104 let inputs = fields.iter().map(|f| {
1105 tcx.item_type(tcx.hir.local_def_id(f.id))
1107 let substs = Substs::identity_for_item(tcx, def_id);
1108 tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
1112 hir::Unsafety::Normal,
1119 NodeField(field) => icx.to_ty(&field.ty),
1121 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1122 tcx.mk_closure(def_id, Substs::for_item(
1125 let region = def.to_early_bound_region_data();
1126 tcx.mk_region(ty::ReEarlyBound(region))
1128 |def, _| tcx.mk_param_from_def(def)
1132 NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
1133 NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
1134 NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
1135 NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
1136 if body.node_id == node_id => tcx.types.usize,
1138 NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
1139 if e.node_id == node_id => {
1140 tcx.lookup_adt_def(tcx.hir.get_parent_did(node_id))
1141 .repr.discr_type().to_ty(tcx)
1145 bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
1149 NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
1153 NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1154 let owner = tcx.hir.get_parent_did(node_id);
1155 tcx.item_tables(owner).node_id_to_type(node_id)
1159 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1164 fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1166 -> Option<ty::TraitRef<'tcx>> {
1167 let icx = ItemCtxt::new(tcx, def_id);
1169 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1170 match tcx.hir.expect_item(node_id).node {
1171 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
1172 Some(AstConv::instantiate_mono_trait_ref(&icx,
1174 tcx.mk_self_type()))
1176 hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
1177 opt_trait_ref.as_ref().map(|ast_trait_ref| {
1178 let selfty = tcx.item_type(def_id);
1179 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1186 // Is it marked with ?Sized
1187 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1188 ast_bounds: &[hir::TyParamBound],
1191 let tcx = astconv.tcx();
1193 // Try to find an unbound in bounds.
1194 let mut unbound = None;
1195 for ab in ast_bounds {
1196 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1197 if unbound.is_none() {
1198 unbound = Some(ptr.trait_ref.clone());
1200 span_err!(tcx.sess, span, E0203,
1201 "type parameter has more than one relaxed default \
1202 bound, only one is supported");
1207 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1210 // FIXME(#8559) currently requires the unbound to be built-in.
1211 if let Ok(kind_id) = kind_id {
1212 if tpb.path.def != Def::Trait(kind_id) {
1213 tcx.sess.span_warn(span,
1214 "default bound relaxed for a type parameter, but \
1215 this does nothing because the given bound is not \
1216 a default. Only `?Sized` is supported");
1220 _ if kind_id.is_ok() => {
1223 // No lang item for Sized, so we can't add it as a bound.
1230 /// Returns the early-bound lifetimes declared in this generics
1231 /// listing. For anything other than fns/methods, this is just all
1232 /// the lifetimes that are declared. For fns or methods, we have to
1233 /// screen out those that do not appear in any where-clauses etc using
1234 /// `resolve_lifetime::early_bound_lifetimes`.
1235 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1236 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1237 ast_generics: &'a hir::Generics)
1238 -> impl Iterator<Item=&'a hir::LifetimeDef>
1243 .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
1246 fn predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1248 -> ty::GenericPredicates<'tcx> {
1249 use rustc::hir::map::*;
1252 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1253 let node = tcx.hir.get(node_id);
1255 let mut is_trait = None;
1257 let icx = ItemCtxt::new(tcx, def_id);
1258 let no_generics = hir::Generics::empty();
1259 let ast_generics = match node {
1260 NodeTraitItem(item) => {
1262 TraitItemKind::Method(ref sig, _) => &sig.generics,
1267 NodeImplItem(item) => {
1269 ImplItemKind::Method(ref sig, _) => &sig.generics,
1276 ItemFn(.., ref generics, _) |
1277 ItemImpl(_, _, ref generics, ..) |
1278 ItemTy(_, ref generics) |
1279 ItemEnum(_, ref generics) |
1280 ItemStruct(_, ref generics) |
1281 ItemUnion(_, ref generics) => {
1285 ItemTrait(_, ref generics, .., ref items) => {
1286 is_trait = Some((ty::TraitRef {
1288 substs: Substs::identity_for_item(tcx, def_id)
1297 NodeForeignItem(item) => {
1299 ForeignItemStatic(..) => &no_generics,
1300 ForeignItemFn(_, _, ref generics) => generics
1304 NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1305 let substs = Substs::identity_for_item(tcx, def_id);
1306 let anon_ty = tcx.mk_anon(def_id, substs);
1308 // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1309 let bounds = compute_bounds(&icx, anon_ty, bounds,
1310 SizedByDefault::Yes,
1312 return ty::GenericPredicates {
1314 predicates: bounds.predicates(tcx, anon_ty)
1321 let generics = tcx.item_generics(def_id);
1322 let parent_count = generics.parent_count() as u32;
1323 let has_own_self = generics.has_self && parent_count == 0;
1325 let mut predicates = vec![];
1327 // Below we'll consider the bounds on the type parameters (including `Self`)
1328 // and the explicit where-clauses, but to get the full set of predicates
1329 // on a trait we need to add in the supertrait bounds and bounds found on
1330 // associated types.
1331 if let Some((trait_ref, _)) = is_trait {
1332 predicates = tcx.item_super_predicates(def_id).predicates;
1334 // Add in a predicate that `Self:Trait` (where `Trait` is the
1335 // current trait). This is needed for builtin bounds.
1336 predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
1339 // Collect the region predicates that were declared inline as
1340 // well. In the case of parameters declared on a fn or method, we
1341 // have to be careful to only iterate over early-bound regions.
1342 let mut index = parent_count + has_own_self as u32;
1343 for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1344 let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1346 name: param.lifetime.name
1350 for bound in ¶m.bounds {
1351 let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
1352 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1353 predicates.push(outlives.to_predicate());
1357 // Collect the predicates that were written inline by the user on each
1358 // type parameter (e.g., `<T:Foo>`).
1359 for param in &ast_generics.ty_params {
1360 let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
1363 let bounds = compute_bounds(&icx,
1366 SizedByDefault::Yes,
1368 predicates.extend(bounds.predicates(tcx, param_ty));
1371 // Add in the bounds that appear in the where-clause
1372 let where_clause = &ast_generics.where_clause;
1373 for predicate in &where_clause.predicates {
1375 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1376 let ty = icx.to_ty(&bound_pred.bounded_ty);
1378 for bound in bound_pred.bounds.iter() {
1380 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1381 let mut projections = Vec::new();
1384 AstConv::instantiate_poly_trait_ref(&icx,
1389 predicates.push(trait_ref.to_predicate());
1391 for projection in &projections {
1392 predicates.push(projection.to_predicate());
1396 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1397 let region = AstConv::ast_region_to_region(&icx,
1400 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1401 predicates.push(ty::Predicate::TypeOutlives(pred))
1407 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1408 let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
1409 for bound in ®ion_pred.bounds {
1410 let r2 = AstConv::ast_region_to_region(&icx, bound, None);
1411 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1412 predicates.push(ty::Predicate::RegionOutlives(pred))
1416 &hir::WherePredicate::EqPredicate(..) => {
1422 // Add predicates from associated type bounds.
1423 if let Some((self_trait_ref, trait_items)) = is_trait {
1424 predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1425 let trait_item = tcx.hir.trait_item(trait_item_ref.id);
1426 let bounds = match trait_item.node {
1427 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1429 return vec![].into_iter();
1433 let assoc_ty = tcx.mk_projection(self_trait_ref, trait_item.name);
1435 let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id),
1438 SizedByDefault::Yes,
1441 bounds.predicates(tcx, assoc_ty).into_iter()
1445 // Subtle: before we store the predicates into the tcx, we
1446 // sort them so that predicates like `T: Foo<Item=U>` come
1447 // before uses of `U`. This avoids false ambiguity errors
1448 // in trait checking. See `setup_constraining_predicates`
1450 if let NodeItem(&Item { node: ItemImpl(..), .. }) = node {
1451 let self_ty = tcx.item_type(def_id);
1452 let trait_ref = tcx.impl_trait_ref(def_id);
1453 ctp::setup_constraining_predicates(&mut predicates,
1455 &mut ctp::parameters_for_impl(self_ty, trait_ref));
1458 ty::GenericPredicates {
1459 parent: generics.parent,
1460 predicates: predicates
1464 pub enum SizedByDefault { Yes, No, }
1466 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1467 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1468 /// built-in trait (formerly known as kind): Send.
1469 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1470 param_ty: ty::Ty<'tcx>,
1471 ast_bounds: &[hir::TyParamBound],
1472 sized_by_default: SizedByDefault,
1476 let mut region_bounds = vec![];
1477 let mut trait_bounds = vec![];
1478 for ast_bound in ast_bounds {
1480 hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
1481 trait_bounds.push(b);
1483 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
1484 hir::RegionTyParamBound(ref l) => {
1485 region_bounds.push(l);
1490 let mut projection_bounds = vec![];
1492 let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1493 astconv.instantiate_poly_trait_ref(bound,
1495 &mut projection_bounds)
1498 let region_bounds = region_bounds.into_iter().map(|r| {
1499 astconv.ast_region_to_region(r, None)
1502 trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1504 let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1505 !is_unsized(astconv, ast_bounds, span)
1511 region_bounds: region_bounds,
1512 implicitly_sized: implicitly_sized,
1513 trait_bounds: trait_bounds,
1514 projection_bounds: projection_bounds,
1518 /// Converts a specific TyParamBound from the AST into a set of
1519 /// predicates that apply to the self-type. A vector is returned
1520 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1521 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1522 /// and `<T as Bar>::X == i32`).
1523 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1525 bound: &hir::TyParamBound)
1526 -> Vec<ty::Predicate<'tcx>>
1529 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1530 let mut projections = Vec::new();
1531 let pred = astconv.instantiate_poly_trait_ref(tr,
1534 projections.into_iter()
1535 .map(|p| p.to_predicate())
1536 .chain(Some(pred.to_predicate()))
1539 hir::RegionTyParamBound(ref lifetime) => {
1540 let region = astconv.ast_region_to_region(lifetime, None);
1541 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1542 vec![ty::Predicate::TypeOutlives(pred)]
1544 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1550 fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
1551 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1557 let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
1559 // feature gate SIMD types in FFI, since I (huonw) am not sure the
1560 // ABIs are handled at all correctly.
1561 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
1562 && !tcx.sess.features.borrow().simd_ffi {
1563 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
1565 tcx.sess.struct_span_err(ast_ty.span,
1566 &format!("use of SIMD type `{}` in FFI is highly experimental and \
1567 may result in invalid code",
1568 tcx.hir.node_to_pretty_string(ast_ty.id)))
1569 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
1573 for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
1576 if let hir::Return(ref ty) = decl.output {
1577 check(&ty, *fty.output().skip_binder())
1581 let substs = Substs::identity_for_item(tcx, def_id);
1582 tcx.mk_fn_def(def_id, substs, fty)