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,
107 ///////////////////////////////////////////////////////////////////////////
109 /// Context specific to some particular item. This is what implements
110 /// AstConv. It has information about the predicates that are defined
111 /// on the trait. Unfortunately, this predicate information is
112 /// available in various different forms at various points in the
113 /// process. So we can't just store a pointer to e.g. the AST or the
114 /// parsed ty form, we have to be more flexible. To this end, the
115 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
116 /// `get_type_parameter_bounds` requests, drawing the information from
117 /// the AST (`hir::Generics`), recursively.
118 pub struct ItemCtxt<'a,'tcx:'a> {
119 tcx: TyCtxt<'a, 'tcx, 'tcx>,
123 ///////////////////////////////////////////////////////////////////////////
125 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
126 tcx: TyCtxt<'a, 'tcx, 'tcx>
129 impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
130 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
131 NestedVisitorMap::OnlyBodies(&self.tcx.hir)
134 fn visit_item(&mut self, item: &'tcx hir::Item) {
135 convert_item(self.tcx, item.id);
136 intravisit::walk_item(self, item);
139 fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
140 for param in &generics.ty_params {
141 if param.default.is_some() {
142 let def_id = self.tcx.hir.local_def_id(param.id);
143 self.tcx.type_of(def_id);
146 intravisit::walk_generics(self, generics);
149 fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
150 if let hir::ExprClosure(..) = expr.node {
151 let def_id = self.tcx.hir.local_def_id(expr.id);
152 self.tcx.generics_of(def_id);
153 self.tcx.type_of(def_id);
155 intravisit::walk_expr(self, expr);
158 fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
159 if let hir::TyImplTrait(..) = ty.node {
160 let def_id = self.tcx.hir.local_def_id(ty.id);
161 self.tcx.generics_of(def_id);
162 self.tcx.predicates_of(def_id);
164 intravisit::walk_ty(self, ty);
167 fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
168 convert_trait_item(self.tcx, trait_item.id);
169 intravisit::walk_trait_item(self, trait_item);
172 fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
173 convert_impl_item(self.tcx, impl_item.id);
174 intravisit::walk_impl_item(self, impl_item);
178 ///////////////////////////////////////////////////////////////////////////
179 // Utility types and common code for the above passes.
181 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
182 pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
183 -> ItemCtxt<'a,'tcx> {
186 item_def_id: item_def_id,
191 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
192 pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
193 AstConv::ast_ty_to_ty(self, ast_ty)
197 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
198 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx }
200 fn get_type_parameter_bounds(&self,
203 -> ty::GenericPredicates<'tcx>
205 self.tcx.at(span).type_param_predicates((self.item_def_id, def_id))
208 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
212 fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
213 -> Option<ty::Region<'tcx>> {
217 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
222 "the type placeholder `_` is not allowed within types on item signatures"
223 ).span_label(span, "not allowed in type signatures")
228 fn projected_ty_from_poly_trait_ref(&self,
230 poly_trait_ref: ty::PolyTraitRef<'tcx>,
231 item_name: ast::Name)
234 if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
235 self.tcx().mk_projection(trait_ref, item_name)
237 // no late-bound regions, we can just ignore the binder
238 span_err!(self.tcx().sess, span, E0212,
239 "cannot extract an associated type from a higher-ranked trait bound \
245 fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
246 // types in item signatures are not normalized, to avoid undue
251 fn set_tainted_by_errors(&self) {
252 // no obvious place to track this, just let it go
256 fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
257 (item_def_id, def_id): (DefId, DefId))
258 -> ty::GenericPredicates<'tcx> {
259 use rustc::hir::map::*;
262 // In the AST, bounds can derive from two places. Either
263 // written inline like `<T:Foo>` or in a where clause like
266 let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
267 let param_owner = tcx.hir.ty_param_owner(param_id);
268 let param_owner_def_id = tcx.hir.local_def_id(param_owner);
269 let generics = tcx.generics_of(param_owner_def_id);
270 let index = generics.type_param_to_index[&def_id.index];
271 let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id));
273 // Don't look for bounds where the type parameter isn't in scope.
274 let parent = if item_def_id == param_owner_def_id {
277 tcx.generics_of(item_def_id).parent
280 let mut result = parent.map_or(ty::GenericPredicates {
284 let icx = ItemCtxt::new(tcx, parent);
285 icx.get_type_parameter_bounds(DUMMY_SP, def_id)
288 let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
289 let ast_generics = match tcx.hir.get(item_node_id) {
290 NodeTraitItem(item) => {
292 TraitItemKind::Method(ref sig, _) => &sig.generics,
297 NodeImplItem(item) => {
299 ImplItemKind::Method(ref sig, _) => &sig.generics,
306 ItemFn(.., ref generics, _) |
307 ItemImpl(_, _, _, ref generics, ..) |
308 ItemTy(_, ref generics) |
309 ItemEnum(_, ref generics) |
310 ItemStruct(_, ref generics) |
311 ItemUnion(_, ref generics) => generics,
312 ItemTrait(_, ref generics, ..) => {
313 // Implied `Self: Trait` and supertrait bounds.
314 if param_id == item_node_id {
315 result.predicates.push(ty::TraitRef {
317 substs: Substs::identity_for_item(tcx, item_def_id)
326 NodeForeignItem(item) => {
328 ForeignItemFn(_, _, ref generics) => generics,
336 let icx = ItemCtxt::new(tcx, item_def_id);
337 result.predicates.extend(
338 icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty));
342 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
343 /// Find bounds from hir::Generics. This requires scanning through the
344 /// AST. We do this to avoid having to convert *all* the bounds, which
345 /// would create artificial cycles. Instead we can only convert the
346 /// bounds for a type parameter `X` if `X::Foo` is used.
347 fn type_parameter_bounds_in_generics(&self,
348 ast_generics: &hir::Generics,
349 param_id: ast::NodeId,
351 -> Vec<ty::Predicate<'tcx>>
354 ast_generics.ty_params
356 .filter(|p| p.id == param_id)
357 .flat_map(|p| p.bounds.iter())
358 .flat_map(|b| predicates_from_bound(self, ty, b));
360 let from_where_clauses =
361 ast_generics.where_clause
364 .filter_map(|wp| match *wp {
365 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
368 .filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id))
369 .flat_map(|bp| bp.bounds.iter())
370 .flat_map(|b| predicates_from_bound(self, ty, b));
372 from_ty_params.chain(from_where_clauses).collect()
376 /// Tests whether this is the AST for a reference to the type
377 /// parameter with id `param_id`. We use this so as to avoid running
378 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
379 /// conversion of the type to avoid inducing unnecessary cycles.
380 fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
382 param_id: ast::NodeId)
385 if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
387 Def::SelfTy(Some(def_id), None) |
388 Def::TyParam(def_id) => {
389 def_id == tcx.hir.local_def_id(param_id)
398 fn ensure_no_ty_param_bounds(tcx: TyCtxt,
400 generics: &hir::Generics,
401 thing: &'static str) {
402 let mut warn = false;
404 for ty_param in generics.ty_params.iter() {
405 for bound in ty_param.bounds.iter() {
407 hir::TraitTyParamBound(..) => {
410 hir::RegionTyParamBound(..) => { }
415 for predicate in generics.where_clause.predicates.iter() {
417 hir::WherePredicate::BoundPredicate(..) => {
420 hir::WherePredicate::RegionPredicate(..) => { }
421 hir::WherePredicate::EqPredicate(..) => { }
426 // According to accepted RFC #XXX, we should
427 // eventually accept these, but it will not be
428 // part of this PR. Still, convert to warning to
429 // make bootstrapping easier.
430 span_warn!(tcx.sess, span, E0122,
431 "trait bounds are not (yet) enforced \
437 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
438 let it = tcx.hir.expect_item(item_id);
439 debug!("convert: item {} with id {}", it.name, it.id);
440 let def_id = tcx.hir.local_def_id(item_id);
442 // These don't define types.
443 hir::ItemExternCrate(_) |
446 hir::ItemGlobalAsm(_) => {}
447 hir::ItemForeignMod(ref foreign_mod) => {
448 for item in &foreign_mod.items {
449 let def_id = tcx.hir.local_def_id(item.id);
450 tcx.generics_of(def_id);
452 tcx.predicates_of(def_id);
455 hir::ItemEnum(ref enum_definition, _) => {
456 tcx.generics_of(def_id);
458 tcx.predicates_of(def_id);
459 convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
461 hir::ItemDefaultImpl(..) => {
462 tcx.impl_trait_ref(def_id);
464 hir::ItemImpl(..) => {
465 tcx.generics_of(def_id);
467 tcx.impl_trait_ref(def_id);
468 tcx.predicates_of(def_id);
470 hir::ItemTrait(..) => {
471 tcx.generics_of(def_id);
472 tcx.trait_def(def_id);
473 tcx.at(it.span).super_predicates_of(def_id);
474 tcx.predicates_of(def_id);
476 hir::ItemStruct(ref struct_def, _) |
477 hir::ItemUnion(ref struct_def, _) => {
478 tcx.generics_of(def_id);
480 tcx.predicates_of(def_id);
482 for f in struct_def.fields() {
483 let def_id = tcx.hir.local_def_id(f.id);
484 tcx.generics_of(def_id);
486 tcx.predicates_of(def_id);
489 if !struct_def.is_struct() {
490 convert_variant_ctor(tcx, struct_def.id());
493 hir::ItemTy(_, ref generics) => {
494 ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
495 tcx.generics_of(def_id);
497 tcx.predicates_of(def_id);
499 hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => {
500 tcx.generics_of(def_id);
502 tcx.predicates_of(def_id);
507 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
508 let trait_item = tcx.hir.expect_trait_item(trait_item_id);
509 let def_id = tcx.hir.local_def_id(trait_item.id);
510 tcx.generics_of(def_id);
512 match trait_item.node {
513 hir::TraitItemKind::Const(..) |
514 hir::TraitItemKind::Type(_, Some(_)) |
515 hir::TraitItemKind::Method(..) => {
519 hir::TraitItemKind::Type(_, None) => {}
522 tcx.predicates_of(def_id);
525 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
526 let def_id = tcx.hir.local_def_id(impl_item_id);
527 tcx.generics_of(def_id);
529 tcx.predicates_of(def_id);
532 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
533 ctor_id: ast::NodeId) {
534 let def_id = tcx.hir.local_def_id(ctor_id);
535 tcx.generics_of(def_id);
537 tcx.predicates_of(def_id);
540 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
542 variants: &[hir::Variant]) {
543 let def = tcx.adt_def(def_id);
544 let repr_type = def.repr.discr_type();
545 let initial = repr_type.initial_discriminant(tcx);
546 let mut prev_discr = None::<ConstInt>;
548 // fill the discriminant values and field types
549 for variant in variants {
550 let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr());
551 prev_discr = Some(if let Some(e) = variant.node.disr_expr {
552 let expr_did = tcx.hir.local_def_id(e.node_id);
553 let substs = Substs::empty();
554 let result = tcx.at(variant.span).const_eval((expr_did, substs));
556 // enum variant evaluation happens before the global constant check
557 // so we need to report the real error
558 if let Err(ref err) = result {
559 err.report(tcx, variant.span, "enum discriminant");
563 Ok(ConstVal::Integral(x)) => Some(x),
566 } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
569 struct_span_err!(tcx.sess, variant.span, E0370,
570 "enum discriminant overflowed")
571 .span_label(variant.span, format!("overflowed on value after {}",
572 prev_discr.unwrap()))
573 .note(&format!("explicitly set `{} = {}` if that is desired outcome",
574 variant.node.name, wrapped_discr))
577 }.unwrap_or(wrapped_discr));
579 for f in variant.node.data.fields() {
580 let def_id = tcx.hir.local_def_id(f.id);
581 tcx.generics_of(def_id);
583 tcx.predicates_of(def_id);
586 // Convert the ctor, if any. This also registers the variant as
588 convert_variant_ctor(tcx, variant.node.data.id());
592 fn convert_struct_variant<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
595 discr: ty::VariantDiscr,
596 def: &hir::VariantData)
598 let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
599 let node_id = tcx.hir.as_local_node_id(did).unwrap();
600 let fields = def.fields().iter().map(|f| {
601 let fid = tcx.hir.local_def_id(f.id);
602 let dup_span = seen_fields.get(&f.name).cloned();
603 if let Some(prev_span) = dup_span {
604 struct_span_err!(tcx.sess, f.span, E0124,
605 "field `{}` is already declared",
607 .span_label(f.span, "field already declared")
608 .span_label(prev_span, format!("`{}` first declared here", f.name))
611 seen_fields.insert(f.name, f.span);
617 vis: ty::Visibility::from_hir(&f.vis, node_id, tcx)
625 ctor_kind: CtorKind::from_hir(def),
629 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
631 -> &'tcx ty::AdtDef {
632 use rustc::hir::map::*;
635 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
636 let item = match tcx.hir.get(node_id) {
637 NodeItem(item) => item,
641 let repr = ReprOptions::new(tcx, def_id);
642 let (kind, variants) = match item.node {
643 ItemEnum(ref def, _) => {
644 let mut distance_from_explicit = 0;
645 (AdtKind::Enum, def.variants.iter().map(|v| {
646 let did = tcx.hir.local_def_id(v.node.data.id());
647 let discr = if let Some(e) = v.node.disr_expr {
648 distance_from_explicit = 0;
649 ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
651 ty::VariantDiscr::Relative(distance_from_explicit)
653 distance_from_explicit += 1;
655 convert_struct_variant(tcx, did, v.node.name, discr, &v.node.data)
658 ItemStruct(ref def, _) => {
659 // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
660 let ctor_id = if !def.is_struct() {
661 Some(tcx.hir.local_def_id(def.id()))
665 (AdtKind::Struct, vec![
666 convert_struct_variant(tcx, ctor_id.unwrap_or(def_id), item.name,
667 ty::VariantDiscr::Relative(0), def)
670 ItemUnion(ref def, _) => {
671 (AdtKind::Union, vec![
672 convert_struct_variant(tcx, def_id, item.name,
673 ty::VariantDiscr::Relative(0), def)
678 tcx.alloc_adt_def(def_id, kind, variants, repr)
681 /// Ensures that the super-predicates of the trait with def-id
682 /// trait_def_id are converted and stored. This also ensures that
683 /// the transitive super-predicates are converted;
684 fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
686 -> ty::GenericPredicates<'tcx> {
687 debug!("super_predicates(trait_def_id={:?})", trait_def_id);
688 let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
690 let item = match tcx.hir.get(trait_node_id) {
691 hir_map::NodeItem(item) => item,
692 _ => bug!("trait_node_id {} is not an item", trait_node_id)
695 let (generics, bounds) = match item.node {
696 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
697 _ => span_bug!(item.span,
698 "super_predicates invoked on non-trait"),
701 let icx = ItemCtxt::new(tcx, trait_def_id);
703 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
704 let self_param_ty = tcx.mk_self_type();
705 let superbounds1 = compute_bounds(&icx,
711 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
713 // Convert any explicit superbounds in the where clause,
714 // e.g. `trait Foo where Self : Bar`:
715 let superbounds2 = icx.type_parameter_bounds_in_generics(generics, item.id, self_param_ty);
717 // Combine the two lists to form the complete set of superbounds:
718 let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
720 // Now require that immediate supertraits are converted,
721 // which will, in turn, reach indirect supertraits.
722 for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) {
723 tcx.at(item.span).super_predicates_of(bound.def_id());
726 ty::GenericPredicates {
728 predicates: superbounds
732 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
734 -> &'tcx ty::TraitDef {
735 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
736 let item = tcx.hir.expect_item(node_id);
738 let unsafety = match item.node {
739 hir::ItemTrait(unsafety, ..) => unsafety,
740 _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
743 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
744 if paren_sugar && !tcx.sess.features.borrow().unboxed_closures {
745 let mut err = tcx.sess.struct_span_err(
747 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
748 which traits can use parenthetical notation");
750 "add `#![feature(unboxed_closures)]` to \
751 the crate attributes to use it");
755 let def_path_hash = tcx.def_path_hash(def_id);
756 let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash);
758 if tcx.hir.trait_is_auto(def_id) {
759 def.record_has_default_impl();
762 tcx.alloc_trait_def(def)
765 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
767 -> &'tcx ty::Generics {
768 use rustc::hir::map::*;
771 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
773 let node = tcx.hir.get(node_id);
774 let parent_def_id = match node {
780 let parent_id = tcx.hir.get_parent(node_id);
781 Some(tcx.hir.local_def_id(parent_id))
783 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
784 Some(tcx.closure_base_def_id(def_id))
786 NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
787 let mut parent_id = node_id;
789 match tcx.hir.get(parent_id) {
790 NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
792 parent_id = tcx.hir.get_parent_node(parent_id);
796 Some(tcx.hir.local_def_id(parent_id))
801 let mut opt_self = None;
802 let mut allow_defaults = false;
804 let no_generics = hir::Generics::empty();
805 let ast_generics = match node {
806 NodeTraitItem(item) => {
808 TraitItemKind::Method(ref sig, _) => &sig.generics,
813 NodeImplItem(item) => {
815 ImplItemKind::Method(ref sig, _) => &sig.generics,
822 ItemFn(.., ref generics, _) |
823 ItemImpl(_, _, _, ref generics, ..) => generics,
825 ItemTy(_, ref generics) |
826 ItemEnum(_, ref generics) |
827 ItemStruct(_, ref generics) |
828 ItemUnion(_, ref generics) => {
829 allow_defaults = true;
833 ItemTrait(_, ref generics, ..) => {
834 // Add in the self type parameter.
836 // Something of a hack: use the node id for the trait, also as
837 // the node id for the Self type parameter.
838 let param_id = item.id;
840 opt_self = Some(ty::TypeParameterDef {
842 name: keywords::SelfType.name(),
843 def_id: tcx.hir.local_def_id(param_id),
845 object_lifetime_default: rl::Set1::Empty,
846 pure_wrt_drop: false,
849 allow_defaults = true;
857 NodeForeignItem(item) => {
859 ForeignItemStatic(..) => &no_generics,
860 ForeignItemFn(_, _, ref generics) => generics
867 let has_self = opt_self.is_some();
868 let mut parent_has_self = false;
869 let mut own_start = has_self as u32;
870 let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
871 let generics = tcx.generics_of(def_id);
872 assert_eq!(has_self, false);
873 parent_has_self = generics.has_self;
874 own_start = generics.count() as u32;
875 (generics.parent_regions + generics.regions.len() as u32,
876 generics.parent_types + generics.types.len() as u32)
879 let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
880 let regions = early_lifetimes.enumerate().map(|(i, l)| {
881 let issue_32330 = tcx.named_region_map.issue_32330.get(&l.lifetime.id).cloned();
882 ty::RegionParameterDef {
883 name: l.lifetime.name,
884 index: own_start + i as u32,
885 def_id: tcx.hir.local_def_id(l.lifetime.id),
886 pure_wrt_drop: l.pure_wrt_drop,
887 issue_32330: issue_32330,
889 }).collect::<Vec<_>>();
891 let object_lifetime_defaults =
892 tcx.named_region_map.object_lifetime_defaults.get(&node_id);
894 // Now create the real type parameters.
895 let type_start = own_start + regions.len() as u32;
896 let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
897 if p.name == keywords::SelfType.name() {
898 span_bug!(p.span, "`Self` should not be the name of a regular parameter");
901 if !allow_defaults && p.default.is_some() {
902 if !tcx.sess.features.borrow().default_type_parameter_fallback {
904 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
907 format!("defaults for type parameters are only allowed in `struct`, \
908 `enum`, `type`, or `trait` definitions."));
912 ty::TypeParameterDef {
913 index: type_start + i as u32,
915 def_id: tcx.hir.local_def_id(p.id),
916 has_default: p.default.is_some(),
917 object_lifetime_default:
918 object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
919 pure_wrt_drop: p.pure_wrt_drop,
922 let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
924 // provide junk type parameter defs - the only place that
925 // cares about anything but the length is instantiation,
926 // and we don't do that for closures.
927 if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node {
928 tcx.with_freevars(node_id, |fv| {
929 types.extend(fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
930 index: type_start + i as u32,
931 name: Symbol::intern("<upvar>"),
934 object_lifetime_default: rl::Set1::Empty,
935 pure_wrt_drop: false,
940 let mut type_param_to_index = BTreeMap::new();
941 for param in &types {
942 type_param_to_index.insert(param.def_id.index, param.index);
945 tcx.alloc_generics(ty::Generics {
946 parent: parent_def_id,
947 parent_regions: parent_regions,
948 parent_types: parent_types,
951 type_param_to_index: type_param_to_index,
952 has_self: has_self || parent_has_self
956 fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
959 use rustc::hir::map::*;
962 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
964 let icx = ItemCtxt::new(tcx, def_id);
966 match tcx.hir.get(node_id) {
967 NodeTraitItem(item) => {
969 TraitItemKind::Method(ref sig, _) => {
970 let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
971 let substs = Substs::identity_for_item(tcx, def_id);
972 tcx.mk_fn_def(def_id, substs, fty)
974 TraitItemKind::Const(ref ty, _) |
975 TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
976 TraitItemKind::Type(_, None) => {
977 span_bug!(item.span, "associated type missing default");
982 NodeImplItem(item) => {
984 ImplItemKind::Method(ref sig, _) => {
985 let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
986 let substs = Substs::identity_for_item(tcx, def_id);
987 tcx.mk_fn_def(def_id, substs, fty)
989 ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
990 ImplItemKind::Type(ref ty) => {
991 if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
992 span_err!(tcx.sess, item.span, E0202,
993 "associated types are not allowed in inherent impls");
1003 ItemStatic(ref t, ..) | ItemConst(ref t, _) |
1004 ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
1007 ItemFn(ref decl, unsafety, _, abi, _, _) => {
1008 let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl);
1009 let substs = Substs::identity_for_item(tcx, def_id);
1010 tcx.mk_fn_def(def_id, substs, tofd)
1015 let def = tcx.adt_def(def_id);
1016 let substs = Substs::identity_for_item(tcx, def_id);
1017 tcx.mk_adt(def, substs)
1019 ItemDefaultImpl(..) |
1022 ItemForeignMod(..) |
1024 ItemExternCrate(..) |
1028 "compute_type_of_item: unexpected item type: {:?}",
1034 NodeForeignItem(foreign_item) => {
1035 let abi = tcx.hir.get_foreign_abi(node_id);
1037 match foreign_item.node {
1038 ForeignItemFn(ref fn_decl, _, _) => {
1039 compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1041 ForeignItemStatic(ref t, _) => icx.to_ty(t)
1045 NodeStructCtor(&ref def) |
1046 NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
1047 let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
1049 VariantData::Unit(..) | VariantData::Struct(..) => ty,
1050 VariantData::Tuple(ref fields, _) => {
1051 let inputs = fields.iter().map(|f| {
1052 tcx.type_of(tcx.hir.local_def_id(f.id))
1054 let substs = Substs::identity_for_item(tcx, def_id);
1055 tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
1059 hir::Unsafety::Normal,
1066 NodeField(field) => icx.to_ty(&field.ty),
1068 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1069 tcx.mk_closure(def_id, Substs::for_item(
1072 let region = def.to_early_bound_region_data();
1073 tcx.mk_region(ty::ReEarlyBound(region))
1075 |def, _| tcx.mk_param_from_def(def)
1079 NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
1080 NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
1081 NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
1082 NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
1083 if body.node_id == node_id => tcx.types.usize,
1085 NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
1086 if e.node_id == node_id => {
1087 tcx.adt_def(tcx.hir.get_parent_did(node_id))
1088 .repr.discr_type().to_ty(tcx)
1092 bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
1096 NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
1100 NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1101 let owner = tcx.hir.get_parent_did(node_id);
1102 tcx.typeck_tables_of(owner).node_id_to_type(node_id)
1106 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1111 fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1113 -> Option<ty::TraitRef<'tcx>> {
1114 let icx = ItemCtxt::new(tcx, def_id);
1116 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1117 match tcx.hir.expect_item(node_id).node {
1118 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
1119 Some(AstConv::instantiate_mono_trait_ref(&icx,
1121 tcx.mk_self_type()))
1123 hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
1124 opt_trait_ref.as_ref().map(|ast_trait_ref| {
1125 let selfty = tcx.type_of(def_id);
1126 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1133 fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1135 -> hir::ImplPolarity {
1136 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1137 match tcx.hir.expect_item(node_id).node {
1138 hir::ItemImpl(_, polarity, ..) => polarity,
1139 ref item => bug!("impl_polarity: {:?} not an impl", item)
1143 // Is it marked with ?Sized
1144 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1145 ast_bounds: &[hir::TyParamBound],
1148 let tcx = astconv.tcx();
1150 // Try to find an unbound in bounds.
1151 let mut unbound = None;
1152 for ab in ast_bounds {
1153 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1154 if unbound.is_none() {
1155 unbound = Some(ptr.trait_ref.clone());
1157 span_err!(tcx.sess, span, E0203,
1158 "type parameter has more than one relaxed default \
1159 bound, only one is supported");
1164 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1167 // FIXME(#8559) currently requires the unbound to be built-in.
1168 if let Ok(kind_id) = kind_id {
1169 if tpb.path.def != Def::Trait(kind_id) {
1170 tcx.sess.span_warn(span,
1171 "default bound relaxed for a type parameter, but \
1172 this does nothing because the given bound is not \
1173 a default. Only `?Sized` is supported");
1177 _ if kind_id.is_ok() => {
1180 // No lang item for Sized, so we can't add it as a bound.
1187 /// Returns the early-bound lifetimes declared in this generics
1188 /// listing. For anything other than fns/methods, this is just all
1189 /// the lifetimes that are declared. For fns or methods, we have to
1190 /// screen out those that do not appear in any where-clauses etc using
1191 /// `resolve_lifetime::early_bound_lifetimes`.
1192 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1193 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1194 ast_generics: &'a hir::Generics)
1195 -> impl Iterator<Item=&'a hir::LifetimeDef>
1200 .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
1203 fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1205 -> ty::GenericPredicates<'tcx> {
1206 use rustc::hir::map::*;
1209 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1210 let node = tcx.hir.get(node_id);
1212 let mut is_trait = None;
1214 let icx = ItemCtxt::new(tcx, def_id);
1215 let no_generics = hir::Generics::empty();
1216 let ast_generics = match node {
1217 NodeTraitItem(item) => {
1219 TraitItemKind::Method(ref sig, _) => &sig.generics,
1224 NodeImplItem(item) => {
1226 ImplItemKind::Method(ref sig, _) => &sig.generics,
1233 ItemFn(.., ref generics, _) |
1234 ItemImpl(_, _, _, ref generics, ..) |
1235 ItemTy(_, ref generics) |
1236 ItemEnum(_, ref generics) |
1237 ItemStruct(_, ref generics) |
1238 ItemUnion(_, ref generics) => {
1242 ItemTrait(_, ref generics, .., ref items) => {
1243 is_trait = Some((ty::TraitRef {
1245 substs: Substs::identity_for_item(tcx, def_id)
1254 NodeForeignItem(item) => {
1256 ForeignItemStatic(..) => &no_generics,
1257 ForeignItemFn(_, _, ref generics) => generics
1261 NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1262 let substs = Substs::identity_for_item(tcx, def_id);
1263 let anon_ty = tcx.mk_anon(def_id, substs);
1265 // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1266 let bounds = compute_bounds(&icx, anon_ty, bounds,
1267 SizedByDefault::Yes,
1269 return ty::GenericPredicates {
1271 predicates: bounds.predicates(tcx, anon_ty)
1278 let generics = tcx.generics_of(def_id);
1279 let parent_count = generics.parent_count() as u32;
1280 let has_own_self = generics.has_self && parent_count == 0;
1282 let mut predicates = vec![];
1284 // Below we'll consider the bounds on the type parameters (including `Self`)
1285 // and the explicit where-clauses, but to get the full set of predicates
1286 // on a trait we need to add in the supertrait bounds and bounds found on
1287 // associated types.
1288 if let Some((trait_ref, _)) = is_trait {
1289 predicates = tcx.super_predicates_of(def_id).predicates;
1291 // Add in a predicate that `Self:Trait` (where `Trait` is the
1292 // current trait). This is needed for builtin bounds.
1293 predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
1296 // Collect the region predicates that were declared inline as
1297 // well. In the case of parameters declared on a fn or method, we
1298 // have to be careful to only iterate over early-bound regions.
1299 let mut index = parent_count + has_own_self as u32;
1300 for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1301 let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1303 name: param.lifetime.name
1307 for bound in ¶m.bounds {
1308 let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
1309 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1310 predicates.push(outlives.to_predicate());
1314 // Collect the predicates that were written inline by the user on each
1315 // type parameter (e.g., `<T:Foo>`).
1316 for param in &ast_generics.ty_params {
1317 let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
1320 let bounds = compute_bounds(&icx,
1323 SizedByDefault::Yes,
1325 predicates.extend(bounds.predicates(tcx, param_ty));
1328 // Add in the bounds that appear in the where-clause
1329 let where_clause = &ast_generics.where_clause;
1330 for predicate in &where_clause.predicates {
1332 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1333 let ty = icx.to_ty(&bound_pred.bounded_ty);
1335 for bound in bound_pred.bounds.iter() {
1337 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1338 let mut projections = Vec::new();
1341 AstConv::instantiate_poly_trait_ref(&icx,
1346 predicates.push(trait_ref.to_predicate());
1348 for projection in &projections {
1349 predicates.push(projection.to_predicate());
1353 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1354 let region = AstConv::ast_region_to_region(&icx,
1357 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1358 predicates.push(ty::Predicate::TypeOutlives(pred))
1364 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1365 let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
1366 for bound in ®ion_pred.bounds {
1367 let r2 = AstConv::ast_region_to_region(&icx, bound, None);
1368 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1369 predicates.push(ty::Predicate::RegionOutlives(pred))
1373 &hir::WherePredicate::EqPredicate(..) => {
1379 // Add predicates from associated type bounds.
1380 if let Some((self_trait_ref, trait_items)) = is_trait {
1381 predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1382 let trait_item = tcx.hir.trait_item(trait_item_ref.id);
1383 let bounds = match trait_item.node {
1384 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1386 return vec![].into_iter();
1390 let assoc_ty = tcx.mk_projection(self_trait_ref, trait_item.name);
1392 let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id),
1395 SizedByDefault::Yes,
1398 bounds.predicates(tcx, assoc_ty).into_iter()
1402 // Subtle: before we store the predicates into the tcx, we
1403 // sort them so that predicates like `T: Foo<Item=U>` come
1404 // before uses of `U`. This avoids false ambiguity errors
1405 // in trait checking. See `setup_constraining_predicates`
1407 if let NodeItem(&Item { node: ItemImpl(..), .. }) = node {
1408 let self_ty = tcx.type_of(def_id);
1409 let trait_ref = tcx.impl_trait_ref(def_id);
1410 ctp::setup_constraining_predicates(&mut predicates,
1412 &mut ctp::parameters_for_impl(self_ty, trait_ref));
1415 ty::GenericPredicates {
1416 parent: generics.parent,
1417 predicates: predicates
1421 pub enum SizedByDefault { Yes, No, }
1423 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1424 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1425 /// built-in trait (formerly known as kind): Send.
1426 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1427 param_ty: ty::Ty<'tcx>,
1428 ast_bounds: &[hir::TyParamBound],
1429 sized_by_default: SizedByDefault,
1433 let mut region_bounds = vec![];
1434 let mut trait_bounds = vec![];
1435 for ast_bound in ast_bounds {
1437 hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
1438 trait_bounds.push(b);
1440 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
1441 hir::RegionTyParamBound(ref l) => {
1442 region_bounds.push(l);
1447 let mut projection_bounds = vec![];
1449 let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1450 astconv.instantiate_poly_trait_ref(bound,
1452 &mut projection_bounds)
1455 let region_bounds = region_bounds.into_iter().map(|r| {
1456 astconv.ast_region_to_region(r, None)
1459 trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1461 let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1462 !is_unsized(astconv, ast_bounds, span)
1468 region_bounds: region_bounds,
1469 implicitly_sized: implicitly_sized,
1470 trait_bounds: trait_bounds,
1471 projection_bounds: projection_bounds,
1475 /// Converts a specific TyParamBound from the AST into a set of
1476 /// predicates that apply to the self-type. A vector is returned
1477 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1478 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1479 /// and `<T as Bar>::X == i32`).
1480 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1482 bound: &hir::TyParamBound)
1483 -> Vec<ty::Predicate<'tcx>>
1486 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1487 let mut projections = Vec::new();
1488 let pred = astconv.instantiate_poly_trait_ref(tr,
1491 projections.into_iter()
1492 .map(|p| p.to_predicate())
1493 .chain(Some(pred.to_predicate()))
1496 hir::RegionTyParamBound(ref lifetime) => {
1497 let region = astconv.ast_region_to_region(lifetime, None);
1498 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1499 vec![ty::Predicate::TypeOutlives(pred)]
1501 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1507 fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
1508 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1514 let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
1516 // feature gate SIMD types in FFI, since I (huonw) am not sure the
1517 // ABIs are handled at all correctly.
1518 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
1519 && !tcx.sess.features.borrow().simd_ffi {
1520 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
1522 tcx.sess.struct_span_err(ast_ty.span,
1523 &format!("use of SIMD type `{}` in FFI is highly experimental and \
1524 may result in invalid code",
1525 tcx.hir.node_to_pretty_string(ast_ty.id)))
1526 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
1530 for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
1533 if let hir::Return(ref ty) = decl.output {
1534 check(&ty, *fty.output().skip_binder())
1538 let substs = Substs::identity_for_item(tcx, def_id);
1539 tcx.mk_fn_def(def_id, substs, fty)
1542 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1545 match tcx.hir.get_if_local(def_id) {
1546 Some(hir_map::NodeForeignItem(..)) => true,
1548 _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)