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 has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
776 node: hir_map::Node<'tcx>)
778 struct LateBoundRegionsDetector<'a, 'tcx: 'a> {
779 tcx: TyCtxt<'a, 'tcx, 'tcx>,
781 has_late_bound_regions: bool,
784 impl<'a, 'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'a, 'tcx> {
785 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
786 NestedVisitorMap::None
789 fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
790 if self.has_late_bound_regions { return }
792 hir::TyBareFn(..) => {
793 self.binder_depth += 1;
794 intravisit::walk_ty(self, ty);
795 self.binder_depth -= 1;
797 _ => intravisit::walk_ty(self, ty)
801 fn visit_poly_trait_ref(&mut self,
802 tr: &'tcx hir::PolyTraitRef,
803 m: hir::TraitBoundModifier) {
804 if self.has_late_bound_regions { return }
805 self.binder_depth += 1;
806 intravisit::walk_poly_trait_ref(self, tr, m);
807 self.binder_depth -= 1;
810 fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
811 if self.has_late_bound_regions { return }
813 match self.tcx.named_region_map.defs.get(<.id).cloned() {
814 Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {}
815 Some(rl::Region::LateBound(debruijn, _)) |
816 Some(rl::Region::LateBoundAnon(debruijn, _))
817 if debruijn.depth < self.binder_depth => {}
818 _ => self.has_late_bound_regions = true,
823 fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
824 generics: &'tcx hir::Generics,
825 decl: &'tcx hir::FnDecl)
827 let mut visitor = LateBoundRegionsDetector {
828 tcx, binder_depth: 1, has_late_bound_regions: false
830 for lifetime in &generics.lifetimes {
831 if tcx.named_region_map.late_bound.contains(&lifetime.lifetime.id) {
835 visitor.visit_fn_decl(decl);
836 visitor.has_late_bound_regions
840 hir_map::NodeTraitItem(item) => match item.node {
841 hir::TraitItemKind::Method(ref sig, _) =>
842 has_late_bound_regions(tcx, &sig.generics, &sig.decl),
845 hir_map::NodeImplItem(item) => match item.node {
846 hir::ImplItemKind::Method(ref sig, _) =>
847 has_late_bound_regions(tcx, &sig.generics, &sig.decl),
850 hir_map::NodeForeignItem(item) => match item.node {
851 hir::ForeignItemFn(ref fn_decl, _, ref generics) =>
852 has_late_bound_regions(tcx, generics, fn_decl),
855 hir_map::NodeItem(item) => match item.node {
856 hir::ItemFn(ref fn_decl, .., ref generics, _) =>
857 has_late_bound_regions(tcx, generics, fn_decl),
864 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
866 -> &'tcx ty::Generics {
867 use rustc::hir::map::*;
870 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
872 let node = tcx.hir.get(node_id);
873 let parent_def_id = match node {
879 let parent_id = tcx.hir.get_parent(node_id);
880 Some(tcx.hir.local_def_id(parent_id))
882 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
883 Some(tcx.closure_base_def_id(def_id))
885 NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
886 let mut parent_id = node_id;
888 match tcx.hir.get(parent_id) {
889 NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
891 parent_id = tcx.hir.get_parent_node(parent_id);
895 Some(tcx.hir.local_def_id(parent_id))
900 let mut opt_self = None;
901 let mut allow_defaults = false;
903 let no_generics = hir::Generics::empty();
904 let ast_generics = match node {
905 NodeTraitItem(item) => {
907 TraitItemKind::Method(ref sig, _) => &sig.generics,
912 NodeImplItem(item) => {
914 ImplItemKind::Method(ref sig, _) => &sig.generics,
921 ItemFn(.., ref generics, _) |
922 ItemImpl(_, _, _, ref generics, ..) => generics,
924 ItemTy(_, ref generics) |
925 ItemEnum(_, ref generics) |
926 ItemStruct(_, ref generics) |
927 ItemUnion(_, ref generics) => {
928 allow_defaults = true;
932 ItemTrait(_, ref generics, ..) => {
933 // Add in the self type parameter.
935 // Something of a hack: use the node id for the trait, also as
936 // the node id for the Self type parameter.
937 let param_id = item.id;
939 opt_self = Some(ty::TypeParameterDef {
941 name: keywords::SelfType.name(),
942 def_id: tcx.hir.local_def_id(param_id),
944 object_lifetime_default: rl::Set1::Empty,
945 pure_wrt_drop: false,
948 allow_defaults = true;
956 NodeForeignItem(item) => {
958 ForeignItemStatic(..) => &no_generics,
959 ForeignItemFn(_, _, ref generics) => generics
966 let has_self = opt_self.is_some();
967 let mut parent_has_self = false;
968 let mut own_start = has_self as u32;
969 let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
970 let generics = tcx.generics_of(def_id);
971 assert_eq!(has_self, false);
972 parent_has_self = generics.has_self;
973 own_start = generics.count() as u32;
974 (generics.parent_regions + generics.regions.len() as u32,
975 generics.parent_types + generics.types.len() as u32)
978 let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
979 let regions = early_lifetimes.enumerate().map(|(i, l)| {
980 let issue_32330 = tcx.named_region_map.issue_32330.get(&l.lifetime.id).cloned();
981 ty::RegionParameterDef {
982 name: l.lifetime.name,
983 index: own_start + i as u32,
984 def_id: tcx.hir.local_def_id(l.lifetime.id),
985 pure_wrt_drop: l.pure_wrt_drop,
986 issue_32330: issue_32330,
988 }).collect::<Vec<_>>();
990 let object_lifetime_defaults =
991 tcx.named_region_map.object_lifetime_defaults.get(&node_id);
993 // Now create the real type parameters.
994 let type_start = own_start + regions.len() as u32;
995 let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
996 if p.name == keywords::SelfType.name() {
997 span_bug!(p.span, "`Self` should not be the name of a regular parameter");
1000 if !allow_defaults && p.default.is_some() {
1001 if !tcx.sess.features.borrow().default_type_parameter_fallback {
1003 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1006 format!("defaults for type parameters are only allowed in `struct`, \
1007 `enum`, `type`, or `trait` definitions."));
1011 ty::TypeParameterDef {
1012 index: type_start + i as u32,
1014 def_id: tcx.hir.local_def_id(p.id),
1015 has_default: p.default.is_some(),
1016 object_lifetime_default:
1017 object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
1018 pure_wrt_drop: p.pure_wrt_drop,
1021 let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
1023 // provide junk type parameter defs - the only place that
1024 // cares about anything but the length is instantiation,
1025 // and we don't do that for closures.
1026 if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node {
1027 tcx.with_freevars(node_id, |fv| {
1028 types.extend(fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
1029 index: type_start + i as u32,
1030 name: Symbol::intern("<upvar>"),
1033 object_lifetime_default: rl::Set1::Empty,
1034 pure_wrt_drop: false,
1039 let mut type_param_to_index = BTreeMap::new();
1040 for param in &types {
1041 type_param_to_index.insert(param.def_id.index, param.index);
1044 tcx.alloc_generics(ty::Generics {
1045 parent: parent_def_id,
1046 parent_regions: parent_regions,
1047 parent_types: parent_types,
1050 type_param_to_index: type_param_to_index,
1051 has_self: has_self || parent_has_self,
1052 has_late_bound_regions: has_late_bound_regions(tcx, node),
1056 fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1059 use rustc::hir::map::*;
1062 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1064 let icx = ItemCtxt::new(tcx, def_id);
1066 match tcx.hir.get(node_id) {
1067 NodeTraitItem(item) => {
1069 TraitItemKind::Method(..) => {
1070 let substs = Substs::identity_for_item(tcx, def_id);
1071 tcx.mk_fn_def(def_id, substs)
1073 TraitItemKind::Const(ref ty, _) |
1074 TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
1075 TraitItemKind::Type(_, None) => {
1076 span_bug!(item.span, "associated type missing default");
1081 NodeImplItem(item) => {
1083 ImplItemKind::Method(..) => {
1084 let substs = Substs::identity_for_item(tcx, def_id);
1085 tcx.mk_fn_def(def_id, substs)
1087 ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
1088 ImplItemKind::Type(ref ty) => {
1089 if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
1090 span_err!(tcx.sess, item.span, E0202,
1091 "associated types are not allowed in inherent impls");
1101 ItemStatic(ref t, ..) | ItemConst(ref t, _) |
1102 ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
1106 let substs = Substs::identity_for_item(tcx, def_id);
1107 tcx.mk_fn_def(def_id, substs)
1112 let def = tcx.adt_def(def_id);
1113 let substs = Substs::identity_for_item(tcx, def_id);
1114 tcx.mk_adt(def, substs)
1116 ItemDefaultImpl(..) |
1119 ItemForeignMod(..) |
1121 ItemExternCrate(..) |
1125 "compute_type_of_item: unexpected item type: {:?}",
1131 NodeForeignItem(foreign_item) => {
1132 match foreign_item.node {
1133 ForeignItemFn(..) => {
1134 let substs = Substs::identity_for_item(tcx, def_id);
1135 tcx.mk_fn_def(def_id, substs)
1137 ForeignItemStatic(ref t, _) => icx.to_ty(t)
1141 NodeStructCtor(&ref def) |
1142 NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
1144 VariantData::Unit(..) | VariantData::Struct(..) => {
1145 tcx.type_of(tcx.hir.get_parent_did(node_id))
1147 VariantData::Tuple(..) => {
1148 let substs = Substs::identity_for_item(tcx, def_id);
1149 tcx.mk_fn_def(def_id, substs)
1154 NodeField(field) => icx.to_ty(&field.ty),
1156 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1157 tcx.mk_closure(def_id, Substs::for_item(
1160 let region = def.to_early_bound_region_data();
1161 tcx.mk_region(ty::ReEarlyBound(region))
1163 |def, _| tcx.mk_param_from_def(def)
1167 NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
1168 NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
1169 NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
1170 NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
1171 if body.node_id == node_id => tcx.types.usize,
1173 NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
1174 if e.node_id == node_id => {
1175 tcx.adt_def(tcx.hir.get_parent_did(node_id))
1176 .repr.discr_type().to_ty(tcx)
1180 bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
1184 NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
1188 NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1189 let owner = tcx.hir.get_parent_did(node_id);
1190 tcx.typeck_tables_of(owner).node_id_to_type(node_id)
1194 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1199 fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1201 -> ty::PolyFnSig<'tcx> {
1202 use rustc::hir::map::*;
1205 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1207 let icx = ItemCtxt::new(tcx, def_id);
1209 match tcx.hir.get(node_id) {
1210 NodeTraitItem(&hir::TraitItem { node: TraitItemKind::Method(ref sig, _), .. }) |
1211 NodeImplItem(&hir::ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) => {
1212 AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl)
1215 NodeItem(&hir::Item { node: ItemFn(ref decl, unsafety, _, abi, _, _), .. }) => {
1216 AstConv::ty_of_fn(&icx, unsafety, abi, decl)
1219 NodeForeignItem(&hir::ForeignItem { node: ForeignItemFn(ref fn_decl, _, _), .. }) => {
1220 let abi = tcx.hir.get_foreign_abi(node_id);
1221 compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1224 NodeStructCtor(&VariantData::Tuple(ref fields, _)) |
1225 NodeVariant(&Spanned { node: hir::Variant_ {
1226 data: VariantData::Tuple(ref fields, _), ..
1228 let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
1229 let inputs = fields.iter().map(|f| {
1230 tcx.type_of(tcx.hir.local_def_id(f.id))
1232 ty::Binder(tcx.mk_fn_sig(
1236 hir::Unsafety::Normal,
1241 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1242 tcx.typeck_tables_of(def_id).closure_tys[&node_id]
1246 bug!("unexpected sort of node in fn_sig(): {:?}", x);
1251 fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1253 -> Option<ty::TraitRef<'tcx>> {
1254 let icx = ItemCtxt::new(tcx, def_id);
1256 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1257 match tcx.hir.expect_item(node_id).node {
1258 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
1259 Some(AstConv::instantiate_mono_trait_ref(&icx,
1261 tcx.mk_self_type()))
1263 hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
1264 opt_trait_ref.as_ref().map(|ast_trait_ref| {
1265 let selfty = tcx.type_of(def_id);
1266 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1273 fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1275 -> hir::ImplPolarity {
1276 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1277 match tcx.hir.expect_item(node_id).node {
1278 hir::ItemImpl(_, polarity, ..) => polarity,
1279 ref item => bug!("impl_polarity: {:?} not an impl", item)
1283 // Is it marked with ?Sized
1284 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1285 ast_bounds: &[hir::TyParamBound],
1288 let tcx = astconv.tcx();
1290 // Try to find an unbound in bounds.
1291 let mut unbound = None;
1292 for ab in ast_bounds {
1293 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1294 if unbound.is_none() {
1295 unbound = Some(ptr.trait_ref.clone());
1297 span_err!(tcx.sess, span, E0203,
1298 "type parameter has more than one relaxed default \
1299 bound, only one is supported");
1304 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1307 // FIXME(#8559) currently requires the unbound to be built-in.
1308 if let Ok(kind_id) = kind_id {
1309 if tpb.path.def != Def::Trait(kind_id) {
1310 tcx.sess.span_warn(span,
1311 "default bound relaxed for a type parameter, but \
1312 this does nothing because the given bound is not \
1313 a default. Only `?Sized` is supported");
1317 _ if kind_id.is_ok() => {
1320 // No lang item for Sized, so we can't add it as a bound.
1327 /// Returns the early-bound lifetimes declared in this generics
1328 /// listing. For anything other than fns/methods, this is just all
1329 /// the lifetimes that are declared. For fns or methods, we have to
1330 /// screen out those that do not appear in any where-clauses etc using
1331 /// `resolve_lifetime::early_bound_lifetimes`.
1332 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1333 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1334 ast_generics: &'a hir::Generics)
1335 -> impl Iterator<Item=&'a hir::LifetimeDef>
1340 .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
1343 fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1345 -> ty::GenericPredicates<'tcx> {
1346 use rustc::hir::map::*;
1349 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1350 let node = tcx.hir.get(node_id);
1352 let mut is_trait = None;
1354 let icx = ItemCtxt::new(tcx, def_id);
1355 let no_generics = hir::Generics::empty();
1356 let ast_generics = match node {
1357 NodeTraitItem(item) => {
1359 TraitItemKind::Method(ref sig, _) => &sig.generics,
1364 NodeImplItem(item) => {
1366 ImplItemKind::Method(ref sig, _) => &sig.generics,
1373 ItemFn(.., ref generics, _) |
1374 ItemImpl(_, _, _, ref generics, ..) |
1375 ItemTy(_, ref generics) |
1376 ItemEnum(_, ref generics) |
1377 ItemStruct(_, ref generics) |
1378 ItemUnion(_, ref generics) => {
1382 ItemTrait(_, ref generics, .., ref items) => {
1383 is_trait = Some((ty::TraitRef {
1385 substs: Substs::identity_for_item(tcx, def_id)
1394 NodeForeignItem(item) => {
1396 ForeignItemStatic(..) => &no_generics,
1397 ForeignItemFn(_, _, ref generics) => generics
1401 NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1402 let substs = Substs::identity_for_item(tcx, def_id);
1403 let anon_ty = tcx.mk_anon(def_id, substs);
1405 // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1406 let bounds = compute_bounds(&icx, anon_ty, bounds,
1407 SizedByDefault::Yes,
1409 return ty::GenericPredicates {
1411 predicates: bounds.predicates(tcx, anon_ty)
1418 let generics = tcx.generics_of(def_id);
1419 let parent_count = generics.parent_count() as u32;
1420 let has_own_self = generics.has_self && parent_count == 0;
1422 let mut predicates = vec![];
1424 // Below we'll consider the bounds on the type parameters (including `Self`)
1425 // and the explicit where-clauses, but to get the full set of predicates
1426 // on a trait we need to add in the supertrait bounds and bounds found on
1427 // associated types.
1428 if let Some((trait_ref, _)) = is_trait {
1429 predicates = tcx.super_predicates_of(def_id).predicates;
1431 // Add in a predicate that `Self:Trait` (where `Trait` is the
1432 // current trait). This is needed for builtin bounds.
1433 predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
1436 // Collect the region predicates that were declared inline as
1437 // well. In the case of parameters declared on a fn or method, we
1438 // have to be careful to only iterate over early-bound regions.
1439 let mut index = parent_count + has_own_self as u32;
1440 for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1441 let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1442 def_id: tcx.hir.local_def_id(param.lifetime.id),
1444 name: param.lifetime.name
1448 for bound in ¶m.bounds {
1449 let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
1450 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1451 predicates.push(outlives.to_predicate());
1455 // Collect the predicates that were written inline by the user on each
1456 // type parameter (e.g., `<T:Foo>`).
1457 for param in &ast_generics.ty_params {
1458 let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
1461 let bounds = compute_bounds(&icx,
1464 SizedByDefault::Yes,
1466 predicates.extend(bounds.predicates(tcx, param_ty));
1469 // Add in the bounds that appear in the where-clause
1470 let where_clause = &ast_generics.where_clause;
1471 for predicate in &where_clause.predicates {
1473 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1474 let ty = icx.to_ty(&bound_pred.bounded_ty);
1476 for bound in bound_pred.bounds.iter() {
1478 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1479 let mut projections = Vec::new();
1482 AstConv::instantiate_poly_trait_ref(&icx,
1487 predicates.push(trait_ref.to_predicate());
1489 for projection in &projections {
1490 predicates.push(projection.to_predicate());
1494 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1495 let region = AstConv::ast_region_to_region(&icx,
1498 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1499 predicates.push(ty::Predicate::TypeOutlives(pred))
1505 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1506 let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
1507 for bound in ®ion_pred.bounds {
1508 let r2 = AstConv::ast_region_to_region(&icx, bound, None);
1509 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1510 predicates.push(ty::Predicate::RegionOutlives(pred))
1514 &hir::WherePredicate::EqPredicate(..) => {
1520 // Add predicates from associated type bounds.
1521 if let Some((self_trait_ref, trait_items)) = is_trait {
1522 predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1523 let trait_item = tcx.hir.trait_item(trait_item_ref.id);
1524 let bounds = match trait_item.node {
1525 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1527 return vec![].into_iter();
1531 let assoc_ty = tcx.mk_projection(
1532 tcx.hir.local_def_id(trait_item.id),
1533 self_trait_ref.substs,
1536 let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id),
1539 SizedByDefault::Yes,
1542 bounds.predicates(tcx, assoc_ty).into_iter()
1546 // Subtle: before we store the predicates into the tcx, we
1547 // sort them so that predicates like `T: Foo<Item=U>` come
1548 // before uses of `U`. This avoids false ambiguity errors
1549 // in trait checking. See `setup_constraining_predicates`
1551 if let NodeItem(&Item { node: ItemImpl(..), .. }) = node {
1552 let self_ty = tcx.type_of(def_id);
1553 let trait_ref = tcx.impl_trait_ref(def_id);
1554 ctp::setup_constraining_predicates(tcx,
1557 &mut ctp::parameters_for_impl(self_ty, trait_ref));
1560 ty::GenericPredicates {
1561 parent: generics.parent,
1562 predicates: predicates
1566 pub enum SizedByDefault { Yes, No, }
1568 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1569 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1570 /// built-in trait (formerly known as kind): Send.
1571 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1572 param_ty: ty::Ty<'tcx>,
1573 ast_bounds: &[hir::TyParamBound],
1574 sized_by_default: SizedByDefault,
1578 let mut region_bounds = vec![];
1579 let mut trait_bounds = vec![];
1580 for ast_bound in ast_bounds {
1582 hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
1583 trait_bounds.push(b);
1585 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
1586 hir::RegionTyParamBound(ref l) => {
1587 region_bounds.push(l);
1592 let mut projection_bounds = vec![];
1594 let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1595 astconv.instantiate_poly_trait_ref(bound,
1597 &mut projection_bounds)
1600 let region_bounds = region_bounds.into_iter().map(|r| {
1601 astconv.ast_region_to_region(r, None)
1604 trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1606 let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1607 !is_unsized(astconv, ast_bounds, span)
1613 region_bounds: region_bounds,
1614 implicitly_sized: implicitly_sized,
1615 trait_bounds: trait_bounds,
1616 projection_bounds: projection_bounds,
1620 /// Converts a specific TyParamBound from the AST into a set of
1621 /// predicates that apply to the self-type. A vector is returned
1622 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1623 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1624 /// and `<T as Bar>::X == i32`).
1625 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1627 bound: &hir::TyParamBound)
1628 -> Vec<ty::Predicate<'tcx>>
1631 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1632 let mut projections = Vec::new();
1633 let pred = astconv.instantiate_poly_trait_ref(tr,
1636 projections.into_iter()
1637 .map(|p| p.to_predicate())
1638 .chain(Some(pred.to_predicate()))
1641 hir::RegionTyParamBound(ref lifetime) => {
1642 let region = astconv.ast_region_to_region(lifetime, None);
1643 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1644 vec![ty::Predicate::TypeOutlives(pred)]
1646 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1652 fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
1653 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1657 -> ty::PolyFnSig<'tcx>
1659 let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
1661 // feature gate SIMD types in FFI, since I (huonw) am not sure the
1662 // ABIs are handled at all correctly.
1663 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
1664 && !tcx.sess.features.borrow().simd_ffi {
1665 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
1667 tcx.sess.struct_span_err(ast_ty.span,
1668 &format!("use of SIMD type `{}` in FFI is highly experimental and \
1669 may result in invalid code",
1670 tcx.hir.node_to_pretty_string(ast_ty.id)))
1671 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
1675 for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
1678 if let hir::Return(ref ty) = decl.output {
1679 check(&ty, *fty.output().skip_binder())
1686 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1689 match tcx.hir.get_if_local(def_id) {
1690 Some(hir_map::NodeForeignItem(..)) => true,
1692 _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
1696 fn is_default_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1699 match tcx.hir.get_if_local(def_id) {
1700 Some(hir_map::NodeItem(&hir::Item { node: hir::ItemDefaultImpl(..), .. }))
1703 _ => bug!("is_default_impl applied to non-local def-id {:?}", def_id)