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
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::ty::subst::Substs;
63 use rustc::ty::{ToPredicate, ReprOptions};
64 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
65 use rustc::ty::maps::Providers;
66 use rustc::ty::util::IntTypeExt;
67 use util::nodemap::FxHashMap;
69 use rustc_const_math::ConstInt;
71 use std::collections::BTreeMap;
73 use syntax::{abi, ast};
74 use syntax::codemap::Spanned;
75 use syntax::symbol::{Symbol, keywords};
76 use syntax_pos::{Span, DUMMY_SP};
78 use rustc::hir::{self, map as hir_map};
79 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
80 use rustc::hir::def::{Def, CtorKind};
81 use rustc::hir::def_id::DefId;
83 ///////////////////////////////////////////////////////////////////////////
86 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
87 let mut visitor = CollectItemTypesVisitor { tcx: tcx };
88 tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
91 pub fn provide(providers: &mut Providers) {
92 *providers = Providers {
97 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 pub 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> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
132 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
133 NestedVisitorMap::OnlyBodies(&self.tcx.hir)
136 fn visit_item(&mut self, item: &'tcx hir::Item) {
137 convert_item(self.tcx, item.id);
138 intravisit::walk_item(self, item);
141 fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
142 for param in &generics.ty_params {
143 if param.default.is_some() {
144 let def_id = self.tcx.hir.local_def_id(param.id);
145 self.tcx.type_of(def_id);
148 intravisit::walk_generics(self, generics);
151 fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
152 if let hir::ExprClosure(..) = expr.node {
153 let def_id = self.tcx.hir.local_def_id(expr.id);
154 self.tcx.generics_of(def_id);
155 self.tcx.type_of(def_id);
157 intravisit::walk_expr(self, expr);
160 fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
161 if let hir::TyImplTrait(..) = ty.node {
162 let def_id = self.tcx.hir.local_def_id(ty.id);
163 self.tcx.generics_of(def_id);
164 self.tcx.predicates_of(def_id);
166 intravisit::walk_ty(self, ty);
169 fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
170 convert_trait_item(self.tcx, trait_item.id);
171 intravisit::walk_trait_item(self, trait_item);
174 fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
175 convert_impl_item(self.tcx, impl_item.id);
176 intravisit::walk_impl_item(self, impl_item);
180 ///////////////////////////////////////////////////////////////////////////
181 // Utility types and common code for the above passes.
183 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
184 pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
185 -> ItemCtxt<'a,'tcx> {
188 item_def_id: item_def_id,
193 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
194 pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
195 AstConv::ast_ty_to_ty(self, ast_ty)
199 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
200 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx }
202 fn get_type_parameter_bounds(&self,
205 -> ty::GenericPredicates<'tcx>
207 self.tcx.at(span).type_param_predicates((self.item_def_id, def_id))
210 fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
211 -> Option<ty::Region<'tcx>> {
215 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
220 "the type placeholder `_` is not allowed within types on item signatures"
221 ).span_label(span, "not allowed in type signatures")
226 fn projected_ty_from_poly_trait_ref(&self,
229 poly_trait_ref: ty::PolyTraitRef<'tcx>)
232 if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
233 self.tcx().mk_projection(item_def_id, trait_ref.substs)
235 // no late-bound regions, we can just ignore the binder
236 span_err!(self.tcx().sess, span, E0212,
237 "cannot extract an associated type from a higher-ranked trait bound \
243 fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
244 // types in item signatures are not normalized, to avoid undue
249 fn set_tainted_by_errors(&self) {
250 // no obvious place to track this, just let it go
254 fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
255 (item_def_id, def_id): (DefId, DefId))
256 -> ty::GenericPredicates<'tcx> {
257 use rustc::hir::map::*;
260 // In the AST, bounds can derive from two places. Either
261 // written inline like `<T:Foo>` or in a where clause like
264 let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
265 let param_owner = tcx.hir.ty_param_owner(param_id);
266 let param_owner_def_id = tcx.hir.local_def_id(param_owner);
267 let generics = tcx.generics_of(param_owner_def_id);
268 let index = generics.type_param_to_index[&def_id.index];
269 let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id));
271 // Don't look for bounds where the type parameter isn't in scope.
272 let parent = if item_def_id == param_owner_def_id {
275 tcx.generics_of(item_def_id).parent
278 let mut result = parent.map_or(ty::GenericPredicates {
282 let icx = ItemCtxt::new(tcx, parent);
283 icx.get_type_parameter_bounds(DUMMY_SP, def_id)
286 let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
287 let ast_generics = match tcx.hir.get(item_node_id) {
288 NodeTraitItem(item) => {
290 TraitItemKind::Method(ref sig, _) => &sig.generics,
295 NodeImplItem(item) => {
297 ImplItemKind::Method(ref sig, _) => &sig.generics,
304 ItemFn(.., ref generics, _) |
305 ItemImpl(_, _, _, ref generics, ..) |
306 ItemTy(_, ref generics) |
307 ItemEnum(_, ref generics) |
308 ItemStruct(_, ref generics) |
309 ItemUnion(_, ref generics) => generics,
310 ItemTrait(_, ref generics, ..) => {
311 // Implied `Self: Trait` and supertrait bounds.
312 if param_id == item_node_id {
313 result.predicates.push(ty::TraitRef {
315 substs: Substs::identity_for_item(tcx, item_def_id)
324 NodeForeignItem(item) => {
326 ForeignItemFn(_, _, ref generics) => generics,
334 let icx = ItemCtxt::new(tcx, item_def_id);
335 result.predicates.extend(
336 icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty));
340 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
341 /// Find bounds from hir::Generics. This requires scanning through the
342 /// AST. We do this to avoid having to convert *all* the bounds, which
343 /// would create artificial cycles. Instead we can only convert the
344 /// bounds for a type parameter `X` if `X::Foo` is used.
345 fn type_parameter_bounds_in_generics(&self,
346 ast_generics: &hir::Generics,
347 param_id: ast::NodeId,
349 -> Vec<ty::Predicate<'tcx>>
352 ast_generics.ty_params
354 .filter(|p| p.id == param_id)
355 .flat_map(|p| p.bounds.iter())
356 .flat_map(|b| predicates_from_bound(self, ty, b));
358 let from_where_clauses =
359 ast_generics.where_clause
362 .filter_map(|wp| match *wp {
363 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
366 .filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id))
367 .flat_map(|bp| bp.bounds.iter())
368 .flat_map(|b| predicates_from_bound(self, ty, b));
370 from_ty_params.chain(from_where_clauses).collect()
374 /// Tests whether this is the AST for a reference to the type
375 /// parameter with id `param_id`. We use this so as to avoid running
376 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
377 /// conversion of the type to avoid inducing unnecessary cycles.
378 fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
380 param_id: ast::NodeId)
383 if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
385 Def::SelfTy(Some(def_id), None) |
386 Def::TyParam(def_id) => {
387 def_id == tcx.hir.local_def_id(param_id)
396 fn ensure_no_ty_param_bounds(tcx: TyCtxt,
398 generics: &hir::Generics,
399 thing: &'static str) {
400 let mut warn = false;
402 for ty_param in generics.ty_params.iter() {
403 for bound in ty_param.bounds.iter() {
405 hir::TraitTyParamBound(..) => {
408 hir::RegionTyParamBound(..) => { }
413 for predicate in generics.where_clause.predicates.iter() {
415 hir::WherePredicate::BoundPredicate(..) => {
418 hir::WherePredicate::RegionPredicate(..) => { }
419 hir::WherePredicate::EqPredicate(..) => { }
424 // According to accepted RFC #XXX, we should
425 // eventually accept these, but it will not be
426 // part of this PR. Still, convert to warning to
427 // make bootstrapping easier.
428 span_warn!(tcx.sess, span, E0122,
429 "trait bounds are not (yet) enforced \
435 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
436 let it = tcx.hir.expect_item(item_id);
437 debug!("convert: item {} with id {}", it.name, it.id);
438 let def_id = tcx.hir.local_def_id(item_id);
440 // These don't define types.
441 hir::ItemExternCrate(_) |
444 hir::ItemGlobalAsm(_) => {}
445 hir::ItemForeignMod(ref foreign_mod) => {
446 for item in &foreign_mod.items {
447 let def_id = tcx.hir.local_def_id(item.id);
448 tcx.generics_of(def_id);
450 tcx.predicates_of(def_id);
451 if let hir::ForeignItemFn(..) = item.node {
456 hir::ItemEnum(ref enum_definition, _) => {
457 tcx.generics_of(def_id);
459 tcx.predicates_of(def_id);
460 convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
462 hir::ItemDefaultImpl(..) => {
463 tcx.impl_trait_ref(def_id);
465 hir::ItemImpl(..) => {
466 tcx.generics_of(def_id);
468 tcx.impl_trait_ref(def_id);
469 tcx.predicates_of(def_id);
471 hir::ItemTrait(..) => {
472 tcx.generics_of(def_id);
473 tcx.trait_def(def_id);
474 tcx.at(it.span).super_predicates_of(def_id);
475 tcx.predicates_of(def_id);
477 hir::ItemStruct(ref struct_def, _) |
478 hir::ItemUnion(ref struct_def, _) => {
479 tcx.generics_of(def_id);
481 tcx.predicates_of(def_id);
483 for f in struct_def.fields() {
484 let def_id = tcx.hir.local_def_id(f.id);
485 tcx.generics_of(def_id);
487 tcx.predicates_of(def_id);
490 if !struct_def.is_struct() {
491 convert_variant_ctor(tcx, struct_def.id());
494 hir::ItemTy(_, ref generics) => {
495 ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
496 tcx.generics_of(def_id);
498 tcx.predicates_of(def_id);
500 hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => {
501 tcx.generics_of(def_id);
503 tcx.predicates_of(def_id);
504 if let hir::ItemFn(..) = it.node {
511 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
512 let trait_item = tcx.hir.expect_trait_item(trait_item_id);
513 let def_id = tcx.hir.local_def_id(trait_item.id);
514 tcx.generics_of(def_id);
516 match trait_item.node {
517 hir::TraitItemKind::Const(..) |
518 hir::TraitItemKind::Type(_, Some(_)) |
519 hir::TraitItemKind::Method(..) => {
521 if let hir::TraitItemKind::Method(..) = trait_item.node {
526 hir::TraitItemKind::Type(_, None) => {}
529 tcx.predicates_of(def_id);
532 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
533 let def_id = tcx.hir.local_def_id(impl_item_id);
534 tcx.generics_of(def_id);
536 tcx.predicates_of(def_id);
537 if let hir::ImplItemKind::Method(..) = tcx.hir.expect_impl_item(impl_item_id).node {
542 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
543 ctor_id: ast::NodeId) {
544 let def_id = tcx.hir.local_def_id(ctor_id);
545 tcx.generics_of(def_id);
547 tcx.predicates_of(def_id);
550 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
552 variants: &[hir::Variant]) {
553 let def = tcx.adt_def(def_id);
554 let repr_type = def.repr.discr_type();
555 let initial = repr_type.initial_discriminant(tcx);
556 let mut prev_discr = None::<ConstInt>;
558 // fill the discriminant values and field types
559 for variant in variants {
560 let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr());
561 prev_discr = Some(if let Some(e) = variant.node.disr_expr {
562 let expr_did = tcx.hir.local_def_id(e.node_id);
563 let substs = Substs::empty();
564 let result = tcx.at(variant.span).const_eval((expr_did, substs));
566 // enum variant evaluation happens before the global constant check
567 // so we need to report the real error
568 if let Err(ref err) = result {
569 err.report(tcx, variant.span, "enum discriminant");
573 Ok(ConstVal::Integral(x)) => Some(x),
576 } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
579 struct_span_err!(tcx.sess, variant.span, E0370,
580 "enum discriminant overflowed")
581 .span_label(variant.span, format!("overflowed on value after {}",
582 prev_discr.unwrap()))
583 .note(&format!("explicitly set `{} = {}` if that is desired outcome",
584 variant.node.name, wrapped_discr))
587 }.unwrap_or(wrapped_discr));
589 for f in variant.node.data.fields() {
590 let def_id = tcx.hir.local_def_id(f.id);
591 tcx.generics_of(def_id);
593 tcx.predicates_of(def_id);
596 // Convert the ctor, if any. This also registers the variant as
598 convert_variant_ctor(tcx, variant.node.data.id());
602 fn convert_struct_variant<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
605 discr: ty::VariantDiscr,
606 def: &hir::VariantData)
608 let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
609 let node_id = tcx.hir.as_local_node_id(did).unwrap();
610 let fields = def.fields().iter().map(|f| {
611 let fid = tcx.hir.local_def_id(f.id);
612 let dup_span = seen_fields.get(&f.name).cloned();
613 if let Some(prev_span) = dup_span {
614 struct_span_err!(tcx.sess, f.span, E0124,
615 "field `{}` is already declared",
617 .span_label(f.span, "field already declared")
618 .span_label(prev_span, format!("`{}` first declared here", f.name))
621 seen_fields.insert(f.name, f.span);
627 vis: ty::Visibility::from_hir(&f.vis, node_id, tcx)
635 ctor_kind: CtorKind::from_hir(def),
639 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
641 -> &'tcx ty::AdtDef {
642 use rustc::hir::map::*;
645 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
646 let item = match tcx.hir.get(node_id) {
647 NodeItem(item) => item,
651 let repr = ReprOptions::new(tcx, def_id);
652 let (kind, variants) = match item.node {
653 ItemEnum(ref def, _) => {
654 let mut distance_from_explicit = 0;
655 (AdtKind::Enum, def.variants.iter().map(|v| {
656 let did = tcx.hir.local_def_id(v.node.data.id());
657 let discr = if let Some(e) = v.node.disr_expr {
658 distance_from_explicit = 0;
659 ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
661 ty::VariantDiscr::Relative(distance_from_explicit)
663 distance_from_explicit += 1;
665 convert_struct_variant(tcx, did, v.node.name, discr, &v.node.data)
668 ItemStruct(ref def, _) => {
669 // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
670 let ctor_id = if !def.is_struct() {
671 Some(tcx.hir.local_def_id(def.id()))
675 (AdtKind::Struct, vec![
676 convert_struct_variant(tcx, ctor_id.unwrap_or(def_id), item.name,
677 ty::VariantDiscr::Relative(0), def)
680 ItemUnion(ref def, _) => {
681 (AdtKind::Union, vec![
682 convert_struct_variant(tcx, def_id, item.name,
683 ty::VariantDiscr::Relative(0), def)
688 tcx.alloc_adt_def(def_id, kind, variants, repr)
691 /// Ensures that the super-predicates of the trait with def-id
692 /// trait_def_id are converted and stored. This also ensures that
693 /// the transitive super-predicates are converted;
694 fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
696 -> ty::GenericPredicates<'tcx> {
697 debug!("super_predicates(trait_def_id={:?})", trait_def_id);
698 let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
700 let item = match tcx.hir.get(trait_node_id) {
701 hir_map::NodeItem(item) => item,
702 _ => bug!("trait_node_id {} is not an item", trait_node_id)
705 let (generics, bounds) = match item.node {
706 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
707 _ => span_bug!(item.span,
708 "super_predicates invoked on non-trait"),
711 let icx = ItemCtxt::new(tcx, trait_def_id);
713 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
714 let self_param_ty = tcx.mk_self_type();
715 let superbounds1 = compute_bounds(&icx,
721 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
723 // Convert any explicit superbounds in the where clause,
724 // e.g. `trait Foo where Self : Bar`:
725 let superbounds2 = icx.type_parameter_bounds_in_generics(generics, item.id, self_param_ty);
727 // Combine the two lists to form the complete set of superbounds:
728 let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
730 // Now require that immediate supertraits are converted,
731 // which will, in turn, reach indirect supertraits.
732 for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) {
733 tcx.at(item.span).super_predicates_of(bound.def_id());
736 ty::GenericPredicates {
738 predicates: superbounds
742 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
744 -> &'tcx ty::TraitDef {
745 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
746 let item = tcx.hir.expect_item(node_id);
748 let unsafety = match item.node {
749 hir::ItemTrait(unsafety, ..) => unsafety,
750 _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
753 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
754 if paren_sugar && !tcx.sess.features.borrow().unboxed_closures {
755 let mut err = tcx.sess.struct_span_err(
757 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
758 which traits can use parenthetical notation");
760 "add `#![feature(unboxed_closures)]` to \
761 the crate attributes to use it");
765 let def_path_hash = tcx.def_path_hash(def_id);
766 let has_default_impl = tcx.hir.trait_is_auto(def_id);
767 let def = ty::TraitDef::new(def_id,
772 tcx.alloc_trait_def(def)
775 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
777 -> &'tcx ty::Generics {
778 use rustc::hir::map::*;
781 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
783 let node = tcx.hir.get(node_id);
784 let parent_def_id = match node {
790 let parent_id = tcx.hir.get_parent(node_id);
791 Some(tcx.hir.local_def_id(parent_id))
793 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
794 Some(tcx.closure_base_def_id(def_id))
796 NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
797 let mut parent_id = node_id;
799 match tcx.hir.get(parent_id) {
800 NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
802 parent_id = tcx.hir.get_parent_node(parent_id);
806 Some(tcx.hir.local_def_id(parent_id))
811 let mut opt_self = None;
812 let mut allow_defaults = false;
814 let no_generics = hir::Generics::empty();
815 let ast_generics = match node {
816 NodeTraitItem(item) => {
818 TraitItemKind::Method(ref sig, _) => &sig.generics,
823 NodeImplItem(item) => {
825 ImplItemKind::Method(ref sig, _) => &sig.generics,
832 ItemFn(.., ref generics, _) |
833 ItemImpl(_, _, _, ref generics, ..) => generics,
835 ItemTy(_, ref generics) |
836 ItemEnum(_, ref generics) |
837 ItemStruct(_, ref generics) |
838 ItemUnion(_, ref generics) => {
839 allow_defaults = true;
843 ItemTrait(_, ref generics, ..) => {
844 // Add in the self type parameter.
846 // Something of a hack: use the node id for the trait, also as
847 // the node id for the Self type parameter.
848 let param_id = item.id;
850 opt_self = Some(ty::TypeParameterDef {
852 name: keywords::SelfType.name(),
853 def_id: tcx.hir.local_def_id(param_id),
855 object_lifetime_default: rl::Set1::Empty,
856 pure_wrt_drop: false,
859 allow_defaults = true;
867 NodeForeignItem(item) => {
869 ForeignItemStatic(..) => &no_generics,
870 ForeignItemFn(_, _, ref generics) => generics
877 let has_self = opt_self.is_some();
878 let mut parent_has_self = false;
879 let mut own_start = has_self as u32;
880 let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
881 let generics = tcx.generics_of(def_id);
882 assert_eq!(has_self, false);
883 parent_has_self = generics.has_self;
884 own_start = generics.count() as u32;
885 (generics.parent_regions + generics.regions.len() as u32,
886 generics.parent_types + generics.types.len() as u32)
889 let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
890 let regions = early_lifetimes.enumerate().map(|(i, l)| {
891 let issue_32330 = tcx.named_region_map.issue_32330.get(&l.lifetime.id).cloned();
892 ty::RegionParameterDef {
893 name: l.lifetime.name,
894 index: own_start + i as u32,
895 def_id: tcx.hir.local_def_id(l.lifetime.id),
896 pure_wrt_drop: l.pure_wrt_drop,
897 issue_32330: issue_32330,
899 }).collect::<Vec<_>>();
901 let object_lifetime_defaults =
902 tcx.named_region_map.object_lifetime_defaults.get(&node_id);
904 // Now create the real type parameters.
905 let type_start = own_start + regions.len() as u32;
906 let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
907 if p.name == keywords::SelfType.name() {
908 span_bug!(p.span, "`Self` should not be the name of a regular parameter");
911 if !allow_defaults && p.default.is_some() {
912 if !tcx.sess.features.borrow().default_type_parameter_fallback {
914 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
917 format!("defaults for type parameters are only allowed in `struct`, \
918 `enum`, `type`, or `trait` definitions."));
922 ty::TypeParameterDef {
923 index: type_start + i as u32,
925 def_id: tcx.hir.local_def_id(p.id),
926 has_default: p.default.is_some(),
927 object_lifetime_default:
928 object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
929 pure_wrt_drop: p.pure_wrt_drop,
932 let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
934 // provide junk type parameter defs - the only place that
935 // cares about anything but the length is instantiation,
936 // and we don't do that for closures.
937 if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node {
938 tcx.with_freevars(node_id, |fv| {
939 types.extend(fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
940 index: type_start + i as u32,
941 name: Symbol::intern("<upvar>"),
944 object_lifetime_default: rl::Set1::Empty,
945 pure_wrt_drop: false,
950 let mut type_param_to_index = BTreeMap::new();
951 for param in &types {
952 type_param_to_index.insert(param.def_id.index, param.index);
955 tcx.alloc_generics(ty::Generics {
956 parent: parent_def_id,
957 parent_regions: parent_regions,
958 parent_types: parent_types,
961 type_param_to_index: type_param_to_index,
962 has_self: has_self || parent_has_self
966 fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
969 use rustc::hir::map::*;
972 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
974 let icx = ItemCtxt::new(tcx, def_id);
976 match tcx.hir.get(node_id) {
977 NodeTraitItem(item) => {
979 TraitItemKind::Method(..) => {
980 let substs = Substs::identity_for_item(tcx, def_id);
981 tcx.mk_fn_def(def_id, substs)
983 TraitItemKind::Const(ref ty, _) |
984 TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
985 TraitItemKind::Type(_, None) => {
986 span_bug!(item.span, "associated type missing default");
991 NodeImplItem(item) => {
993 ImplItemKind::Method(..) => {
994 let substs = Substs::identity_for_item(tcx, def_id);
995 tcx.mk_fn_def(def_id, substs)
997 ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
998 ImplItemKind::Type(ref ty) => {
999 if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
1000 span_err!(tcx.sess, item.span, E0202,
1001 "associated types are not allowed in inherent impls");
1011 ItemStatic(ref t, ..) | ItemConst(ref t, _) |
1012 ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
1016 let substs = Substs::identity_for_item(tcx, def_id);
1017 tcx.mk_fn_def(def_id, substs)
1022 let def = tcx.adt_def(def_id);
1023 let substs = Substs::identity_for_item(tcx, def_id);
1024 tcx.mk_adt(def, substs)
1026 ItemDefaultImpl(..) |
1029 ItemForeignMod(..) |
1031 ItemExternCrate(..) |
1035 "compute_type_of_item: unexpected item type: {:?}",
1041 NodeForeignItem(foreign_item) => {
1042 match foreign_item.node {
1043 ForeignItemFn(..) => {
1044 let substs = Substs::identity_for_item(tcx, def_id);
1045 tcx.mk_fn_def(def_id, substs)
1047 ForeignItemStatic(ref t, _) => icx.to_ty(t)
1051 NodeStructCtor(&ref def) |
1052 NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
1054 VariantData::Unit(..) | VariantData::Struct(..) => {
1055 tcx.type_of(tcx.hir.get_parent_did(node_id))
1057 VariantData::Tuple(..) => {
1058 let substs = Substs::identity_for_item(tcx, def_id);
1059 tcx.mk_fn_def(def_id, substs)
1064 NodeField(field) => icx.to_ty(&field.ty),
1066 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1067 tcx.mk_closure(def_id, Substs::for_item(
1070 let region = def.to_early_bound_region_data();
1071 tcx.mk_region(ty::ReEarlyBound(region))
1073 |def, _| tcx.mk_param_from_def(def)
1077 NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
1078 NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
1079 NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
1080 NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
1081 if body.node_id == node_id => tcx.types.usize,
1083 NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
1084 if e.node_id == node_id => {
1085 tcx.adt_def(tcx.hir.get_parent_did(node_id))
1086 .repr.discr_type().to_ty(tcx)
1090 bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
1094 NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
1098 NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1099 let owner = tcx.hir.get_parent_did(node_id);
1100 tcx.typeck_tables_of(owner).node_id_to_type(node_id)
1104 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1109 fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1111 -> ty::PolyFnSig<'tcx> {
1112 use rustc::hir::map::*;
1115 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1117 let icx = ItemCtxt::new(tcx, def_id);
1119 match tcx.hir.get(node_id) {
1120 NodeTraitItem(&hir::TraitItem { node: TraitItemKind::Method(ref sig, _), .. }) |
1121 NodeImplItem(&hir::ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) => {
1122 AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl)
1125 NodeItem(&hir::Item { node: ItemFn(ref decl, unsafety, _, abi, _, _), .. }) => {
1126 AstConv::ty_of_fn(&icx, unsafety, abi, decl)
1129 NodeForeignItem(&hir::ForeignItem { node: ForeignItemFn(ref fn_decl, _, _), .. }) => {
1130 let abi = tcx.hir.get_foreign_abi(node_id);
1131 compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1134 NodeStructCtor(&VariantData::Tuple(ref fields, _)) |
1135 NodeVariant(&Spanned { node: hir::Variant_ {
1136 data: VariantData::Tuple(ref fields, _), ..
1138 let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
1139 let inputs = fields.iter().map(|f| {
1140 tcx.type_of(tcx.hir.local_def_id(f.id))
1142 ty::Binder(tcx.mk_fn_sig(
1146 hir::Unsafety::Normal,
1151 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1152 tcx.typeck_tables_of(def_id).closure_tys[&node_id]
1156 bug!("unexpected sort of node in fn_sig(): {:?}", x);
1161 fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1163 -> Option<ty::TraitRef<'tcx>> {
1164 let icx = ItemCtxt::new(tcx, def_id);
1166 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1167 match tcx.hir.expect_item(node_id).node {
1168 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
1169 Some(AstConv::instantiate_mono_trait_ref(&icx,
1171 tcx.mk_self_type()))
1173 hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
1174 opt_trait_ref.as_ref().map(|ast_trait_ref| {
1175 let selfty = tcx.type_of(def_id);
1176 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1183 fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1185 -> hir::ImplPolarity {
1186 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1187 match tcx.hir.expect_item(node_id).node {
1188 hir::ItemImpl(_, polarity, ..) => polarity,
1189 ref item => bug!("impl_polarity: {:?} not an impl", item)
1193 // Is it marked with ?Sized
1194 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1195 ast_bounds: &[hir::TyParamBound],
1198 let tcx = astconv.tcx();
1200 // Try to find an unbound in bounds.
1201 let mut unbound = None;
1202 for ab in ast_bounds {
1203 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1204 if unbound.is_none() {
1205 unbound = Some(ptr.trait_ref.clone());
1207 span_err!(tcx.sess, span, E0203,
1208 "type parameter has more than one relaxed default \
1209 bound, only one is supported");
1214 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1217 // FIXME(#8559) currently requires the unbound to be built-in.
1218 if let Ok(kind_id) = kind_id {
1219 if tpb.path.def != Def::Trait(kind_id) {
1220 tcx.sess.span_warn(span,
1221 "default bound relaxed for a type parameter, but \
1222 this does nothing because the given bound is not \
1223 a default. Only `?Sized` is supported");
1227 _ if kind_id.is_ok() => {
1230 // No lang item for Sized, so we can't add it as a bound.
1237 /// Returns the early-bound lifetimes declared in this generics
1238 /// listing. For anything other than fns/methods, this is just all
1239 /// the lifetimes that are declared. For fns or methods, we have to
1240 /// screen out those that do not appear in any where-clauses etc using
1241 /// `resolve_lifetime::early_bound_lifetimes`.
1242 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1243 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1244 ast_generics: &'a hir::Generics)
1245 -> impl Iterator<Item=&'a hir::LifetimeDef>
1250 .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
1253 fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1255 -> ty::GenericPredicates<'tcx> {
1256 use rustc::hir::map::*;
1259 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1260 let node = tcx.hir.get(node_id);
1262 let mut is_trait = None;
1264 let icx = ItemCtxt::new(tcx, def_id);
1265 let no_generics = hir::Generics::empty();
1266 let ast_generics = match node {
1267 NodeTraitItem(item) => {
1269 TraitItemKind::Method(ref sig, _) => &sig.generics,
1274 NodeImplItem(item) => {
1276 ImplItemKind::Method(ref sig, _) => &sig.generics,
1283 ItemFn(.., ref generics, _) |
1284 ItemImpl(_, _, _, ref generics, ..) |
1285 ItemTy(_, ref generics) |
1286 ItemEnum(_, ref generics) |
1287 ItemStruct(_, ref generics) |
1288 ItemUnion(_, ref generics) => {
1292 ItemTrait(_, ref generics, .., ref items) => {
1293 is_trait = Some((ty::TraitRef {
1295 substs: Substs::identity_for_item(tcx, def_id)
1304 NodeForeignItem(item) => {
1306 ForeignItemStatic(..) => &no_generics,
1307 ForeignItemFn(_, _, ref generics) => generics
1311 NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1312 let substs = Substs::identity_for_item(tcx, def_id);
1313 let anon_ty = tcx.mk_anon(def_id, substs);
1315 // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1316 let bounds = compute_bounds(&icx, anon_ty, bounds,
1317 SizedByDefault::Yes,
1319 return ty::GenericPredicates {
1321 predicates: bounds.predicates(tcx, anon_ty)
1328 let generics = tcx.generics_of(def_id);
1329 let parent_count = generics.parent_count() as u32;
1330 let has_own_self = generics.has_self && parent_count == 0;
1332 let mut predicates = vec![];
1334 // Below we'll consider the bounds on the type parameters (including `Self`)
1335 // and the explicit where-clauses, but to get the full set of predicates
1336 // on a trait we need to add in the supertrait bounds and bounds found on
1337 // associated types.
1338 if let Some((trait_ref, _)) = is_trait {
1339 predicates = tcx.super_predicates_of(def_id).predicates;
1341 // Add in a predicate that `Self:Trait` (where `Trait` is the
1342 // current trait). This is needed for builtin bounds.
1343 predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
1346 // Collect the region predicates that were declared inline as
1347 // well. In the case of parameters declared on a fn or method, we
1348 // have to be careful to only iterate over early-bound regions.
1349 let mut index = parent_count + has_own_self as u32;
1350 for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1351 let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1352 def_id: tcx.hir.local_def_id(param.lifetime.id),
1354 name: param.lifetime.name
1358 for bound in ¶m.bounds {
1359 let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
1360 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1361 predicates.push(outlives.to_predicate());
1365 // Collect the predicates that were written inline by the user on each
1366 // type parameter (e.g., `<T:Foo>`).
1367 for param in &ast_generics.ty_params {
1368 let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
1371 let bounds = compute_bounds(&icx,
1374 SizedByDefault::Yes,
1376 predicates.extend(bounds.predicates(tcx, param_ty));
1379 // Add in the bounds that appear in the where-clause
1380 let where_clause = &ast_generics.where_clause;
1381 for predicate in &where_clause.predicates {
1383 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1384 let ty = icx.to_ty(&bound_pred.bounded_ty);
1386 for bound in bound_pred.bounds.iter() {
1388 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1389 let mut projections = Vec::new();
1392 AstConv::instantiate_poly_trait_ref(&icx,
1397 predicates.push(trait_ref.to_predicate());
1399 for projection in &projections {
1400 predicates.push(projection.to_predicate());
1404 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1405 let region = AstConv::ast_region_to_region(&icx,
1408 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1409 predicates.push(ty::Predicate::TypeOutlives(pred))
1415 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1416 let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
1417 for bound in ®ion_pred.bounds {
1418 let r2 = AstConv::ast_region_to_region(&icx, bound, None);
1419 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1420 predicates.push(ty::Predicate::RegionOutlives(pred))
1424 &hir::WherePredicate::EqPredicate(..) => {
1430 // Add predicates from associated type bounds.
1431 if let Some((self_trait_ref, trait_items)) = is_trait {
1432 predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1433 let trait_item = tcx.hir.trait_item(trait_item_ref.id);
1434 let bounds = match trait_item.node {
1435 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1437 return vec![].into_iter();
1441 let assoc_ty = tcx.mk_projection(
1442 tcx.hir.local_def_id(trait_item.id),
1443 self_trait_ref.substs,
1446 let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id),
1449 SizedByDefault::Yes,
1452 bounds.predicates(tcx, assoc_ty).into_iter()
1456 // Subtle: before we store the predicates into the tcx, we
1457 // sort them so that predicates like `T: Foo<Item=U>` come
1458 // before uses of `U`. This avoids false ambiguity errors
1459 // in trait checking. See `setup_constraining_predicates`
1461 if let NodeItem(&Item { node: ItemImpl(..), .. }) = node {
1462 let self_ty = tcx.type_of(def_id);
1463 let trait_ref = tcx.impl_trait_ref(def_id);
1464 ctp::setup_constraining_predicates(tcx,
1467 &mut ctp::parameters_for_impl(self_ty, trait_ref));
1470 ty::GenericPredicates {
1471 parent: generics.parent,
1472 predicates: predicates
1476 pub enum SizedByDefault { Yes, No, }
1478 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1479 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1480 /// built-in trait (formerly known as kind): Send.
1481 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1482 param_ty: ty::Ty<'tcx>,
1483 ast_bounds: &[hir::TyParamBound],
1484 sized_by_default: SizedByDefault,
1488 let mut region_bounds = vec![];
1489 let mut trait_bounds = vec![];
1490 for ast_bound in ast_bounds {
1492 hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
1493 trait_bounds.push(b);
1495 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
1496 hir::RegionTyParamBound(ref l) => {
1497 region_bounds.push(l);
1502 let mut projection_bounds = vec![];
1504 let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1505 astconv.instantiate_poly_trait_ref(bound,
1507 &mut projection_bounds)
1510 let region_bounds = region_bounds.into_iter().map(|r| {
1511 astconv.ast_region_to_region(r, None)
1514 trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1516 let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1517 !is_unsized(astconv, ast_bounds, span)
1523 region_bounds: region_bounds,
1524 implicitly_sized: implicitly_sized,
1525 trait_bounds: trait_bounds,
1526 projection_bounds: projection_bounds,
1530 /// Converts a specific TyParamBound from the AST into a set of
1531 /// predicates that apply to the self-type. A vector is returned
1532 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1533 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1534 /// and `<T as Bar>::X == i32`).
1535 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1537 bound: &hir::TyParamBound)
1538 -> Vec<ty::Predicate<'tcx>>
1541 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1542 let mut projections = Vec::new();
1543 let pred = astconv.instantiate_poly_trait_ref(tr,
1546 projections.into_iter()
1547 .map(|p| p.to_predicate())
1548 .chain(Some(pred.to_predicate()))
1551 hir::RegionTyParamBound(ref lifetime) => {
1552 let region = astconv.ast_region_to_region(lifetime, None);
1553 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1554 vec![ty::Predicate::TypeOutlives(pred)]
1556 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1562 fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
1563 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1567 -> ty::PolyFnSig<'tcx>
1569 let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
1571 // feature gate SIMD types in FFI, since I (huonw) am not sure the
1572 // ABIs are handled at all correctly.
1573 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
1574 && !tcx.sess.features.borrow().simd_ffi {
1575 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
1577 tcx.sess.struct_span_err(ast_ty.span,
1578 &format!("use of SIMD type `{}` in FFI is highly experimental and \
1579 may result in invalid code",
1580 tcx.hir.node_to_pretty_string(ast_ty.id)))
1581 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
1585 for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
1588 if let hir::Return(ref ty) = decl.output {
1589 check(&ty, *fty.output().skip_binder())
1596 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1599 match tcx.hir.get_if_local(def_id) {
1600 Some(hir_map::NodeForeignItem(..)) => true,
1602 _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
1606 fn is_default_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1609 match tcx.hir.get_if_local(def_id) {
1610 Some(hir_map::NodeItem(&hir::Item { node: hir::ItemDefaultImpl(..), .. }))
1613 _ => bug!("is_default_impl applied to non-local def-id {:?}", def_id)