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::traits::Reveal;
63 use rustc::ty::subst::Substs;
64 use rustc::ty::{ToPredicate, ReprOptions};
65 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
66 use rustc::ty::maps::Providers;
67 use rustc::ty::util::IntTypeExt;
68 use util::nodemap::FxHashMap;
70 use rustc_const_math::ConstInt;
72 use std::collections::BTreeMap;
74 use syntax::{abi, ast};
75 use syntax::codemap::Spanned;
76 use syntax::symbol::{Symbol, keywords};
77 use syntax_pos::{Span, DUMMY_SP};
79 use rustc::hir::{self, map as hir_map};
80 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
81 use rustc::hir::def::{Def, CtorKind};
82 use rustc::hir::def_id::DefId;
84 ///////////////////////////////////////////////////////////////////////////
87 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
88 let mut visitor = CollectItemTypesVisitor { tcx: tcx };
89 tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
92 pub fn provide(providers: &mut Providers) {
93 *providers = Providers {
98 type_param_predicates,
110 ///////////////////////////////////////////////////////////////////////////
112 /// Context specific to some particular item. This is what implements
113 /// AstConv. It has information about the predicates that are defined
114 /// on the trait. Unfortunately, this predicate information is
115 /// available in various different forms at various points in the
116 /// process. So we can't just store a pointer to e.g. the AST or the
117 /// parsed ty form, we have to be more flexible. To this end, the
118 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
119 /// `get_type_parameter_bounds` requests, drawing the information from
120 /// the AST (`hir::Generics`), recursively.
121 pub struct ItemCtxt<'a,'tcx:'a> {
122 tcx: TyCtxt<'a, 'tcx, 'tcx>,
126 ///////////////////////////////////////////////////////////////////////////
128 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
129 tcx: TyCtxt<'a, 'tcx, 'tcx>
132 impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
133 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
134 NestedVisitorMap::OnlyBodies(&self.tcx.hir)
137 fn visit_item(&mut self, item: &'tcx hir::Item) {
138 convert_item(self.tcx, item.id);
139 intravisit::walk_item(self, item);
142 fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
143 for param in &generics.ty_params {
144 if param.default.is_some() {
145 let def_id = self.tcx.hir.local_def_id(param.id);
146 self.tcx.type_of(def_id);
149 intravisit::walk_generics(self, generics);
152 fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
153 if let hir::ExprClosure(..) = expr.node {
154 let def_id = self.tcx.hir.local_def_id(expr.id);
155 self.tcx.generics_of(def_id);
156 self.tcx.type_of(def_id);
158 intravisit::walk_expr(self, expr);
161 fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
162 if let hir::TyImplTrait(..) = ty.node {
163 let def_id = self.tcx.hir.local_def_id(ty.id);
164 self.tcx.generics_of(def_id);
165 self.tcx.predicates_of(def_id);
167 intravisit::walk_ty(self, ty);
170 fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
171 convert_trait_item(self.tcx, trait_item.id);
172 intravisit::walk_trait_item(self, trait_item);
175 fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
176 convert_impl_item(self.tcx, impl_item.id);
177 intravisit::walk_impl_item(self, impl_item);
181 ///////////////////////////////////////////////////////////////////////////
182 // Utility types and common code for the above passes.
184 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
185 pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
186 -> ItemCtxt<'a,'tcx> {
194 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
195 pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
196 AstConv::ast_ty_to_ty(self, ast_ty)
200 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
201 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx }
203 fn get_type_parameter_bounds(&self,
206 -> ty::GenericPredicates<'tcx>
208 self.tcx.at(span).type_param_predicates((self.item_def_id, def_id))
211 fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
212 -> Option<ty::Region<'tcx>> {
216 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
221 "the type placeholder `_` is not allowed within types on item signatures"
222 ).span_label(span, "not allowed in type signatures")
227 fn projected_ty_from_poly_trait_ref(&self,
230 poly_trait_ref: ty::PolyTraitRef<'tcx>)
233 if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
234 self.tcx().mk_projection(item_def_id, trait_ref.substs)
236 // no late-bound regions, we can just ignore the binder
237 span_err!(self.tcx().sess, span, E0212,
238 "cannot extract an associated type from a higher-ranked trait bound \
244 fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
245 // types in item signatures are not normalized, to avoid undue
250 fn set_tainted_by_errors(&self) {
251 // no obvious place to track this, just let it go
255 fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
256 (item_def_id, def_id): (DefId, DefId))
257 -> ty::GenericPredicates<'tcx> {
258 use rustc::hir::map::*;
261 // In the AST, bounds can derive from two places. Either
262 // written inline like `<T:Foo>` or in a where clause like
265 let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
266 let param_owner = tcx.hir.ty_param_owner(param_id);
267 let param_owner_def_id = tcx.hir.local_def_id(param_owner);
268 let generics = tcx.generics_of(param_owner_def_id);
269 let index = generics.type_param_to_index[&def_id.index];
270 let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id));
272 // Don't look for bounds where the type parameter isn't in scope.
273 let parent = if item_def_id == param_owner_def_id {
276 tcx.generics_of(item_def_id).parent
279 let mut result = parent.map_or(ty::GenericPredicates {
283 let icx = ItemCtxt::new(tcx, parent);
284 icx.get_type_parameter_bounds(DUMMY_SP, def_id)
287 let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
288 let ast_generics = match tcx.hir.get(item_node_id) {
289 NodeTraitItem(item) => {
291 TraitItemKind::Method(ref sig, _) => &sig.generics,
296 NodeImplItem(item) => {
298 ImplItemKind::Method(ref sig, _) => &sig.generics,
305 ItemFn(.., ref generics, _) |
306 ItemImpl(_, _, _, ref generics, ..) |
307 ItemTy(_, ref generics) |
308 ItemEnum(_, ref generics) |
309 ItemStruct(_, ref generics) |
310 ItemUnion(_, ref generics) => generics,
311 ItemTrait(_, ref generics, ..) => {
312 // Implied `Self: Trait` and supertrait bounds.
313 if param_id == item_node_id {
314 result.predicates.push(ty::TraitRef {
316 substs: Substs::identity_for_item(tcx, item_def_id)
325 NodeForeignItem(item) => {
327 ForeignItemFn(_, _, ref generics) => generics,
335 let icx = ItemCtxt::new(tcx, item_def_id);
336 result.predicates.extend(
337 icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty));
341 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
342 /// Find bounds from hir::Generics. This requires scanning through the
343 /// AST. We do this to avoid having to convert *all* the bounds, which
344 /// would create artificial cycles. Instead we can only convert the
345 /// bounds for a type parameter `X` if `X::Foo` is used.
346 fn type_parameter_bounds_in_generics(&self,
347 ast_generics: &hir::Generics,
348 param_id: ast::NodeId,
350 -> Vec<ty::Predicate<'tcx>>
353 ast_generics.ty_params
355 .filter(|p| p.id == param_id)
356 .flat_map(|p| p.bounds.iter())
357 .flat_map(|b| predicates_from_bound(self, ty, b));
359 let from_where_clauses =
360 ast_generics.where_clause
363 .filter_map(|wp| match *wp {
364 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
367 .filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id))
368 .flat_map(|bp| bp.bounds.iter())
369 .flat_map(|b| predicates_from_bound(self, ty, b));
371 from_ty_params.chain(from_where_clauses).collect()
375 /// Tests whether this is the AST for a reference to the type
376 /// parameter with id `param_id`. We use this so as to avoid running
377 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
378 /// conversion of the type to avoid inducing unnecessary cycles.
379 fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
381 param_id: ast::NodeId)
384 if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
386 Def::SelfTy(Some(def_id), None) |
387 Def::TyParam(def_id) => {
388 def_id == tcx.hir.local_def_id(param_id)
397 fn ensure_no_ty_param_bounds(tcx: TyCtxt,
399 generics: &hir::Generics,
400 thing: &'static str) {
401 let mut warn = false;
403 for ty_param in generics.ty_params.iter() {
404 for bound in ty_param.bounds.iter() {
406 hir::TraitTyParamBound(..) => {
409 hir::RegionTyParamBound(..) => { }
414 for predicate in generics.where_clause.predicates.iter() {
416 hir::WherePredicate::BoundPredicate(..) => {
419 hir::WherePredicate::RegionPredicate(..) => { }
420 hir::WherePredicate::EqPredicate(..) => { }
425 // According to accepted RFC #XXX, we should
426 // eventually accept these, but it will not be
427 // part of this PR. Still, convert to warning to
428 // make bootstrapping easier.
429 span_warn!(tcx.sess, span, E0122,
430 "trait bounds are not (yet) enforced \
436 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
437 let it = tcx.hir.expect_item(item_id);
438 debug!("convert: item {} with id {}", it.name, it.id);
439 let def_id = tcx.hir.local_def_id(item_id);
441 // These don't define types.
442 hir::ItemExternCrate(_) |
445 hir::ItemGlobalAsm(_) => {}
446 hir::ItemForeignMod(ref foreign_mod) => {
447 for item in &foreign_mod.items {
448 let def_id = tcx.hir.local_def_id(item.id);
449 tcx.generics_of(def_id);
451 tcx.predicates_of(def_id);
452 if let hir::ForeignItemFn(..) = item.node {
457 hir::ItemEnum(ref enum_definition, _) => {
458 tcx.generics_of(def_id);
460 tcx.predicates_of(def_id);
461 convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
463 hir::ItemDefaultImpl(..) => {
464 tcx.impl_trait_ref(def_id);
466 hir::ItemImpl(..) => {
467 tcx.generics_of(def_id);
469 tcx.impl_trait_ref(def_id);
470 tcx.predicates_of(def_id);
472 hir::ItemTrait(..) => {
473 tcx.generics_of(def_id);
474 tcx.trait_def(def_id);
475 tcx.at(it.span).super_predicates_of(def_id);
476 tcx.predicates_of(def_id);
478 hir::ItemStruct(ref struct_def, _) |
479 hir::ItemUnion(ref struct_def, _) => {
480 tcx.generics_of(def_id);
482 tcx.predicates_of(def_id);
484 for f in struct_def.fields() {
485 let def_id = tcx.hir.local_def_id(f.id);
486 tcx.generics_of(def_id);
488 tcx.predicates_of(def_id);
491 if !struct_def.is_struct() {
492 convert_variant_ctor(tcx, struct_def.id());
495 hir::ItemTy(_, ref generics) => {
496 ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
497 tcx.generics_of(def_id);
499 tcx.predicates_of(def_id);
501 hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => {
502 tcx.generics_of(def_id);
504 tcx.predicates_of(def_id);
505 if let hir::ItemFn(..) = it.node {
512 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
513 let trait_item = tcx.hir.expect_trait_item(trait_item_id);
514 let def_id = tcx.hir.local_def_id(trait_item.id);
515 tcx.generics_of(def_id);
517 match trait_item.node {
518 hir::TraitItemKind::Const(..) |
519 hir::TraitItemKind::Type(_, Some(_)) |
520 hir::TraitItemKind::Method(..) => {
522 if let hir::TraitItemKind::Method(..) = trait_item.node {
527 hir::TraitItemKind::Type(_, None) => {}
530 tcx.predicates_of(def_id);
533 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
534 let def_id = tcx.hir.local_def_id(impl_item_id);
535 tcx.generics_of(def_id);
537 tcx.predicates_of(def_id);
538 if let hir::ImplItemKind::Method(..) = tcx.hir.expect_impl_item(impl_item_id).node {
543 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
544 ctor_id: ast::NodeId) {
545 let def_id = tcx.hir.local_def_id(ctor_id);
546 tcx.generics_of(def_id);
548 tcx.predicates_of(def_id);
551 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
553 variants: &[hir::Variant]) {
554 let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
555 let def = tcx.adt_def(def_id);
556 let repr_type = def.repr.discr_type();
557 let initial = repr_type.initial_discriminant(tcx);
558 let mut prev_discr = None::<ConstInt>;
560 // fill the discriminant values and field types
561 for variant in variants {
562 let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr());
563 prev_discr = Some(if let Some(e) = variant.node.disr_expr {
564 let expr_did = tcx.hir.local_def_id(e.node_id);
565 let substs = Substs::identity_for_item(tcx, expr_did);
566 let result = tcx.at(variant.span).const_eval(param_env.and((expr_did, substs)));
568 // enum variant evaluation happens before the global constant check
569 // so we need to report the real error
570 if let Err(ref err) = result {
571 err.report(tcx, variant.span, "enum discriminant");
575 Ok(ConstVal::Integral(x)) => Some(x),
578 } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
581 struct_span_err!(tcx.sess, variant.span, E0370,
582 "enum discriminant overflowed")
583 .span_label(variant.span, format!("overflowed on value after {}",
584 prev_discr.unwrap()))
585 .note(&format!("explicitly set `{} = {}` if that is desired outcome",
586 variant.node.name, wrapped_discr))
589 }.unwrap_or(wrapped_discr));
591 for f in variant.node.data.fields() {
592 let def_id = tcx.hir.local_def_id(f.id);
593 tcx.generics_of(def_id);
595 tcx.predicates_of(def_id);
598 // Convert the ctor, if any. This also registers the variant as
600 convert_variant_ctor(tcx, variant.node.data.id());
604 fn convert_struct_variant<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
607 discr: ty::VariantDiscr,
608 def: &hir::VariantData)
610 let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
611 let node_id = tcx.hir.as_local_node_id(did).unwrap();
612 let fields = def.fields().iter().map(|f| {
613 let fid = tcx.hir.local_def_id(f.id);
614 let dup_span = seen_fields.get(&f.name).cloned();
615 if let Some(prev_span) = dup_span {
616 struct_span_err!(tcx.sess, f.span, E0124,
617 "field `{}` is already declared",
619 .span_label(f.span, "field already declared")
620 .span_label(prev_span, format!("`{}` first declared here", f.name))
623 seen_fields.insert(f.name, f.span);
629 vis: ty::Visibility::from_hir(&f.vis, node_id, tcx)
637 ctor_kind: CtorKind::from_hir(def),
641 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
643 -> &'tcx ty::AdtDef {
644 use rustc::hir::map::*;
647 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
648 let item = match tcx.hir.get(node_id) {
649 NodeItem(item) => item,
653 let repr = ReprOptions::new(tcx, def_id);
654 let (kind, variants) = match item.node {
655 ItemEnum(ref def, _) => {
656 let mut distance_from_explicit = 0;
657 (AdtKind::Enum, def.variants.iter().map(|v| {
658 let did = tcx.hir.local_def_id(v.node.data.id());
659 let discr = if let Some(e) = v.node.disr_expr {
660 distance_from_explicit = 0;
661 ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
663 ty::VariantDiscr::Relative(distance_from_explicit)
665 distance_from_explicit += 1;
667 convert_struct_variant(tcx, did, v.node.name, discr, &v.node.data)
670 ItemStruct(ref def, _) => {
671 // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
672 let ctor_id = if !def.is_struct() {
673 Some(tcx.hir.local_def_id(def.id()))
677 (AdtKind::Struct, vec![
678 convert_struct_variant(tcx, ctor_id.unwrap_or(def_id), item.name,
679 ty::VariantDiscr::Relative(0), def)
682 ItemUnion(ref def, _) => {
683 (AdtKind::Union, vec![
684 convert_struct_variant(tcx, def_id, item.name,
685 ty::VariantDiscr::Relative(0), def)
690 tcx.alloc_adt_def(def_id, kind, variants, repr)
693 /// Ensures that the super-predicates of the trait with def-id
694 /// trait_def_id are converted and stored. This also ensures that
695 /// the transitive super-predicates are converted;
696 fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
698 -> ty::GenericPredicates<'tcx> {
699 debug!("super_predicates(trait_def_id={:?})", trait_def_id);
700 let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
702 let item = match tcx.hir.get(trait_node_id) {
703 hir_map::NodeItem(item) => item,
704 _ => bug!("trait_node_id {} is not an item", trait_node_id)
707 let (generics, bounds) = match item.node {
708 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
709 _ => span_bug!(item.span,
710 "super_predicates invoked on non-trait"),
713 let icx = ItemCtxt::new(tcx, trait_def_id);
715 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
716 let self_param_ty = tcx.mk_self_type();
717 let superbounds1 = compute_bounds(&icx,
723 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
725 // Convert any explicit superbounds in the where clause,
726 // e.g. `trait Foo where Self : Bar`:
727 let superbounds2 = icx.type_parameter_bounds_in_generics(generics, item.id, self_param_ty);
729 // Combine the two lists to form the complete set of superbounds:
730 let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
732 // Now require that immediate supertraits are converted,
733 // which will, in turn, reach indirect supertraits.
734 for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) {
735 tcx.at(item.span).super_predicates_of(bound.def_id());
738 ty::GenericPredicates {
740 predicates: superbounds
744 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
746 -> &'tcx ty::TraitDef {
747 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
748 let item = tcx.hir.expect_item(node_id);
750 let unsafety = match item.node {
751 hir::ItemTrait(unsafety, ..) => unsafety,
752 _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
755 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
756 if paren_sugar && !tcx.sess.features.borrow().unboxed_closures {
757 let mut err = tcx.sess.struct_span_err(
759 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
760 which traits can use parenthetical notation");
762 "add `#![feature(unboxed_closures)]` to \
763 the crate attributes to use it");
767 let def_path_hash = tcx.def_path_hash(def_id);
768 let has_default_impl = tcx.hir.trait_is_auto(def_id);
769 let def = ty::TraitDef::new(def_id,
774 tcx.alloc_trait_def(def)
777 fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
778 node: hir_map::Node<'tcx>)
780 struct LateBoundRegionsDetector<'a, 'tcx: 'a> {
781 tcx: TyCtxt<'a, 'tcx, 'tcx>,
783 has_late_bound_regions: Option<Span>,
786 impl<'a, 'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'a, 'tcx> {
787 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
788 NestedVisitorMap::None
791 fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
792 if self.has_late_bound_regions.is_some() { return }
794 hir::TyBareFn(..) => {
795 self.binder_depth += 1;
796 intravisit::walk_ty(self, ty);
797 self.binder_depth -= 1;
799 _ => intravisit::walk_ty(self, ty)
803 fn visit_poly_trait_ref(&mut self,
804 tr: &'tcx hir::PolyTraitRef,
805 m: hir::TraitBoundModifier) {
806 if self.has_late_bound_regions.is_some() { return }
807 self.binder_depth += 1;
808 intravisit::walk_poly_trait_ref(self, tr, m);
809 self.binder_depth -= 1;
812 fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
813 if self.has_late_bound_regions.is_some() { return }
815 match self.tcx.named_region_map.defs.get(<.id).cloned() {
816 Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {}
817 Some(rl::Region::LateBound(debruijn, _)) |
818 Some(rl::Region::LateBoundAnon(debruijn, _))
819 if debruijn.depth < self.binder_depth => {}
820 _ => self.has_late_bound_regions = Some(lt.span),
825 fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
826 generics: &'tcx hir::Generics,
827 decl: &'tcx hir::FnDecl)
829 let mut visitor = LateBoundRegionsDetector {
830 tcx, binder_depth: 1, has_late_bound_regions: None
832 for lifetime in &generics.lifetimes {
833 if tcx.named_region_map.late_bound.contains(&lifetime.lifetime.id) {
834 return Some(lifetime.lifetime.span);
837 visitor.visit_fn_decl(decl);
838 visitor.has_late_bound_regions
842 hir_map::NodeTraitItem(item) => match item.node {
843 hir::TraitItemKind::Method(ref sig, _) =>
844 has_late_bound_regions(tcx, &sig.generics, &sig.decl),
847 hir_map::NodeImplItem(item) => match item.node {
848 hir::ImplItemKind::Method(ref sig, _) =>
849 has_late_bound_regions(tcx, &sig.generics, &sig.decl),
852 hir_map::NodeForeignItem(item) => match item.node {
853 hir::ForeignItemFn(ref fn_decl, _, ref generics) =>
854 has_late_bound_regions(tcx, generics, fn_decl),
857 hir_map::NodeItem(item) => match item.node {
858 hir::ItemFn(ref fn_decl, .., ref generics, _) =>
859 has_late_bound_regions(tcx, generics, fn_decl),
866 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
868 -> &'tcx ty::Generics {
869 use rustc::hir::map::*;
872 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
874 let node = tcx.hir.get(node_id);
875 let parent_def_id = match node {
881 let parent_id = tcx.hir.get_parent(node_id);
882 Some(tcx.hir.local_def_id(parent_id))
884 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
885 Some(tcx.closure_base_def_id(def_id))
887 NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
888 let mut parent_id = node_id;
890 match tcx.hir.get(parent_id) {
891 NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
893 parent_id = tcx.hir.get_parent_node(parent_id);
897 Some(tcx.hir.local_def_id(parent_id))
902 let mut opt_self = None;
903 let mut allow_defaults = false;
905 let no_generics = hir::Generics::empty();
906 let ast_generics = match node {
907 NodeTraitItem(item) => {
909 TraitItemKind::Method(ref sig, _) => &sig.generics,
914 NodeImplItem(item) => {
916 ImplItemKind::Method(ref sig, _) => &sig.generics,
923 ItemFn(.., ref generics, _) |
924 ItemImpl(_, _, _, ref generics, ..) => generics,
926 ItemTy(_, ref generics) |
927 ItemEnum(_, ref generics) |
928 ItemStruct(_, ref generics) |
929 ItemUnion(_, ref generics) => {
930 allow_defaults = true;
934 ItemTrait(_, ref generics, ..) => {
935 // Add in the self type parameter.
937 // Something of a hack: use the node id for the trait, also as
938 // the node id for the Self type parameter.
939 let param_id = item.id;
941 opt_self = Some(ty::TypeParameterDef {
943 name: keywords::SelfType.name(),
944 def_id: tcx.hir.local_def_id(param_id),
946 object_lifetime_default: rl::Set1::Empty,
947 pure_wrt_drop: false,
950 allow_defaults = true;
958 NodeForeignItem(item) => {
960 ForeignItemStatic(..) => &no_generics,
961 ForeignItemFn(_, _, ref generics) => generics
968 let has_self = opt_self.is_some();
969 let mut parent_has_self = false;
970 let mut own_start = has_self as u32;
971 let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
972 let generics = tcx.generics_of(def_id);
973 assert_eq!(has_self, false);
974 parent_has_self = generics.has_self;
975 own_start = generics.count() as u32;
976 (generics.parent_regions + generics.regions.len() as u32,
977 generics.parent_types + generics.types.len() as u32)
980 let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
981 let regions = early_lifetimes.enumerate().map(|(i, l)| {
982 ty::RegionParameterDef {
983 name: l.lifetime.name,
984 index: own_start + i as u32,
985 def_id: tcx.hir.local_def_id(l.lifetime.id),
986 pure_wrt_drop: l.pure_wrt_drop,
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,
1050 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(.., is_generator), .. }) => {
1158 let hir_id = tcx.hir.node_to_hir_id(node_id);
1159 return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id);
1162 tcx.mk_closure(def_id, Substs::for_item(
1165 let region = def.to_early_bound_region_data();
1166 tcx.mk_region(ty::ReEarlyBound(region))
1168 |def, _| tcx.mk_param_from_def(def)
1172 NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
1173 NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
1174 NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
1175 NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
1176 if body.node_id == node_id => tcx.types.usize,
1178 NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
1179 if e.node_id == node_id => {
1180 tcx.adt_def(tcx.hir.get_parent_did(node_id))
1181 .repr.discr_type().to_ty(tcx)
1185 bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
1189 NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
1193 NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1194 let owner = tcx.hir.get_parent_did(node_id);
1195 let hir_id = tcx.hir.node_to_hir_id(node_id);
1196 tcx.typeck_tables_of(owner).node_id_to_type(hir_id)
1200 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1205 fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1207 -> ty::PolyFnSig<'tcx> {
1208 use rustc::hir::map::*;
1211 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1213 let icx = ItemCtxt::new(tcx, def_id);
1215 match tcx.hir.get(node_id) {
1216 NodeTraitItem(&hir::TraitItem { node: TraitItemKind::Method(ref sig, _), .. }) |
1217 NodeImplItem(&hir::ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) => {
1218 AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl)
1221 NodeItem(&hir::Item { node: ItemFn(ref decl, unsafety, _, abi, _, _), .. }) => {
1222 AstConv::ty_of_fn(&icx, unsafety, abi, decl)
1225 NodeForeignItem(&hir::ForeignItem { node: ForeignItemFn(ref fn_decl, _, _), .. }) => {
1226 let abi = tcx.hir.get_foreign_abi(node_id);
1227 compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1230 NodeStructCtor(&VariantData::Tuple(ref fields, _)) |
1231 NodeVariant(&Spanned { node: hir::Variant_ {
1232 data: VariantData::Tuple(ref fields, _), ..
1234 let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
1235 let inputs = fields.iter().map(|f| {
1236 tcx.type_of(tcx.hir.local_def_id(f.id))
1238 ty::Binder(tcx.mk_fn_sig(
1242 hir::Unsafety::Normal,
1247 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), hir_id, .. }) => {
1248 tcx.typeck_tables_of(def_id).closure_tys()[hir_id]
1252 bug!("unexpected sort of node in fn_sig(): {:?}", x);
1257 fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1259 -> Option<ty::TraitRef<'tcx>> {
1260 let icx = ItemCtxt::new(tcx, def_id);
1262 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1263 match tcx.hir.expect_item(node_id).node {
1264 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
1265 Some(AstConv::instantiate_mono_trait_ref(&icx,
1267 tcx.mk_self_type()))
1269 hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
1270 opt_trait_ref.as_ref().map(|ast_trait_ref| {
1271 let selfty = tcx.type_of(def_id);
1272 AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1279 fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1281 -> hir::ImplPolarity {
1282 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1283 match tcx.hir.expect_item(node_id).node {
1284 hir::ItemImpl(_, polarity, ..) => polarity,
1285 ref item => bug!("impl_polarity: {:?} not an impl", item)
1289 // Is it marked with ?Sized
1290 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1291 ast_bounds: &[hir::TyParamBound],
1294 let tcx = astconv.tcx();
1296 // Try to find an unbound in bounds.
1297 let mut unbound = None;
1298 for ab in ast_bounds {
1299 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1300 if unbound.is_none() {
1301 unbound = Some(ptr.trait_ref.clone());
1303 span_err!(tcx.sess, span, E0203,
1304 "type parameter has more than one relaxed default \
1305 bound, only one is supported");
1310 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1313 // FIXME(#8559) currently requires the unbound to be built-in.
1314 if let Ok(kind_id) = kind_id {
1315 if tpb.path.def != Def::Trait(kind_id) {
1316 tcx.sess.span_warn(span,
1317 "default bound relaxed for a type parameter, but \
1318 this does nothing because the given bound is not \
1319 a default. Only `?Sized` is supported");
1323 _ if kind_id.is_ok() => {
1326 // No lang item for Sized, so we can't add it as a bound.
1333 /// Returns the early-bound lifetimes declared in this generics
1334 /// listing. For anything other than fns/methods, this is just all
1335 /// the lifetimes that are declared. For fns or methods, we have to
1336 /// screen out those that do not appear in any where-clauses etc using
1337 /// `resolve_lifetime::early_bound_lifetimes`.
1338 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1339 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1340 ast_generics: &'a hir::Generics)
1341 -> impl Iterator<Item=&'a hir::LifetimeDef>
1346 .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
1349 fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1351 -> ty::GenericPredicates<'tcx> {
1352 use rustc::hir::map::*;
1355 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1356 let node = tcx.hir.get(node_id);
1358 let mut is_trait = None;
1360 let icx = ItemCtxt::new(tcx, def_id);
1361 let no_generics = hir::Generics::empty();
1362 let ast_generics = match node {
1363 NodeTraitItem(item) => {
1365 TraitItemKind::Method(ref sig, _) => &sig.generics,
1370 NodeImplItem(item) => {
1372 ImplItemKind::Method(ref sig, _) => &sig.generics,
1379 ItemFn(.., ref generics, _) |
1380 ItemImpl(_, _, _, ref generics, ..) |
1381 ItemTy(_, ref generics) |
1382 ItemEnum(_, ref generics) |
1383 ItemStruct(_, ref generics) |
1384 ItemUnion(_, ref generics) => {
1388 ItemTrait(_, ref generics, .., ref items) => {
1389 is_trait = Some((ty::TraitRef {
1391 substs: Substs::identity_for_item(tcx, def_id)
1400 NodeForeignItem(item) => {
1402 ForeignItemStatic(..) => &no_generics,
1403 ForeignItemFn(_, _, ref generics) => generics
1407 NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1408 let substs = Substs::identity_for_item(tcx, def_id);
1409 let anon_ty = tcx.mk_anon(def_id, substs);
1411 // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
1412 let bounds = compute_bounds(&icx, anon_ty, bounds,
1413 SizedByDefault::Yes,
1415 return ty::GenericPredicates {
1417 predicates: bounds.predicates(tcx, anon_ty)
1424 let generics = tcx.generics_of(def_id);
1425 let parent_count = generics.parent_count() as u32;
1426 let has_own_self = generics.has_self && parent_count == 0;
1428 let mut predicates = vec![];
1430 // Below we'll consider the bounds on the type parameters (including `Self`)
1431 // and the explicit where-clauses, but to get the full set of predicates
1432 // on a trait we need to add in the supertrait bounds and bounds found on
1433 // associated types.
1434 if let Some((trait_ref, _)) = is_trait {
1435 predicates = tcx.super_predicates_of(def_id).predicates;
1437 // Add in a predicate that `Self:Trait` (where `Trait` is the
1438 // current trait). This is needed for builtin bounds.
1439 predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
1442 // Collect the region predicates that were declared inline as
1443 // well. In the case of parameters declared on a fn or method, we
1444 // have to be careful to only iterate over early-bound regions.
1445 let mut index = parent_count + has_own_self as u32;
1446 for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
1447 let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1448 def_id: tcx.hir.local_def_id(param.lifetime.id),
1450 name: param.lifetime.name
1454 for bound in ¶m.bounds {
1455 let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
1456 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1457 predicates.push(outlives.to_predicate());
1461 // Collect the predicates that were written inline by the user on each
1462 // type parameter (e.g., `<T:Foo>`).
1463 for param in &ast_generics.ty_params {
1464 let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
1467 let bounds = compute_bounds(&icx,
1470 SizedByDefault::Yes,
1472 predicates.extend(bounds.predicates(tcx, param_ty));
1475 // Add in the bounds that appear in the where-clause
1476 let where_clause = &ast_generics.where_clause;
1477 for predicate in &where_clause.predicates {
1479 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1480 let ty = icx.to_ty(&bound_pred.bounded_ty);
1482 for bound in bound_pred.bounds.iter() {
1484 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1485 let mut projections = Vec::new();
1488 AstConv::instantiate_poly_trait_ref(&icx,
1493 predicates.push(trait_ref.to_predicate());
1495 for projection in &projections {
1496 predicates.push(projection.to_predicate());
1500 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1501 let region = AstConv::ast_region_to_region(&icx,
1504 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1505 predicates.push(ty::Predicate::TypeOutlives(pred))
1511 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1512 let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
1513 for bound in ®ion_pred.bounds {
1514 let r2 = AstConv::ast_region_to_region(&icx, bound, None);
1515 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1516 predicates.push(ty::Predicate::RegionOutlives(pred))
1520 &hir::WherePredicate::EqPredicate(..) => {
1526 // Add predicates from associated type bounds.
1527 if let Some((self_trait_ref, trait_items)) = is_trait {
1528 predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
1529 let trait_item = tcx.hir.trait_item(trait_item_ref.id);
1530 let bounds = match trait_item.node {
1531 hir::TraitItemKind::Type(ref bounds, _) => bounds,
1533 return vec![].into_iter();
1537 let assoc_ty = tcx.mk_projection(
1538 tcx.hir.local_def_id(trait_item.id),
1539 self_trait_ref.substs,
1542 let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id),
1545 SizedByDefault::Yes,
1548 bounds.predicates(tcx, assoc_ty).into_iter()
1552 // Subtle: before we store the predicates into the tcx, we
1553 // sort them so that predicates like `T: Foo<Item=U>` come
1554 // before uses of `U`. This avoids false ambiguity errors
1555 // in trait checking. See `setup_constraining_predicates`
1557 if let NodeItem(&Item { node: ItemImpl(..), .. }) = node {
1558 let self_ty = tcx.type_of(def_id);
1559 let trait_ref = tcx.impl_trait_ref(def_id);
1560 ctp::setup_constraining_predicates(tcx,
1563 &mut ctp::parameters_for_impl(self_ty, trait_ref));
1566 ty::GenericPredicates {
1567 parent: generics.parent,
1572 pub enum SizedByDefault { Yes, No, }
1574 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1575 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1576 /// built-in trait (formerly known as kind): Send.
1577 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1578 param_ty: ty::Ty<'tcx>,
1579 ast_bounds: &[hir::TyParamBound],
1580 sized_by_default: SizedByDefault,
1584 let mut region_bounds = vec![];
1585 let mut trait_bounds = vec![];
1586 for ast_bound in ast_bounds {
1588 hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
1589 trait_bounds.push(b);
1591 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
1592 hir::RegionTyParamBound(ref l) => {
1593 region_bounds.push(l);
1598 let mut projection_bounds = vec![];
1600 let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1601 astconv.instantiate_poly_trait_ref(bound,
1603 &mut projection_bounds)
1606 let region_bounds = region_bounds.into_iter().map(|r| {
1607 astconv.ast_region_to_region(r, None)
1610 trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1612 let implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
1613 !is_unsized(astconv, ast_bounds, span)
1626 /// Converts a specific TyParamBound from the AST into a set of
1627 /// predicates that apply to the self-type. A vector is returned
1628 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1629 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1630 /// and `<T as Bar>::X == i32`).
1631 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1633 bound: &hir::TyParamBound)
1634 -> Vec<ty::Predicate<'tcx>>
1637 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1638 let mut projections = Vec::new();
1639 let pred = astconv.instantiate_poly_trait_ref(tr,
1642 projections.into_iter()
1643 .map(|p| p.to_predicate())
1644 .chain(Some(pred.to_predicate()))
1647 hir::RegionTyParamBound(ref lifetime) => {
1648 let region = astconv.ast_region_to_region(lifetime, None);
1649 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1650 vec![ty::Predicate::TypeOutlives(pred)]
1652 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1658 fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
1659 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1663 -> ty::PolyFnSig<'tcx>
1665 let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
1667 // feature gate SIMD types in FFI, since I (huonw) am not sure the
1668 // ABIs are handled at all correctly.
1669 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
1670 && !tcx.sess.features.borrow().simd_ffi {
1671 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
1673 tcx.sess.struct_span_err(ast_ty.span,
1674 &format!("use of SIMD type `{}` in FFI is highly experimental and \
1675 may result in invalid code",
1676 tcx.hir.node_to_pretty_string(ast_ty.id)))
1677 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
1681 for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
1684 if let hir::Return(ref ty) = decl.output {
1685 check(&ty, *fty.output().skip_binder())
1692 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1695 match tcx.hir.get_if_local(def_id) {
1696 Some(hir_map::NodeForeignItem(..)) => true,
1698 _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
1702 fn is_default_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1705 match tcx.hir.get_if_local(def_id) {
1706 Some(hir_map::NodeItem(&hir::Item { node: hir::ItemDefaultImpl(..), .. }))
1709 _ => bug!("is_default_impl applied to non-local def-id {:?}", def_id)