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.tcache`
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 an instance of `ty::TypeScheme`. This combines the
26 core type along with a list of the bounds for each parameter. Type
27 parameters themselves are represented as `ty_param()` instances.
29 The phasing of type conversion is somewhat complicated. There is no
30 clear set of phases we can enforce (e.g., converting traits first,
31 then types, or something like that) because the user can introduce
32 arbitrary interdependencies. So instead we generally convert things
33 lazilly and on demand, and include logic that checks for cycles.
34 Demand is driven by calls to `AstConv::get_item_type_scheme` or
35 `AstConv::lookup_trait_def`.
37 Currently, we "convert" types and traits in three phases (note that
38 conversion only affects the types of items / enum variants / methods;
39 it does not e.g. compute the types of individual expressions):
45 Conversion itself is done by simply walking each of the items in turn
46 and invoking an appropriate function (e.g., `trait_def_of_item` or
47 `convert_item`). However, it is possible that while converting an
48 item, we may need to compute the *type scheme* or *trait definition*
51 There are some shortcomings in this design:
53 - Before walking the set of supertraits for a given trait, you must
54 call `ensure_super_predicates` on that trait def-id. Otherwise,
55 `lookup_super_predicates` will result in ICEs.
56 - Because the type scheme includes defaults, cycles through type
57 parameter defaults are illegal even if those defaults are never
58 employed. This is not necessarily a bug.
59 - The phasing of trait definitions before type definitions does not
60 seem to be necessary, sufficient, or particularly helpful, given that
61 processing a trait definition can trigger processing a type def and
62 vice versa. However, if I remove it, I get ICEs, so some more work is
63 needed in that area. -nmatsakis
67 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
69 use middle::def_id::DefId;
70 use constrained_type_params as ctp;
71 use middle::lang_items::SizedTraitLangItem;
72 use middle::free_region::FreeRegionMap;
74 use middle::resolve_lifetime;
75 use middle::const_eval::{self, ConstVal};
76 use middle::const_eval::EvalHint::UncheckedExprHint;
77 use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
78 use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
79 use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme};
80 use middle::ty::{VariantKind};
81 use middle::ty::fold::{TypeFolder, TypeFoldable};
82 use middle::ty::util::IntTypeExt;
85 use rustc::front::map as hir_map;
86 use util::common::{ErrorReported, memoized};
87 use util::nodemap::{FnvHashMap, FnvHashSet};
90 use std::cell::{Cell, RefCell};
91 use std::collections::HashSet;
97 use syntax::codemap::Span;
98 use syntax::parse::token::special_idents;
100 use rustc_front::hir;
101 use rustc_front::visit;
102 use rustc_front::print::pprust;
104 ///////////////////////////////////////////////////////////////////////////
107 pub fn collect_item_types(tcx: &ty::ctxt) {
108 let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) };
110 let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
111 visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
113 let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
114 visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
117 ///////////////////////////////////////////////////////////////////////////
119 struct CrateCtxt<'a,'tcx:'a> {
120 tcx: &'a ty::ctxt<'tcx>,
122 // This stack is used to identify cycles in the user's source.
123 // Note that these cycles can cross multiple items.
124 stack: RefCell<Vec<AstConvRequest>>,
127 /// Context specific to some particular item. This is what implements
128 /// AstConv. It has information about the predicates that are defined
129 /// on the trait. Unfortunately, this predicate information is
130 /// available in various different forms at various points in the
131 /// process. So we can't just store a pointer to e.g. the AST or the
132 /// parsed ty form, we have to be more flexible. To this end, the
133 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
134 /// that it uses to satisfy `get_type_parameter_bounds` requests.
135 /// This object might draw the information from the AST
136 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
137 /// or both (a tuple).
138 struct ItemCtxt<'a,'tcx:'a> {
139 ccx: &'a CrateCtxt<'a,'tcx>,
140 param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
143 #[derive(Copy, Clone, PartialEq, Eq)]
144 enum AstConvRequest {
145 GetItemTypeScheme(DefId),
147 EnsureSuperPredicates(DefId),
148 GetTypeParameterBounds(ast::NodeId),
151 ///////////////////////////////////////////////////////////////////////////
152 // First phase: just collect *trait definitions* -- basically, the set
153 // of type parameters and supertraits. This is information we need to
154 // know later when parsing field defs.
156 struct CollectTraitDefVisitor<'a, 'tcx: 'a> {
157 ccx: &'a CrateCtxt<'a, 'tcx>
160 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> {
161 fn visit_item(&mut self, i: &hir::Item) {
163 hir::ItemTrait(..) => {
164 // computing the trait def also fills in the table
165 let _ = trait_def_of_item(self.ccx, i);
170 visit::walk_item(self, i);
174 ///////////////////////////////////////////////////////////////////////////
175 // Second phase: collection proper.
177 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
178 ccx: &'a CrateCtxt<'a, 'tcx>
181 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
182 fn visit_item(&mut self, i: &hir::Item) {
183 convert_item(self.ccx, i);
184 visit::walk_item(self, i);
186 fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
187 convert_foreign_item(self.ccx, i);
188 visit::walk_foreign_item(self, i);
192 ///////////////////////////////////////////////////////////////////////////
193 // Utility types and common code for the above passes.
195 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
196 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
197 ItemCtxt { ccx: self, param_bounds: param_bounds }
200 fn method_ty(&self, method_id: ast::NodeId) -> Rc<ty::Method<'tcx>> {
201 let def_id = self.tcx.map.local_def_id(method_id);
202 match *self.tcx.impl_or_trait_items.borrow().get(&def_id).unwrap() {
203 ty::MethodTraitItem(ref mty) => mty.clone(),
205 self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id));
210 fn cycle_check<F,R>(&self,
212 request: AstConvRequest,
214 -> Result<R,ErrorReported>
215 where F: FnOnce() -> Result<R,ErrorReported>
218 let mut stack = self.stack.borrow_mut();
219 match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
222 let cycle = &stack[i..];
223 self.report_cycle(span, cycle);
224 return Err(ErrorReported);
232 self.stack.borrow_mut().pop();
236 fn report_cycle(&self,
238 cycle: &[AstConvRequest])
240 assert!(!cycle.is_empty());
243 span_err!(tcx.sess, span, E0391,
244 "unsupported cyclic reference between types/traits detected");
247 AstConvRequest::GetItemTypeScheme(def_id) |
248 AstConvRequest::GetTraitDef(def_id) => {
250 &format!("the cycle begins when processing `{}`...",
251 tcx.item_path_str(def_id)));
253 AstConvRequest::EnsureSuperPredicates(def_id) => {
255 &format!("the cycle begins when computing the supertraits of `{}`...",
256 tcx.item_path_str(def_id)));
258 AstConvRequest::GetTypeParameterBounds(id) => {
259 let def = tcx.type_parameter_def(id);
261 &format!("the cycle begins when computing the bounds \
262 for type parameter `{}`...",
267 for request in &cycle[1..] {
269 AstConvRequest::GetItemTypeScheme(def_id) |
270 AstConvRequest::GetTraitDef(def_id) => {
272 &format!("...which then requires processing `{}`...",
273 tcx.item_path_str(def_id)));
275 AstConvRequest::EnsureSuperPredicates(def_id) => {
277 &format!("...which then requires computing the supertraits of `{}`...",
278 tcx.item_path_str(def_id)));
280 AstConvRequest::GetTypeParameterBounds(id) => {
281 let def = tcx.type_parameter_def(id);
283 &format!("...which then requires computing the bounds \
284 for type parameter `{}`...",
291 AstConvRequest::GetItemTypeScheme(def_id) |
292 AstConvRequest::GetTraitDef(def_id) => {
294 &format!("...which then again requires processing `{}`, completing the cycle.",
295 tcx.item_path_str(def_id)));
297 AstConvRequest::EnsureSuperPredicates(def_id) => {
299 &format!("...which then again requires computing the supertraits of `{}`, \
300 completing the cycle.",
301 tcx.item_path_str(def_id)));
303 AstConvRequest::GetTypeParameterBounds(id) => {
304 let def = tcx.type_parameter_def(id);
306 &format!("...which then again requires computing the bounds \
307 for type parameter `{}`, completing the cycle.",
313 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
314 fn get_trait_def(&self, trait_id: DefId)
315 -> &'tcx ty::TraitDef<'tcx>
319 if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
320 let item = match tcx.map.get(trait_id) {
321 hir_map::NodeItem(item) => item,
322 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
325 trait_def_of_item(self, &*item)
327 tcx.lookup_trait_def(trait_id)
331 /// Ensure that the (transitive) super predicates for
332 /// `trait_def_id` are available. This will report a cycle error
333 /// if a trait `X` (transitively) extends itself in some form.
334 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
335 -> Result<(), ErrorReported>
337 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
338 let def_ids = ensure_super_predicates_step(self, trait_def_id);
340 for def_id in def_ids {
341 try!(self.ensure_super_predicates(span, def_id));
349 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
350 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
351 ast_ty_to_ty(self, rs, ast_ty)
355 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
356 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
358 fn get_item_type_scheme(&self, span: Span, id: DefId)
359 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
361 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
362 Ok(type_scheme_of_def_id(self.ccx, id))
366 fn get_trait_def(&self, span: Span, id: DefId)
367 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
369 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
370 Ok(self.ccx.get_trait_def(id))
374 fn ensure_super_predicates(&self,
377 -> Result<(), ErrorReported>
379 debug!("ensure_super_predicates(trait_def_id={:?})",
382 self.ccx.ensure_super_predicates(span, trait_def_id)
386 fn get_type_parameter_bounds(&self,
388 node_id: ast::NodeId)
389 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
391 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
392 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
394 .filter_map(|p| p.to_opt_poly_trait_ref())
400 fn trait_defines_associated_type_named(&self,
402 assoc_name: ast::Name)
405 if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
406 trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
408 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
409 trait_def.associated_type_names.contains(&assoc_name)
414 _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
415 _substs: Option<&mut Substs<'tcx>>,
416 _space: Option<ParamSpace>,
417 span: Span) -> Ty<'tcx> {
418 span_err!(self.tcx().sess, span, E0121,
419 "the type placeholder `_` is not allowed within types on item signatures");
423 fn projected_ty(&self,
425 trait_ref: ty::TraitRef<'tcx>,
426 item_name: ast::Name)
429 self.tcx().mk_projection(trait_ref, item_name)
433 /// Interface used to find the bounds on a type parameter from within
434 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
435 trait GetTypeParameterBounds<'tcx> {
436 fn get_type_parameter_bounds(&self,
437 astconv: &AstConv<'tcx>,
439 node_id: ast::NodeId)
440 -> Vec<ty::Predicate<'tcx>>;
443 /// Find bounds from both elements of the tuple.
444 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
445 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
447 fn get_type_parameter_bounds(&self,
448 astconv: &AstConv<'tcx>,
450 node_id: ast::NodeId)
451 -> Vec<ty::Predicate<'tcx>>
453 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
454 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
459 /// Empty set of bounds.
460 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
461 fn get_type_parameter_bounds(&self,
462 _astconv: &AstConv<'tcx>,
464 _node_id: ast::NodeId)
465 -> Vec<ty::Predicate<'tcx>>
471 /// Find bounds from the parsed and converted predicates. This is
472 /// used when converting methods, because by that time the predicates
473 /// from the trait/impl have been fully converted.
474 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
475 fn get_type_parameter_bounds(&self,
476 astconv: &AstConv<'tcx>,
478 node_id: ast::NodeId)
479 -> Vec<ty::Predicate<'tcx>>
481 let def = astconv.tcx().type_parameter_def(node_id);
485 .filter(|predicate| {
487 ty::Predicate::Trait(ref data) => {
488 data.skip_binder().self_ty().is_param(def.space, def.index)
490 ty::Predicate::TypeOutlives(ref data) => {
491 data.skip_binder().0.is_param(def.space, def.index)
493 ty::Predicate::Equate(..) |
494 ty::Predicate::RegionOutlives(..) |
495 ty::Predicate::WellFormed(..) |
496 ty::Predicate::ObjectSafe(..) |
497 ty::Predicate::Projection(..) => {
507 /// Find bounds from hir::Generics. This requires scanning through the
508 /// AST. We do this to avoid having to convert *all* the bounds, which
509 /// would create artificial cycles. Instead we can only convert the
510 /// bounds for a type parameter `X` if `X::Foo` is used.
511 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
512 fn get_type_parameter_bounds(&self,
513 astconv: &AstConv<'tcx>,
515 node_id: ast::NodeId)
516 -> Vec<ty::Predicate<'tcx>>
518 // In the AST, bounds can derive from two places. Either
519 // written inline like `<T:Foo>` or in a where clause like
522 let def = astconv.tcx().type_parameter_def(node_id);
523 let ty = astconv.tcx().mk_param_from_def(&def);
528 .filter(|p| p.id == node_id)
529 .flat_map(|p| p.bounds.iter())
530 .flat_map(|b| predicates_from_bound(astconv, ty, b));
532 let from_where_clauses =
536 .filter_map(|wp| match *wp {
537 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
540 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
541 .flat_map(|bp| bp.bounds.iter())
542 .flat_map(|b| predicates_from_bound(astconv, ty, b));
544 from_ty_params.chain(from_where_clauses).collect()
548 /// Tests whether this is the AST for a reference to the type
549 /// parameter with id `param_id`. We use this so as to avoid running
550 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
551 /// conversion of the type to avoid inducing unnecessary cycles.
552 fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
554 param_id: ast::NodeId)
557 if let hir::TyPath(None, _) = ast_ty.node {
558 let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
559 match path_res.base_def {
560 def::DefSelfTy(Some(def_id), None) => {
561 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
563 def::DefTyParam(_, _, def_id, _) => {
564 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
576 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
577 container: ImplOrTraitItemContainer,
578 sig: &hir::MethodSig,
581 vis: hir::Visibility,
582 untransformed_rcvr_ty: Ty<'tcx>,
583 rcvr_ty_generics: &ty::Generics<'tcx>,
584 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
585 let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
587 let ty_generic_predicates =
588 ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
590 let (fty, explicit_self_category) =
591 astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
592 sig, untransformed_rcvr_ty);
594 let def_id = ccx.tcx.map.local_def_id(id);
595 let ty_method = ty::Method::new(name,
597 ty_generic_predicates,
599 explicit_self_category,
604 let fty = ccx.tcx.mk_fn(Some(def_id),
605 ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
606 debug!("method {} (id {}) has type {:?}",
608 ccx.tcx.register_item_type(def_id, TypeScheme {
609 generics: ty_method.generics.clone(),
612 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
614 write_ty_to_tcx(ccx.tcx, id, fty);
616 debug!("writing method type: def_id={:?} mty={:?}",
619 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
620 ty::MethodTraitItem(Rc::new(ty_method)));
623 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
624 struct_generics: &ty::Generics<'tcx>,
625 struct_predicates: &ty::GenericPredicates<'tcx>,
626 v: &hir::StructField,
627 ty_f: ty::FieldDefMaster<'tcx>)
629 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
631 write_ty_to_tcx(ccx.tcx, v.node.id, tt);
633 /* add the field to the tcache */
634 ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(v.node.id),
636 generics: struct_generics.clone(),
639 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(v.node.id),
640 struct_predicates.clone());
643 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
644 container: ImplOrTraitItemContainer,
647 vis: hir::Visibility,
651 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
652 ty::GenericPredicates::empty());
654 write_ty_to_tcx(ccx.tcx, id, ty);
656 let associated_const = Rc::new(ty::AssociatedConst {
659 def_id: ccx.tcx.map.local_def_id(id),
660 container: container,
664 ccx.tcx.impl_or_trait_items.borrow_mut()
665 .insert(ccx.tcx.map.local_def_id(id), ty::ConstTraitItem(associated_const));
668 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
669 container: ImplOrTraitItemContainer,
672 vis: hir::Visibility,
673 ty: Option<Ty<'tcx>>)
675 let associated_type = Rc::new(ty::AssociatedType {
679 def_id: ccx.tcx.map.local_def_id(id),
682 ccx.tcx.impl_or_trait_items.borrow_mut()
683 .insert(ccx.tcx.map.local_def_id(id), ty::TypeTraitItem(associated_type));
686 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
687 container: ImplOrTraitItemContainer,
689 untransformed_rcvr_ty: Ty<'tcx>,
690 rcvr_ty_generics: &ty::Generics<'tcx>,
691 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
692 where I: Iterator<Item=(&'i hir::MethodSig, ast::NodeId, ast::Name, hir::Visibility, Span)>
694 debug!("convert_methods(untransformed_rcvr_ty={:?}, rcvr_ty_generics={:?}, \
695 rcvr_ty_predicates={:?})",
696 untransformed_rcvr_ty,
700 for (sig, id, name, vis, _span) in methods {
707 untransformed_rcvr_ty,
713 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
715 generics: &hir::Generics,
716 thing: &'static str) {
717 let mut warn = false;
719 for ty_param in generics.ty_params.iter() {
720 for bound in ty_param.bounds.iter() {
722 hir::TraitTyParamBound(..) => {
725 hir::RegionTyParamBound(..) => { }
731 // According to accepted RFC #XXX, we should
732 // eventually accept these, but it will not be
733 // part of this PR. Still, convert to warning to
734 // make bootstrapping easier.
735 span_warn!(ccx.tcx.sess, span, E0122,
736 "trait bounds are not (yet) enforced \
742 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
744 debug!("convert: item {} with id {}", it.name, it.id);
746 // These don't define types.
747 hir::ItemExternCrate(_) | hir::ItemUse(_) |
748 hir::ItemForeignMod(_) | hir::ItemMod(_) => {
750 hir::ItemEnum(ref enum_definition, _) => {
751 let (scheme, predicates) = convert_typed_item(ccx, it);
752 write_ty_to_tcx(tcx, it.id, scheme.ty);
753 convert_enum_variant_types(ccx,
754 tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
757 &enum_definition.variants);
759 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
761 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
766 tcx.record_trait_has_default_impl(trait_ref.def_id);
768 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
776 // Create generics from the generics specified in the impl head.
777 debug!("convert: ast_generics={:?}", generics);
778 let def_id = ccx.tcx.map.local_def_id(it.id);
779 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
780 let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
782 debug!("convert: impl_bounds={:?}", ty_predicates);
784 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
785 write_ty_to_tcx(tcx, it.id, selfty);
787 tcx.register_item_type(def_id,
788 TypeScheme { generics: ty_generics.clone(),
790 if let &Some(ref ast_trait_ref) = opt_trait_ref {
791 tcx.impl_trait_refs.borrow_mut().insert(
793 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
799 tcx.impl_trait_refs.borrow_mut().insert(def_id, None);
802 enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id);
803 tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
806 // If there is a trait reference, treat the methods as always public.
807 // This is to work around some incorrect behavior in privacy checking:
808 // when the method belongs to a trait, it should acquire the privacy
809 // from the trait, not the impl. Forcing the visibility to be public
810 // makes things sorta work.
811 let parent_visibility = if opt_trait_ref.is_some() {
817 // Convert all the associated consts.
818 // Also, check if there are any duplicate associated items
819 let mut seen_type_items = FnvHashSet();
820 let mut seen_value_items = FnvHashSet();
822 for impl_item in impl_items {
823 let seen_items = match impl_item.node {
824 hir::TypeImplItem(_) => &mut seen_type_items,
825 _ => &mut seen_value_items,
827 if !seen_items.insert(impl_item.name) {
828 let desc = match impl_item.node {
829 hir::ConstImplItem(_, _) => "associated constant",
830 hir::TypeImplItem(_) => "associated type",
831 hir::MethodImplItem(ref sig, _) =>
832 match sig.explicit_self.node {
833 hir::SelfStatic => "associated function",
838 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
841 if let hir::ConstImplItem(ref ty, _) = impl_item.node {
842 let ty = ccx.icx(&ty_predicates)
843 .to_ty(&ExplicitRscope, &*ty);
844 tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
846 generics: ty_generics.clone(),
849 convert_associated_const(ccx, ImplContainer(def_id),
850 impl_item.name, impl_item.id,
851 impl_item.vis.inherit_from(parent_visibility),
852 ty, true /* has_value */);
856 // Convert all the associated types.
857 for impl_item in impl_items {
858 if let hir::TypeImplItem(ref ty) = impl_item.node {
859 if opt_trait_ref.is_none() {
860 span_err!(tcx.sess, impl_item.span, E0202,
861 "associated types are not allowed in inherent impls");
864 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
866 convert_associated_type(ccx, ImplContainer(def_id),
867 impl_item.name, impl_item.id, impl_item.vis,
872 let methods = impl_items.iter().filter_map(|ii| {
873 if let hir::MethodImplItem(ref sig, _) = ii.node {
874 // if the method specifies a visibility, use that, otherwise
875 // inherit the visibility from the impl (so `foo` in `pub impl
876 // { fn foo(); }` is public, but private in `impl { fn
878 let method_vis = ii.vis.inherit_from(parent_visibility);
879 Some((sig, ii.id, ii.name, method_vis, ii.span))
885 ImplContainer(def_id),
891 for impl_item in impl_items {
892 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
893 let body_id = body.id;
894 check_method_self_type(ccx,
895 &BindingRscope::new(),
896 ccx.method_ty(impl_item.id),
903 enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
905 hir::ItemTrait(_, _, _, ref trait_items) => {
906 let trait_def = trait_def_of_item(ccx, it);
907 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
908 ccx.ensure_super_predicates(it.span, ccx.tcx.map.local_def_id(it.id));
909 convert_trait_predicates(ccx, it);
910 let trait_predicates = tcx.lookup_predicates(ccx.tcx.map.local_def_id(it.id));
912 debug!("convert: trait_bounds={:?}", trait_predicates);
914 // Convert all the associated types.
915 for trait_item in trait_items {
916 match trait_item.node {
917 hir::ConstTraitItem(ref ty, ref default) => {
918 let ty = ccx.icx(&trait_predicates)
919 .to_ty(&ExplicitRscope, ty);
920 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
922 generics: trait_def.generics.clone(),
925 convert_associated_const(ccx,
926 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
937 // Convert all the associated types.
938 for trait_item in trait_items {
939 match trait_item.node {
940 hir::TypeTraitItem(_, ref opt_ty) => {
941 let typ = opt_ty.as_ref().map({
942 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
945 convert_associated_type(ccx,
946 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
956 let methods = trait_items.iter().filter_map(|ti| {
957 let sig = match ti.node {
958 hir::MethodTraitItem(ref sig, _) => sig,
961 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
964 // Run convert_methods on the trait methods.
966 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
972 // Add an entry mapping
973 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
974 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
975 match trait_item.node {
976 hir::ConstTraitItem(..) => {
977 ty::ConstTraitItemId(def_id)
979 hir::MethodTraitItem(..) => {
980 ty::MethodTraitItemId(def_id)
982 hir::TypeTraitItem(..) => {
983 ty::TypeTraitItemId(def_id)
987 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
990 // This must be done after `collect_trait_methods` so that
991 // we have a method type stored for every method.
992 for trait_item in trait_items {
993 let sig = match trait_item.node {
994 hir::MethodTraitItem(ref sig, _) => sig,
997 check_method_self_type(ccx,
998 &BindingRscope::new(),
999 ccx.method_ty(trait_item.id),
1005 hir::ItemStruct(ref struct_def, _) => {
1006 let (scheme, predicates) = convert_typed_item(ccx, it);
1007 write_ty_to_tcx(tcx, it.id, scheme.ty);
1009 let it_def_id = ccx.tcx.map.local_def_id(it.id);
1010 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
1012 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
1013 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1016 if !struct_def.is_struct() {
1017 convert_variant_ctor(tcx, struct_def.id(), variant, scheme, predicates);
1020 hir::ItemTy(_, ref generics) => {
1021 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1022 let (scheme, _) = convert_typed_item(ccx, it);
1023 write_ty_to_tcx(tcx, it.id, scheme.ty);
1026 // This call populates the type cache with the converted type
1027 // of the item in passing. All we have to do here is to write
1028 // it into the node type table.
1029 let (scheme, _) = convert_typed_item(ccx, it);
1030 write_ty_to_tcx(tcx, it.id, scheme.ty);
1035 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1036 ctor_id: ast::NodeId,
1037 variant: ty::VariantDef<'tcx>,
1038 scheme: ty::TypeScheme<'tcx>,
1039 predicates: ty::GenericPredicates<'tcx>) {
1040 let ctor_ty = match variant.kind() {
1041 VariantKind::Unit | VariantKind::Struct => scheme.ty,
1042 VariantKind::Tuple => {
1043 let inputs: Vec<_> =
1046 .map(|field| field.unsubst_ty())
1048 tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
1053 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1054 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
1055 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
1057 generics: scheme.generics,
1062 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1063 def: ty::AdtDefMaster<'tcx>,
1064 scheme: ty::TypeScheme<'tcx>,
1065 predicates: ty::GenericPredicates<'tcx>,
1066 variants: &[P<hir::Variant>]) {
1067 // fill the field types
1068 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1069 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
1070 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1073 // Convert the ctor, if any. This also registers the variant as
1075 convert_variant_ctor(
1077 variant.node.data.id(),
1085 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1089 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
1090 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1091 let fields = def.fields().iter().map(|f| {
1092 let fid = tcx.map.local_def_id(f.node.id);
1094 hir::NamedField(name, vis) => {
1095 let dup_span = seen_fields.get(&name).cloned();
1096 if let Some(prev_span) = dup_span {
1097 span_err!(tcx.sess, f.span, E0124,
1098 "field `{}` is already declared",
1100 span_note!(tcx.sess, prev_span, "previously declared here");
1102 seen_fields.insert(name, f.span);
1105 ty::FieldDefData::new(fid, name, vis)
1107 hir::UnnamedField(vis) => {
1108 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1112 ty::VariantDefData {
1120 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1122 def: &hir::VariantData)
1123 -> ty::AdtDefMaster<'tcx>
1126 let did = tcx.map.local_def_id(it.id);
1127 let ctor_id = if !def.is_struct() {
1128 tcx.map.local_def_id(def.id())
1134 ty::AdtKind::Struct,
1135 vec![convert_struct_variant(tcx, ctor_id, it.name, 0, def)]
1139 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1142 -> ty::AdtDefMaster<'tcx>
1144 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1146 e: &hir::Expr) -> Option<ty::Disr> {
1147 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1149 let hint = UncheckedExprHint(repr_ty);
1150 match const_eval::eval_const_expr_partial(tcx, e, hint, None) {
1151 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1152 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1154 let sign_desc = if repr_ty.is_signed() {
1159 span_err!(tcx.sess, e.span, E0079,
1160 "expected {} integer constant",
1165 span_err!(tcx.sess, err.span, E0080,
1166 "constant evaluation error: {}",
1168 if !e.span.contains(err.span) {
1169 tcx.sess.span_note(e.span, "for enum discriminant here");
1176 fn report_discrim_overflow(tcx: &ty::ctxt,
1179 repr_type: attr::IntType,
1180 prev_val: ty::Disr) {
1181 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1182 let computed_value = repr_type.disr_string(computed_value);
1183 let prev_val = repr_type.disr_string(prev_val);
1184 let repr_type = repr_type.to_ty(tcx);
1185 span_err!(tcx.sess, variant_span, E0370,
1186 "enum discriminant overflowed on value after {}: {}; \
1187 set explicitly via {} = {} if that is desired outcome",
1188 prev_val, repr_type, variant_name, computed_value);
1191 fn next_disr(tcx: &ty::ctxt,
1193 repr_type: attr::IntType,
1194 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1195 if let Some(prev_disr_val) = prev_disr_val {
1196 let result = repr_type.disr_incr(prev_disr_val);
1197 if let None = result {
1198 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1199 repr_type, prev_disr_val);
1203 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1206 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1209 -> ty::VariantDefData<'tcx, 'tcx>
1211 let did = tcx.map.local_def_id(v.node.data.id());
1212 let name = v.node.name;
1213 convert_struct_variant(tcx, did, name, disr, &v.node.data)
1215 let did = tcx.map.local_def_id(it.id);
1216 let repr_hints = tcx.lookup_repr_hints(did);
1217 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1218 let mut prev_disr = None;
1219 let variants = def.variants.iter().map(|v| {
1220 let disr = match v.node.disr_expr {
1221 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1222 None => next_disr(tcx, v, repr_type, prev_disr)
1223 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1225 let v = convert_enum_variant(tcx, v, disr);
1226 prev_disr = Some(disr);
1229 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1232 /// Ensures that the super-predicates of the trait with def-id
1233 /// trait_def_id are converted and stored. This does NOT ensure that
1234 /// the transitive super-predicates are converted; that is the job of
1235 /// the `ensure_super_predicates()` method in the `AstConv` impl
1236 /// above. Returns a list of trait def-ids that must be ensured as
1237 /// well to guarantee that the transitive superpredicates are
1239 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1240 trait_def_id: DefId)
1245 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1247 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1250 // If this trait comes from an external crate, then all of the
1251 // supertraits it may depend on also must come from external
1252 // crates, and hence all of them already have their
1253 // super-predicates "converted" (and available from crate
1254 // meta-data), so there is no need to transitively test them.
1258 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1259 let superpredicates = superpredicates.unwrap_or_else(|| {
1260 let item = match ccx.tcx.map.get(trait_node_id) {
1261 hir_map::NodeItem(item) => item,
1262 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1265 let (generics, bounds) = match item.node {
1266 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1267 _ => tcx.sess.span_bug(item.span,
1268 "ensure_super_predicates_step invoked on non-trait"),
1271 // In-scope when converting the superbounds for `Trait` are
1272 // that `Self:Trait` as well as any bounds that appear on the
1274 let trait_def = trait_def_of_item(ccx, item);
1275 let self_predicate = ty::GenericPredicates {
1276 predicates: VecPerParamSpace::new(vec![],
1277 vec![trait_def.trait_ref.to_predicate()],
1280 let scope = &(generics, &self_predicate);
1282 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1283 let self_param_ty = tcx.mk_self_type();
1284 let superbounds1 = compute_bounds(&ccx.icx(scope),
1290 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1292 // Convert any explicit superbounds in the where clause,
1293 // e.g. `trait Foo where Self : Bar`:
1294 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1296 // Combine the two lists to form the complete set of superbounds:
1297 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1298 let superpredicates = ty::GenericPredicates {
1299 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1301 debug!("superpredicates for trait {:?} = {:?}",
1302 tcx.map.local_def_id(item.id),
1305 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1310 let def_ids: Vec<_> = superpredicates.predicates
1312 .filter_map(|p| p.to_opt_poly_trait_ref())
1313 .map(|tr| tr.def_id())
1316 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1321 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1323 -> &'tcx ty::TraitDef<'tcx>
1325 let def_id = ccx.tcx.map.local_def_id(it.id);
1328 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1332 let (unsafety, generics, items) = match it.node {
1333 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1334 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1337 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1338 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1339 ccx.tcx.sess.span_err(
1341 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1342 which traits can use parenthetical notation");
1343 fileline_help!(ccx.tcx.sess, it.span,
1344 "add `#![feature(unboxed_closures)]` to \
1345 the crate attributes to use it");
1348 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1350 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1352 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1353 match trait_item.node {
1354 hir::TypeTraitItem(..) => Some(trait_item.name),
1359 let trait_ref = ty::TraitRef {
1364 let trait_def = ty::TraitDef {
1365 paren_sugar: paren_sugar,
1367 generics: ty_generics,
1368 trait_ref: trait_ref,
1369 associated_type_names: associated_type_names,
1370 nonblanket_impls: RefCell::new(FnvHashMap()),
1371 blanket_impls: RefCell::new(vec![]),
1372 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1375 return tcx.intern_trait_def(trait_def);
1377 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1378 generics: &hir::Generics)
1383 // Creates a no-op substitution for the trait's type parameters.
1388 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1389 def_id: tcx.map.local_def_id(def.lifetime.id),
1392 name: def.lifetime.name
1396 // Start with the generics in the type parameters...
1401 .map(|(i, def)| tcx.mk_param(TypeSpace,
1402 i as u32, def.name))
1405 // ...and also create the `Self` parameter.
1406 let self_ty = tcx.mk_self_type();
1408 Substs::new_trait(types, regions, self_ty)
1412 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1413 trait_node_id: ast::NodeId,
1414 assoc_name: ast::Name)
1417 let item = match ccx.tcx.map.get(trait_node_id) {
1418 hir_map::NodeItem(item) => item,
1419 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1422 let trait_items = match item.node {
1423 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1424 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1427 trait_items.iter().any(|trait_item| {
1428 match trait_item.node {
1429 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1435 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1437 let trait_def = trait_def_of_item(ccx, it);
1439 let def_id = ccx.tcx.map.local_def_id(it.id);
1441 let (generics, items) = match it.node {
1442 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1446 &format!("trait_def_of_item invoked on {:?}", s));
1450 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1452 // `ty_generic_predicates` below will consider the bounds on the type
1453 // parameters (including `Self`) and the explicit where-clauses,
1454 // but to get the full set of predicates on a trait we need to add
1455 // in the supertrait bounds and anything declared on the
1456 // associated types.
1457 let mut base_predicates = super_predicates;
1459 // Add in a predicate that `Self:Trait` (where `Trait` is the
1460 // current trait). This is needed for builtin bounds.
1461 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1462 base_predicates.predicates.push(SelfSpace, self_predicate);
1464 // add in the explicit where-clauses
1465 let mut trait_predicates =
1466 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1468 let assoc_predicates = predicates_for_associated_types(ccx,
1471 trait_def.trait_ref,
1473 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1475 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1476 assert!(prev_predicates.is_none());
1480 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1481 ast_generics: &hir::Generics,
1482 trait_predicates: &ty::GenericPredicates<'tcx>,
1483 self_trait_ref: ty::TraitRef<'tcx>,
1484 trait_items: &[P<hir::TraitItem>])
1485 -> Vec<ty::Predicate<'tcx>>
1487 trait_items.iter().flat_map(|trait_item| {
1488 let bounds = match trait_item.node {
1489 hir::TypeTraitItem(ref bounds, _) => bounds,
1491 return vec!().into_iter();
1495 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1498 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1501 SizedByDefault::Yes,
1504 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1509 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1511 -> ty::TypeScheme<'tcx>
1513 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1514 match ccx.tcx.map.find(node_id) {
1515 Some(hir_map::NodeItem(item)) => {
1516 type_scheme_of_item(ccx, &*item)
1518 Some(hir_map::NodeForeignItem(foreign_item)) => {
1519 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1520 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1523 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1524 in get_item_type_scheme(): {:?}",
1529 ccx.tcx.lookup_item_type(def_id)
1533 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1535 -> ty::TypeScheme<'tcx>
1537 memoized(&ccx.tcx.tcache,
1538 ccx.tcx.map.local_def_id(it.id),
1539 |_| compute_type_scheme_of_item(ccx, it))
1542 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1544 -> ty::TypeScheme<'tcx>
1548 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1549 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1550 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1552 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1553 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1554 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1555 let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1556 ty::TypeScheme { ty: ty, generics: ty_generics }
1558 hir::ItemTy(ref t, ref generics) => {
1559 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1560 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1561 ty::TypeScheme { ty: ty, generics: ty_generics }
1563 hir::ItemEnum(ref ei, ref generics) => {
1564 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1565 let substs = mk_item_substs(ccx, &ty_generics);
1566 let def = convert_enum_def(tcx, it, ei);
1567 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1568 ty::TypeScheme { ty: t, generics: ty_generics }
1570 hir::ItemStruct(ref si, ref generics) => {
1571 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1572 let substs = mk_item_substs(ccx, &ty_generics);
1573 let def = convert_struct_def(tcx, it, si);
1574 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1575 ty::TypeScheme { ty: t, generics: ty_generics }
1577 hir::ItemDefaultImpl(..) |
1578 hir::ItemTrait(..) |
1581 hir::ItemForeignMod(..) |
1582 hir::ItemExternCrate(..) |
1583 hir::ItemUse(..) => {
1586 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1592 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1594 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1598 let tag = type_scheme_of_item(ccx, it);
1599 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1600 let predicates = match it.node {
1601 hir::ItemStatic(..) | hir::ItemConst(..) => {
1602 ty::GenericPredicates::empty()
1604 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1605 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1607 hir::ItemTy(_, ref generics) => {
1608 ty_generic_predicates_for_type_or_impl(ccx, generics)
1610 hir::ItemEnum(_, ref generics) => {
1611 ty_generic_predicates_for_type_or_impl(ccx, generics)
1613 hir::ItemStruct(_, ref generics) => {
1614 ty_generic_predicates_for_type_or_impl(ccx, generics)
1616 hir::ItemDefaultImpl(..) |
1617 hir::ItemTrait(..) |
1618 hir::ItemExternCrate(..) |
1622 hir::ItemForeignMod(..) => {
1625 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1630 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1631 predicates.clone());
1632 assert!(prev_predicates.is_none());
1635 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1636 let object_lifetime_default_reprs: String =
1637 scheme.generics.types.iter()
1638 .map(|t| match t.object_lifetime_default {
1639 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1640 d => format!("{:?}", d),
1642 .collect::<Vec<String>>()
1645 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1648 return (scheme, predicates);
1651 fn type_scheme_of_foreign_item<'a, 'tcx>(
1652 ccx: &CrateCtxt<'a, 'tcx>,
1653 it: &hir::ForeignItem,
1655 -> ty::TypeScheme<'tcx>
1657 memoized(&ccx.tcx.tcache,
1658 ccx.tcx.map.local_def_id(it.id),
1659 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1662 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1663 ccx: &CrateCtxt<'a, 'tcx>,
1664 it: &hir::ForeignItem,
1666 -> ty::TypeScheme<'tcx>
1669 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1670 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1672 hir::ForeignItemStatic(ref t, _) => {
1674 generics: ty::Generics::empty(),
1675 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1681 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1682 it: &hir::ForeignItem)
1684 // For reasons I cannot fully articulate, I do so hate the AST
1685 // map, and I regard each time that I use it as a personal and
1686 // moral failing, but at the moment it seems like the only
1687 // convenient way to extract the ABI. - ndm
1689 let abi = tcx.map.get_foreign_abi(it.id);
1691 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1692 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1694 let predicates = match it.node {
1695 hir::ForeignItemFn(_, ref generics) => {
1696 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1698 hir::ForeignItemStatic(..) => {
1699 ty::GenericPredicates::empty()
1703 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1705 assert!(prev_predicates.is_none());
1708 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1709 generics: &hir::Generics)
1710 -> ty::Generics<'tcx> {
1711 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1714 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1715 generics: &hir::Generics)
1716 -> ty::GenericPredicates<'tcx>
1718 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1721 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1722 trait_id: ast::NodeId,
1723 substs: &'tcx Substs<'tcx>,
1724 ast_generics: &hir::Generics)
1725 -> ty::Generics<'tcx>
1727 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1728 ccx.tcx.map.local_def_id(trait_id), substs);
1730 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1732 // Add in the self type parameter.
1734 // Something of a hack: use the node id for the trait, also as
1735 // the node id for the Self type parameter.
1736 let param_id = trait_id;
1738 let parent = ccx.tcx.map.get_parent(param_id);
1740 let def = ty::TypeParameterDef {
1743 name: special_idents::type_self.name,
1744 def_id: ccx.tcx.map.local_def_id(param_id),
1745 default_def_id: ccx.tcx.map.local_def_id(parent),
1747 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1750 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1752 generics.types.push(SelfSpace, def);
1757 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1758 generics: &hir::Generics,
1759 base_generics: &ty::Generics<'tcx>)
1760 -> ty::Generics<'tcx>
1762 ty_generics(ccx, FnSpace, generics, base_generics)
1765 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1766 generics: &hir::Generics,
1767 base_predicates: &ty::GenericPredicates<'tcx>)
1768 -> ty::GenericPredicates<'tcx>
1770 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1773 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1774 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1775 bounds: &mut ty::BuiltinBounds,
1776 ast_bounds: &[hir::TyParamBound],
1779 let tcx = astconv.tcx();
1781 // Try to find an unbound in bounds.
1782 let mut unbound = None;
1783 for ab in ast_bounds {
1784 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1785 if unbound.is_none() {
1786 assert!(ptr.bound_lifetimes.is_empty());
1787 unbound = Some(ptr.trait_ref.clone());
1789 span_err!(tcx.sess, span, E0203,
1790 "type parameter has more than one relaxed default \
1791 bound, only one is supported");
1796 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1799 // FIXME(#8559) currently requires the unbound to be built-in.
1800 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1802 Ok(kind_id) if trait_def_id != kind_id => {
1803 tcx.sess.span_warn(span,
1804 "default bound relaxed for a type parameter, but \
1805 this does nothing because the given bound is not \
1806 a default. Only `?Sized` is supported");
1807 tcx.try_add_builtin_trait(kind_id, bounds);
1812 _ if kind_id.is_ok() => {
1813 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1815 // No lang item for Sized, so we can't add it as a bound.
1820 /// Returns the early-bound lifetimes declared in this generics
1821 /// listing. For anything other than fns/methods, this is just all
1822 /// the lifetimes that are declared. For fns or methods, we have to
1823 /// screen out those that do not appear in any where-clauses etc using
1824 /// `resolve_lifetime::early_bound_lifetimes`.
1825 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1826 ast_generics: &hir::Generics)
1827 -> Vec<hir::LifetimeDef>
1830 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1831 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1835 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1837 ast_generics: &hir::Generics,
1838 base_predicates: &ty::GenericPredicates<'tcx>)
1839 -> ty::GenericPredicates<'tcx>
1842 let mut result = base_predicates.clone();
1844 // Collect the predicates that were written inline by the user on each
1845 // type parameter (e.g., `<T:Foo>`).
1846 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1847 let index = index as u32;
1848 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1849 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1852 SizedByDefault::Yes,
1854 let predicates = bounds.predicates(ccx.tcx, param_ty);
1855 result.predicates.extend(space, predicates.into_iter());
1858 // Collect the region predicates that were declared inline as
1859 // well. In the case of parameters declared on a fn or method, we
1860 // have to be careful to only iterate over early-bound regions.
1861 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1862 for (index, param) in early_lifetimes.iter().enumerate() {
1863 let index = index as u32;
1864 let def_id = tcx.map.local_def_id(param.lifetime.id);
1866 ty::ReEarlyBound(ty::EarlyBoundRegion {
1870 name: param.lifetime.name
1872 for bound in ¶m.bounds {
1873 let bound_region = ast_region_to_region(ccx.tcx, bound);
1874 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1875 result.predicates.push(space, outlives.to_predicate());
1879 // Add in the bounds that appear in the where-clause
1880 let where_clause = &ast_generics.where_clause;
1881 for predicate in &where_clause.predicates {
1883 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1884 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1886 &*bound_pred.bounded_ty);
1888 for bound in bound_pred.bounds.iter() {
1890 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1891 let mut projections = Vec::new();
1894 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1899 result.predicates.push(space, trait_ref.to_predicate());
1901 for projection in &projections {
1902 result.predicates.push(space, projection.to_predicate());
1906 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1907 let region = ast_region_to_region(tcx, lifetime);
1908 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1909 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1915 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1916 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1917 for bound in ®ion_pred.bounds {
1918 let r2 = ast_region_to_region(tcx, bound);
1919 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1920 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1924 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1926 tcx.sess.span_bug(eq_pred.span,
1927 "Equality constraints are not yet \
1928 implemented (#20041)")
1936 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1938 ast_generics: &hir::Generics,
1939 base_generics: &ty::Generics<'tcx>)
1940 -> ty::Generics<'tcx>
1943 let mut result = base_generics.clone();
1945 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1946 for (i, l) in early_lifetimes.iter().enumerate() {
1947 let bounds = l.bounds.iter()
1948 .map(|l| ast_region_to_region(tcx, l))
1950 let def = ty::RegionParameterDef { name: l.lifetime.name,
1953 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1955 result.regions.push(space, def);
1958 assert!(result.types.is_empty_in(space));
1960 // Now create the real type parameters.
1961 for i in 0..ast_generics.ty_params.len() {
1962 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1963 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1964 result.types.push(space, def);
1970 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1976 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1978 for leaf_ty in ty.walk() {
1979 if let ty::TyParam(p) = leaf_ty.sty {
1980 if p.space == space && p.idx >= index {
1981 span_err!(ccx.tcx.sess, path.span, E0128,
1982 "type parameters with a default cannot use \
1983 forward declared identifiers");
1985 return ccx.tcx.types.err
1993 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1994 ast_generics: &hir::Generics,
1997 -> ty::TypeParameterDef<'tcx>
1999 let param = &ast_generics.ty_params[index as usize];
2002 match tcx.ty_param_defs.borrow().get(¶m.id) {
2003 Some(d) => { return d.clone(); }
2007 let default = param.default.as_ref().map(
2008 |def| convert_default_type_parameter(ccx, def, space, index)
2011 let object_lifetime_default =
2012 compute_object_lifetime_default(ccx, param.id,
2013 ¶m.bounds, &ast_generics.where_clause);
2015 let parent = tcx.map.get_parent(param.id);
2017 let def = ty::TypeParameterDef {
2021 def_id: ccx.tcx.map.local_def_id(param.id),
2022 default_def_id: ccx.tcx.map.local_def_id(parent),
2024 object_lifetime_default: object_lifetime_default,
2027 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2032 /// Scan the bounds and where-clauses on a parameter to extract bounds
2033 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2034 /// This runs as part of computing the minimal type scheme, so we
2035 /// intentionally avoid just asking astconv to convert all the where
2036 /// clauses into a `ty::Predicate`. This is because that could induce
2037 /// artificial cycles.
2038 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2039 param_id: ast::NodeId,
2040 param_bounds: &[hir::TyParamBound],
2041 where_clause: &hir::WhereClause)
2042 -> ty::ObjectLifetimeDefault
2044 let inline_bounds = from_bounds(ccx, param_bounds);
2045 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2046 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2047 .chain(where_bounds)
2049 return if all_bounds.len() > 1 {
2050 ty::ObjectLifetimeDefault::Ambiguous
2051 } else if all_bounds.len() == 0 {
2052 ty::ObjectLifetimeDefault::BaseDefault
2054 ty::ObjectLifetimeDefault::Specific(
2055 all_bounds.into_iter().next().unwrap())
2058 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2059 bounds: &[hir::TyParamBound])
2063 .filter_map(|bound| {
2065 hir::TraitTyParamBound(..) =>
2067 hir::RegionTyParamBound(ref lifetime) =>
2068 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2074 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2075 param_id: ast::NodeId,
2076 predicates: &[hir::WherePredicate])
2080 .flat_map(|predicate| {
2082 hir::WherePredicate::BoundPredicate(ref data) => {
2083 if data.bound_lifetimes.is_empty() &&
2084 is_param(ccx.tcx, &data.bounded_ty, param_id)
2086 from_bounds(ccx, &data.bounds).into_iter()
2088 Vec::new().into_iter()
2091 hir::WherePredicate::RegionPredicate(..) |
2092 hir::WherePredicate::EqPredicate(..) => {
2093 Vec::new().into_iter()
2101 enum SizedByDefault { Yes, No, }
2103 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2104 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2105 /// built-in trait (formerly known as kind): Send.
2106 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2107 param_ty: ty::Ty<'tcx>,
2108 ast_bounds: &[hir::TyParamBound],
2109 sized_by_default: SizedByDefault,
2111 -> astconv::Bounds<'tcx>
2114 conv_param_bounds(astconv,
2119 if let SizedByDefault::Yes = sized_by_default {
2120 add_unsized_bound(astconv,
2121 &mut bounds.builtin_bounds,
2126 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2131 /// Converts a specific TyParamBound from the AST into a set of
2132 /// predicates that apply to the self-type. A vector is returned
2133 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2134 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2135 /// and `<T as Bar>::X == i32`).
2136 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2138 bound: &hir::TyParamBound)
2139 -> Vec<ty::Predicate<'tcx>>
2142 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2143 let mut projections = Vec::new();
2144 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2145 projections.into_iter()
2146 .map(|p| p.to_predicate())
2147 .chain(Some(pred.to_predicate()))
2150 hir::RegionTyParamBound(ref lifetime) => {
2151 let region = ast_region_to_region(astconv.tcx(), lifetime);
2152 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2153 vec![ty::Predicate::TypeOutlives(pred)]
2155 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2161 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2163 trait_ref: &hir::PolyTraitRef,
2164 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2165 -> ty::PolyTraitRef<'tcx>
2167 astconv::instantiate_poly_trait_ref(astconv,
2174 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2176 param_ty: ty::Ty<'tcx>,
2177 ast_bounds: &[hir::TyParamBound])
2178 -> astconv::Bounds<'tcx>
2180 let tcx = astconv.tcx();
2181 let astconv::PartitionedBounds {
2185 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2187 let mut projection_bounds = Vec::new();
2189 let trait_bounds: Vec<ty::PolyTraitRef> =
2191 .map(|bound| conv_poly_trait_ref(astconv,
2194 &mut projection_bounds))
2197 let region_bounds: Vec<ty::Region> =
2198 region_bounds.into_iter()
2199 .map(|r| ast_region_to_region(tcx, r))
2203 region_bounds: region_bounds,
2204 builtin_bounds: builtin_bounds,
2205 trait_bounds: trait_bounds,
2206 projection_bounds: projection_bounds,
2210 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2211 ccx: &CrateCtxt<'a, 'tcx>,
2213 ast_generics: &hir::Generics,
2215 -> ty::TypeScheme<'tcx>
2217 for i in &decl.inputs {
2218 match (*i).pat.node {
2219 hir::PatIdent(_, _, _) => (),
2222 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2223 "patterns aren't allowed in foreign function declarations");
2228 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2230 let rb = BindingRscope::new();
2231 let input_tys = decl.inputs
2233 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2236 let output = match decl.output {
2237 hir::Return(ref ty) =>
2238 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2239 hir::DefaultReturn(..) =>
2240 ty::FnConverging(ccx.tcx.mk_nil()),
2241 hir::NoReturn(..) =>
2245 let t_fn = ccx.tcx.mk_fn(None,
2246 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2248 unsafety: hir::Unsafety::Unsafe,
2249 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2251 variadic: decl.variadic}),
2255 generics: ty_generics,
2260 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2261 ty_generics: &ty::Generics<'tcx>)
2265 ty_generics.types.map(
2266 |def| ccx.tcx.mk_param_from_def(def));
2269 ty_generics.regions.map(
2270 |def| def.to_early_bound_region());
2272 Substs::new(types, regions)
2275 /// Verifies that the explicit self type of a method matches the impl
2276 /// or trait. This is a bit weird but basically because right now we
2277 /// don't handle the general case, but instead map it to one of
2278 /// several pre-defined options using various heuristics, this method
2279 /// comes back to check after the fact that explicit type the user
2280 /// wrote actually matches what the pre-defined option said.
2281 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2282 ccx: &CrateCtxt<'a, 'tcx>,
2284 method_type: Rc<ty::Method<'tcx>>,
2285 required_type: Ty<'tcx>,
2286 explicit_self: &hir::ExplicitSelf,
2287 body_id: ast::NodeId)
2290 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2291 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2292 let base_type = match typ.sty {
2293 ty::TyRef(_, tm) => tm.ty,
2294 ty::TyBox(typ) => typ,
2298 let body_scope = tcx.region_maps.item_extent(body_id);
2300 // "Required type" comes from the trait definition. It may
2301 // contain late-bound regions from the method, but not the
2302 // trait (since traits only have early-bound region
2304 assert!(!base_type.has_regions_escaping_depth(1));
2305 let required_type_free =
2306 liberate_early_bound_regions(
2308 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2310 // The "base type" comes from the impl. It too may have late-bound
2311 // regions from the method.
2312 assert!(!base_type.has_regions_escaping_depth(1));
2313 let base_type_free =
2314 liberate_early_bound_regions(
2316 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2318 debug!("required_type={:?} required_type_free={:?} \
2319 base_type={:?} base_type_free={:?}",
2325 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2326 drop(::require_same_types(tcx,
2333 format!("mismatched self type: expected `{}`",
2337 // We could conceviably add more free-region relations here,
2338 // but since this code is just concerned with checking that
2339 // the `&Self` types etc match up, it's not really necessary.
2340 // It would just allow people to be more approximate in some
2341 // cases. In any case, we can do it later as we feel the need;
2342 // I'd like this function to go away eventually.
2343 let free_regions = FreeRegionMap::new();
2345 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2348 fn liberate_early_bound_regions<'tcx,T>(
2349 tcx: &ty::ctxt<'tcx>,
2350 scope: region::CodeExtent,
2353 where T : TypeFoldable<'tcx>
2356 * Convert early-bound regions into free regions; normally this is done by
2357 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2358 * method-self-type check is kind of hacky and done very early in the process,
2359 * before we really have a `ParameterEnvironment` to check.
2362 tcx.fold_regions(value, &mut false, |region, _| {
2364 ty::ReEarlyBound(data) => {
2365 ty::ReFree(ty::FreeRegion {
2367 bound_region: ty::BrNamed(data.def_id, data.name)
2376 /// Checks that all the type parameters on an impl
2377 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2378 ast_generics: &hir::Generics,
2379 impl_predicates: &mut ty::GenericPredicates<'tcx>,
2382 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2383 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2385 assert!(impl_predicates.predicates.is_empty_in(FnSpace));
2386 assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
2388 // The trait reference is an input, so find all type parameters
2389 // reachable from there, to start (if this is an inherent impl,
2390 // then just examine the self type).
2391 let mut input_parameters: HashSet<_> =
2392 ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2393 if let Some(ref trait_ref) = impl_trait_ref {
2394 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2397 ctp::setup_constraining_predicates(tcx,
2398 impl_predicates.predicates.get_mut_slice(TypeSpace),
2400 &mut input_parameters);
2402 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2403 let param_ty = ty::ParamTy { space: TypeSpace,
2405 name: ty_param.name };
2406 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2407 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2412 fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2413 ast_generics: &hir::Generics,
2415 impl_items: &[P<hir::ImplItem>])
2417 // Every lifetime used in an associated type must be constrained.
2418 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2419 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2420 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2422 let mut input_parameters: HashSet<_> =
2423 ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2424 if let Some(ref trait_ref) = impl_trait_ref {
2425 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2427 ctp::identify_constrained_type_params(tcx,
2428 &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
2430 let lifetimes_in_associated_types: HashSet<_> =
2432 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2433 .filter_map(|item| match item {
2434 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2435 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2437 .flat_map(|ty| ctp::parameters_for_type(ty))
2438 .filter_map(|p| match p {
2439 ctp::Parameter::Type(_) => None,
2440 ctp::Parameter::Region(r) => Some(r),
2444 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2445 let def_id = tcx.map.local_def_id(lifetime_def.lifetime.id);
2446 let region = ty::EarlyBoundRegion { def_id: def_id,
2448 index: index as u32,
2449 name: lifetime_def.lifetime.name };
2451 lifetimes_in_associated_types.contains(®ion) && // (*)
2452 !input_parameters.contains(&ctp::Parameter::Region(region))
2454 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2455 "lifetime", ®ion.name.to_string());
2459 // (*) This is a horrible concession to reality. I think it'd be
2460 // better to just ban unconstrianed lifetimes outright, but in
2461 // practice people do non-hygenic macros like:
2464 // macro_rules! __impl_slice_eq1 {
2465 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2466 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2473 // In a concession to backwards compatbility, we continue to
2474 // permit those, so long as the lifetimes aren't used in
2475 // associated types. I believe this is sound, because lifetimes
2476 // used elsewhere are not projected back out.
2479 fn report_unused_parameter(tcx: &ty::ctxt,
2484 span_err!(tcx.sess, span, E0207,
2485 "the {} parameter `{}` is not constrained by the \
2486 impl trait, self type, or predicates",