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, LOCAL_CRATE};
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 = DefId::local(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 trait_id.krate != LOCAL_CRATE {
320 return tcx.lookup_trait_def(trait_id)
323 let item = match tcx.map.get(trait_id.node) {
324 hir_map::NodeItem(item) => item,
325 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
328 trait_def_of_item(self, &*item)
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 trait_def_id.is_local() {
406 trait_defines_associated_type_named(self.ccx, trait_def_id.node, 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 those 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.node == param_id
563 def::DefTyParam(_, _, def_id, _) => {
564 path_res.depth == 0 && def_id == DefId::local(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 = DefId::local(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(DefId::local(v.node.id),
636 generics: struct_generics.clone(),
639 ccx.tcx.predicates.borrow_mut().insert(DefId::local(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(DefId::local(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: DefId::local(id),
660 container: container,
664 ccx.tcx.impl_or_trait_items.borrow_mut()
665 .insert(DefId::local(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: DefId::local(id),
682 ccx.tcx.impl_or_trait_items.borrow_mut()
683 .insert(DefId::local(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(DefId::local(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(DefId::local(it.id), Some(trait_ref));
775 // Create generics from the generics specified in the impl head.
776 debug!("convert: ast_generics={:?}", generics);
777 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
778 let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
780 debug!("convert: impl_bounds={:?}", ty_predicates);
782 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
783 write_ty_to_tcx(tcx, it.id, selfty);
785 tcx.register_item_type(DefId::local(it.id),
786 TypeScheme { generics: ty_generics.clone(),
788 tcx.predicates.borrow_mut().insert(DefId::local(it.id),
789 ty_predicates.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(DefId::local(it.id), None);
803 // If there is a trait reference, treat the methods as always public.
804 // This is to work around some incorrect behavior in privacy checking:
805 // when the method belongs to a trait, it should acquire the privacy
806 // from the trait, not the impl. Forcing the visibility to be public
807 // makes things sorta work.
808 let parent_visibility = if opt_trait_ref.is_some() {
814 // Convert all the associated consts.
815 // Also, check if there are any duplicate associated items
816 let mut seen_type_items = FnvHashSet();
817 let mut seen_value_items = FnvHashSet();
819 for impl_item in impl_items {
820 let seen_items = match impl_item.node {
821 hir::TypeImplItem(_) => &mut seen_type_items,
822 _ => &mut seen_value_items,
824 if !seen_items.insert(impl_item.name) {
825 let desc = match impl_item.node {
826 hir::ConstImplItem(_, _) => "associated constant",
827 hir::TypeImplItem(_) => "associated type",
828 hir::MethodImplItem(ref sig, _) =>
829 match sig.explicit_self.node {
830 hir::SelfStatic => "associated function",
835 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
838 if let hir::ConstImplItem(ref ty, _) = impl_item.node {
839 let ty = ccx.icx(&ty_predicates)
840 .to_ty(&ExplicitRscope, &*ty);
841 tcx.register_item_type(DefId::local(impl_item.id),
843 generics: ty_generics.clone(),
846 convert_associated_const(ccx, ImplContainer(DefId::local(it.id)),
847 impl_item.name, impl_item.id,
848 impl_item.vis.inherit_from(parent_visibility),
849 ty, true /* has_value */);
853 // Convert all the associated types.
854 for impl_item in impl_items {
855 if let hir::TypeImplItem(ref ty) = impl_item.node {
856 if opt_trait_ref.is_none() {
857 span_err!(tcx.sess, impl_item.span, E0202,
858 "associated types are not allowed in inherent impls");
861 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
863 convert_associated_type(ccx, ImplContainer(DefId::local(it.id)),
864 impl_item.name, impl_item.id, impl_item.vis,
869 let methods = impl_items.iter().filter_map(|ii| {
870 if let hir::MethodImplItem(ref sig, _) = ii.node {
871 // if the method specifies a visibility, use that, otherwise
872 // inherit the visibility from the impl (so `foo` in `pub impl
873 // { fn foo(); }` is public, but private in `impl { fn
875 let method_vis = ii.vis.inherit_from(parent_visibility);
876 Some((sig, ii.id, ii.name, method_vis, ii.span))
882 ImplContainer(DefId::local(it.id)),
888 for impl_item in impl_items {
889 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
890 let body_id = body.id;
891 check_method_self_type(ccx,
892 &BindingRscope::new(),
893 ccx.method_ty(impl_item.id),
900 enforce_impl_params_are_constrained(tcx,
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, DefId::local(it.id));
909 convert_trait_predicates(ccx, it);
910 let trait_predicates = tcx.lookup_predicates(DefId::local(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(DefId::local(trait_item.id),
922 generics: trait_def.generics.clone(),
925 convert_associated_const(ccx, TraitContainer(DefId::local(it.id)),
926 trait_item.name, trait_item.id,
927 hir::Public, ty, default.is_some());
933 // Convert all the associated types.
934 for trait_item in trait_items {
935 match trait_item.node {
936 hir::TypeTraitItem(_, ref opt_ty) => {
937 let typ = opt_ty.as_ref().map({
938 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
941 convert_associated_type(ccx, TraitContainer(DefId::local(it.id)),
942 trait_item.name, trait_item.id, hir::Public,
949 let methods = trait_items.iter().filter_map(|ti| {
950 let sig = match ti.node {
951 hir::MethodTraitItem(ref sig, _) => sig,
954 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
957 // Run convert_methods on the trait methods.
959 TraitContainer(DefId::local(it.id)),
965 // Add an entry mapping
966 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
967 let def_id = DefId::local(trait_item.id);
968 match trait_item.node {
969 hir::ConstTraitItem(..) => {
970 ty::ConstTraitItemId(def_id)
972 hir::MethodTraitItem(..) => {
973 ty::MethodTraitItemId(def_id)
975 hir::TypeTraitItem(..) => {
976 ty::TypeTraitItemId(def_id)
980 tcx.trait_item_def_ids.borrow_mut().insert(DefId::local(it.id), trait_item_def_ids);
982 // This must be done after `collect_trait_methods` so that
983 // we have a method type stored for every method.
984 for trait_item in trait_items {
985 let sig = match trait_item.node {
986 hir::MethodTraitItem(ref sig, _) => sig,
989 check_method_self_type(ccx,
990 &BindingRscope::new(),
991 ccx.method_ty(trait_item.id),
997 hir::ItemStruct(ref struct_def, _) => {
998 let (scheme, predicates) = convert_typed_item(ccx, it);
999 write_ty_to_tcx(tcx, it.id, scheme.ty);
1001 let variant = tcx.lookup_adt_def_master(DefId::local(it.id)).struct_variant();
1003 for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
1004 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1007 if let Some(ctor_id) = struct_def.ctor_id {
1008 convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
1011 hir::ItemTy(_, ref generics) => {
1012 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1013 let (scheme, _) = convert_typed_item(ccx, it);
1014 write_ty_to_tcx(tcx, it.id, scheme.ty);
1017 // This call populates the type cache with the converted type
1018 // of the item in passing. All we have to do here is to write
1019 // it into the node type table.
1020 let (scheme, _) = convert_typed_item(ccx, it);
1021 write_ty_to_tcx(tcx, it.id, scheme.ty);
1026 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1027 ctor_id: ast::NodeId,
1028 variant: ty::VariantDef<'tcx>,
1029 scheme: ty::TypeScheme<'tcx>,
1030 predicates: ty::GenericPredicates<'tcx>) {
1031 let ctor_ty = match variant.kind() {
1032 VariantKind::Unit | VariantKind::Dict => scheme.ty,
1033 VariantKind::Tuple => {
1034 let inputs: Vec<_> =
1037 .map(|field| field.unsubst_ty())
1039 tcx.mk_ctor_fn(DefId::local(ctor_id),
1044 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1045 tcx.predicates.borrow_mut().insert(DefId::local(ctor_id), predicates);
1046 tcx.register_item_type(DefId::local(ctor_id),
1048 generics: scheme.generics,
1053 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1054 def: ty::AdtDefMaster<'tcx>,
1055 scheme: ty::TypeScheme<'tcx>,
1056 predicates: ty::GenericPredicates<'tcx>,
1057 variants: &[P<hir::Variant>]) {
1059 let icx = ccx.icx(&predicates);
1061 // fill the field types
1062 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1063 match variant.node.kind {
1064 hir::TupleVariantKind(ref args) => {
1065 let rs = ExplicitRscope;
1066 let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
1067 for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
1068 field.fulfill_ty(ty);
1072 hir::StructVariantKind(ref struct_def) => {
1073 for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
1074 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1079 // Convert the ctor, if any. This also registers the variant as
1081 convert_variant_ctor(
1091 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1095 def: &hir::StructDef) -> ty::VariantDefData<'tcx, 'tcx> {
1096 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1097 let fields = def.fields.iter().map(|f| {
1098 let fid = DefId::local(f.node.id);
1100 hir::NamedField(name, vis) => {
1101 let dup_span = seen_fields.get(&name).cloned();
1102 if let Some(prev_span) = dup_span {
1103 span_err!(tcx.sess, f.span, E0124,
1104 "field `{}` is already declared",
1106 span_note!(tcx.sess, prev_span, "previously declared here");
1108 seen_fields.insert(name, f.span);
1111 ty::FieldDefData::new(fid, name, vis)
1113 hir::UnnamedField(vis) => {
1114 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1118 ty::VariantDefData {
1126 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1128 def: &hir::StructDef)
1129 -> ty::AdtDefMaster<'tcx>
1132 let did = DefId::local(it.id);
1135 ty::AdtKind::Struct,
1136 vec![convert_struct_variant(tcx, did, it.name, 0, def)]
1140 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1143 -> ty::AdtDefMaster<'tcx>
1145 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1147 e: &hir::Expr) -> Option<ty::Disr> {
1148 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1150 let hint = UncheckedExprHint(repr_ty);
1151 match const_eval::eval_const_expr_partial(tcx, e, hint) {
1152 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1153 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1155 let sign_desc = if repr_ty.is_signed() {
1160 span_err!(tcx.sess, e.span, E0079,
1161 "expected {} integer constant",
1166 span_err!(tcx.sess, err.span, E0080,
1167 "constant evaluation error: {}",
1174 fn report_discrim_overflow(tcx: &ty::ctxt,
1177 repr_type: attr::IntType,
1178 prev_val: ty::Disr) {
1179 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1180 let computed_value = repr_type.disr_string(computed_value);
1181 let prev_val = repr_type.disr_string(prev_val);
1182 let repr_type = repr_type.to_ty(tcx);
1183 span_err!(tcx.sess, variant_span, E0370,
1184 "enum discriminant overflowed on value after {}: {}; \
1185 set explicitly via {} = {} if that is desired outcome",
1186 prev_val, repr_type, variant_name, computed_value);
1189 fn next_disr(tcx: &ty::ctxt,
1191 repr_type: attr::IntType,
1192 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1193 if let Some(prev_disr_val) = prev_disr_val {
1194 let result = repr_type.disr_incr(prev_disr_val);
1195 if let None = result {
1196 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1197 repr_type, prev_disr_val);
1201 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1204 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1207 -> ty::VariantDefData<'tcx, 'tcx>
1209 let did = DefId::local(v.node.id);
1210 let name = v.node.name;
1212 hir::TupleVariantKind(ref va) => {
1213 ty::VariantDefData {
1217 fields: va.iter().map(|&hir::VariantArg { id, .. }| {
1218 ty::FieldDefData::new(
1220 special_idents::unnamed_field.name,
1221 hir::Visibility::Public
1226 hir::StructVariantKind(ref def) => {
1227 convert_struct_variant(tcx, did, name, disr, &def)
1231 let did = DefId::local(it.id);
1232 let repr_hints = tcx.lookup_repr_hints(did);
1233 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1234 let mut prev_disr = None;
1235 let variants = def.variants.iter().map(|v| {
1236 let disr = match v.node.disr_expr {
1237 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1238 None => next_disr(tcx, v, repr_type, prev_disr)
1239 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1241 let v = convert_enum_variant(tcx, v, disr);
1242 prev_disr = Some(disr);
1245 tcx.intern_adt_def(DefId::local(it.id), ty::AdtKind::Enum, variants)
1248 /// Ensures that the super-predicates of the trait with def-id
1249 /// trait_def_id are converted and stored. This does NOT ensure that
1250 /// the transitive super-predicates are converted; that is the job of
1251 /// the `ensure_super_predicates()` method in the `AstConv` impl
1252 /// above. Returns a list of trait def-ids that must be ensured as
1253 /// well to guarantee that the transitive superpredicates are
1255 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1256 trait_def_id: DefId)
1261 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1263 if trait_def_id.krate != LOCAL_CRATE {
1264 // If this trait comes from an external crate, then all of the
1265 // supertraits it may depend on also must come from external
1266 // crates, and hence all of them already have their
1267 // super-predicates "converted" (and available from crate
1268 // meta-data), so there is no need to transitively test them.
1272 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1273 let superpredicates = superpredicates.unwrap_or_else(|| {
1274 let trait_node_id = trait_def_id.node;
1276 let item = match ccx.tcx.map.get(trait_node_id) {
1277 hir_map::NodeItem(item) => item,
1278 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1281 let (generics, bounds) = match item.node {
1282 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1283 _ => tcx.sess.span_bug(item.span,
1284 "ensure_super_predicates_step invoked on non-trait"),
1287 // In-scope when converting the superbounds for `Trait` are
1288 // that `Self:Trait` as well as any bounds that appear on the
1290 let trait_def = trait_def_of_item(ccx, item);
1291 let self_predicate = ty::GenericPredicates {
1292 predicates: VecPerParamSpace::new(vec![],
1293 vec![trait_def.trait_ref.to_predicate()],
1296 let scope = &(generics, &self_predicate);
1298 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1299 let self_param_ty = tcx.mk_self_type();
1300 let superbounds1 = compute_bounds(&ccx.icx(scope),
1306 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1308 // Convert any explicit superbounds in the where clause,
1309 // e.g. `trait Foo where Self : Bar`:
1310 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1312 // Combine the two lists to form the complete set of superbounds:
1313 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1314 let superpredicates = ty::GenericPredicates {
1315 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1317 debug!("superpredicates for trait {:?} = {:?}",
1318 DefId::local(item.id),
1321 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1326 let def_ids: Vec<_> = superpredicates.predicates
1328 .filter_map(|p| p.to_opt_poly_trait_ref())
1329 .map(|tr| tr.def_id())
1332 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1337 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1339 -> &'tcx ty::TraitDef<'tcx>
1341 let def_id = DefId::local(it.id);
1344 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1348 let (unsafety, generics, items) = match it.node {
1349 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1350 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1353 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1354 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1355 ccx.tcx.sess.span_err(
1357 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1358 which traits can use parenthetical notation");
1359 fileline_help!(ccx.tcx.sess, it.span,
1360 "add `#![feature(unboxed_closures)]` to \
1361 the crate attributes to use it");
1364 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1366 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1368 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1369 match trait_item.node {
1370 hir::TypeTraitItem(..) => Some(trait_item.name),
1375 let trait_ref = ty::TraitRef {
1380 let trait_def = ty::TraitDef {
1381 paren_sugar: paren_sugar,
1383 generics: ty_generics,
1384 trait_ref: trait_ref,
1385 associated_type_names: associated_type_names,
1386 nonblanket_impls: RefCell::new(FnvHashMap()),
1387 blanket_impls: RefCell::new(vec![]),
1388 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1391 return tcx.intern_trait_def(trait_def);
1393 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1394 generics: &hir::Generics)
1399 // Creates a no-op substitution for the trait's type parameters.
1404 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1405 param_id: def.lifetime.id,
1408 name: def.lifetime.name
1412 // Start with the generics in the type parameters...
1417 .map(|(i, def)| tcx.mk_param(TypeSpace,
1418 i as u32, def.name))
1421 // ...and also create the `Self` parameter.
1422 let self_ty = tcx.mk_self_type();
1424 Substs::new_trait(types, regions, self_ty)
1428 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1429 trait_node_id: ast::NodeId,
1430 assoc_name: ast::Name)
1433 let item = match ccx.tcx.map.get(trait_node_id) {
1434 hir_map::NodeItem(item) => item,
1435 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1438 let trait_items = match item.node {
1439 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1440 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1443 trait_items.iter().any(|trait_item| {
1444 match trait_item.node {
1445 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1451 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1453 let trait_def = trait_def_of_item(ccx, it);
1455 let def_id = DefId::local(it.id);
1457 let (generics, items) = match it.node {
1458 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1462 &format!("trait_def_of_item invoked on {:?}", s));
1466 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1468 // `ty_generic_predicates` below will consider the bounds on the type
1469 // parameters (including `Self`) and the explicit where-clauses,
1470 // but to get the full set of predicates on a trait we need to add
1471 // in the supertrait bounds and anything declared on the
1472 // associated types.
1473 let mut base_predicates = super_predicates;
1475 // Add in a predicate that `Self:Trait` (where `Trait` is the
1476 // current trait). This is needed for builtin bounds.
1477 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1478 base_predicates.predicates.push(SelfSpace, self_predicate);
1480 // add in the explicit where-clauses
1481 let mut trait_predicates =
1482 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1484 let assoc_predicates = predicates_for_associated_types(ccx,
1487 trait_def.trait_ref,
1489 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1491 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1492 assert!(prev_predicates.is_none());
1496 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1497 ast_generics: &hir::Generics,
1498 trait_predicates: &ty::GenericPredicates<'tcx>,
1499 self_trait_ref: ty::TraitRef<'tcx>,
1500 trait_items: &[P<hir::TraitItem>])
1501 -> Vec<ty::Predicate<'tcx>>
1503 trait_items.iter().flat_map(|trait_item| {
1504 let bounds = match trait_item.node {
1505 hir::TypeTraitItem(ref bounds, _) => bounds,
1507 return vec!().into_iter();
1511 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1514 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1517 SizedByDefault::Yes,
1520 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1525 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1527 -> ty::TypeScheme<'tcx>
1529 if def_id.krate != LOCAL_CRATE {
1530 return ccx.tcx.lookup_item_type(def_id);
1533 match ccx.tcx.map.find(def_id.node) {
1534 Some(hir_map::NodeItem(item)) => {
1535 type_scheme_of_item(ccx, &*item)
1537 Some(hir_map::NodeForeignItem(foreign_item)) => {
1538 let abi = ccx.tcx.map.get_foreign_abi(def_id.node);
1539 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1542 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1543 in get_item_type_scheme(): {:?}",
1549 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1551 -> ty::TypeScheme<'tcx>
1553 memoized(&ccx.tcx.tcache,
1554 DefId::local(it.id),
1555 |_| compute_type_scheme_of_item(ccx, it))
1558 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1560 -> ty::TypeScheme<'tcx>
1564 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1565 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1566 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1568 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1569 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1570 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1571 let ty = tcx.mk_fn(Some(DefId::local(it.id)), tcx.mk_bare_fn(tofd));
1572 ty::TypeScheme { ty: ty, generics: ty_generics }
1574 hir::ItemTy(ref t, ref generics) => {
1575 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1576 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1577 ty::TypeScheme { ty: ty, generics: ty_generics }
1579 hir::ItemEnum(ref ei, ref generics) => {
1580 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1581 let substs = mk_item_substs(ccx, &ty_generics);
1582 let def = convert_enum_def(tcx, it, ei);
1583 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1584 ty::TypeScheme { ty: t, generics: ty_generics }
1586 hir::ItemStruct(ref si, ref generics) => {
1587 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1588 let substs = mk_item_substs(ccx, &ty_generics);
1589 let def = convert_struct_def(tcx, it, si);
1590 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1591 ty::TypeScheme { ty: t, generics: ty_generics }
1593 hir::ItemDefaultImpl(..) |
1594 hir::ItemTrait(..) |
1597 hir::ItemForeignMod(..) |
1598 hir::ItemExternCrate(..) |
1599 hir::ItemUse(..) => {
1602 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1608 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1610 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1614 let tag = type_scheme_of_item(ccx, it);
1615 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1616 let predicates = match it.node {
1617 hir::ItemStatic(..) | hir::ItemConst(..) => {
1618 ty::GenericPredicates::empty()
1620 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1621 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1623 hir::ItemTy(_, ref generics) => {
1624 ty_generic_predicates_for_type_or_impl(ccx, generics)
1626 hir::ItemEnum(_, ref generics) => {
1627 ty_generic_predicates_for_type_or_impl(ccx, generics)
1629 hir::ItemStruct(_, ref generics) => {
1630 ty_generic_predicates_for_type_or_impl(ccx, generics)
1632 hir::ItemDefaultImpl(..) |
1633 hir::ItemTrait(..) |
1634 hir::ItemExternCrate(..) |
1638 hir::ItemForeignMod(..) => {
1641 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1646 let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id),
1647 predicates.clone());
1648 assert!(prev_predicates.is_none());
1651 if tcx.has_attr(DefId::local(it.id), "rustc_object_lifetime_default") {
1652 let object_lifetime_default_reprs: String =
1653 scheme.generics.types.iter()
1654 .map(|t| match t.object_lifetime_default {
1655 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1656 d => format!("{:?}", d),
1658 .collect::<Vec<String>>()
1661 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1664 return (scheme, predicates);
1667 fn type_scheme_of_foreign_item<'a, 'tcx>(
1668 ccx: &CrateCtxt<'a, 'tcx>,
1669 it: &hir::ForeignItem,
1671 -> ty::TypeScheme<'tcx>
1673 memoized(&ccx.tcx.tcache,
1674 DefId::local(it.id),
1675 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1678 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1679 ccx: &CrateCtxt<'a, 'tcx>,
1680 it: &hir::ForeignItem,
1682 -> ty::TypeScheme<'tcx>
1685 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1686 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1688 hir::ForeignItemStatic(ref t, _) => {
1690 generics: ty::Generics::empty(),
1691 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1697 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1698 it: &hir::ForeignItem)
1700 // For reasons I cannot fully articulate, I do so hate the AST
1701 // map, and I regard each time that I use it as a personal and
1702 // moral failing, but at the moment it seems like the only
1703 // convenient way to extract the ABI. - ndm
1705 let abi = tcx.map.get_foreign_abi(it.id);
1707 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1708 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1710 let predicates = match it.node {
1711 hir::ForeignItemFn(_, ref generics) => {
1712 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1714 hir::ForeignItemStatic(..) => {
1715 ty::GenericPredicates::empty()
1719 let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id), predicates);
1720 assert!(prev_predicates.is_none());
1723 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1724 generics: &hir::Generics)
1725 -> ty::Generics<'tcx> {
1726 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1729 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1730 generics: &hir::Generics)
1731 -> ty::GenericPredicates<'tcx>
1733 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1736 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1737 trait_id: ast::NodeId,
1738 substs: &'tcx Substs<'tcx>,
1739 ast_generics: &hir::Generics)
1740 -> ty::Generics<'tcx>
1742 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1743 DefId::local(trait_id), substs);
1745 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1747 // Add in the self type parameter.
1749 // Something of a hack: use the node id for the trait, also as
1750 // the node id for the Self type parameter.
1751 let param_id = trait_id;
1753 let parent = ccx.tcx.map.get_parent(param_id);
1755 let def = ty::TypeParameterDef {
1758 name: special_idents::type_self.name,
1759 def_id: DefId::local(param_id),
1760 default_def_id: DefId::local(parent),
1762 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1765 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1767 generics.types.push(SelfSpace, def);
1772 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1773 generics: &hir::Generics,
1774 base_generics: &ty::Generics<'tcx>)
1775 -> ty::Generics<'tcx>
1777 ty_generics(ccx, FnSpace, generics, base_generics)
1780 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1781 generics: &hir::Generics,
1782 base_predicates: &ty::GenericPredicates<'tcx>)
1783 -> ty::GenericPredicates<'tcx>
1785 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1788 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1789 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1790 bounds: &mut ty::BuiltinBounds,
1791 ast_bounds: &[hir::TyParamBound],
1794 let tcx = astconv.tcx();
1796 // Try to find an unbound in bounds.
1797 let mut unbound = None;
1798 for ab in ast_bounds {
1799 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1800 if unbound.is_none() {
1801 assert!(ptr.bound_lifetimes.is_empty());
1802 unbound = Some(ptr.trait_ref.clone());
1804 span_err!(tcx.sess, span, E0203,
1805 "type parameter has more than one relaxed default \
1806 bound, only one is supported");
1811 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1814 // FIXME(#8559) currently requires the unbound to be built-in.
1815 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1817 Ok(kind_id) if trait_def_id != kind_id => {
1818 tcx.sess.span_warn(span,
1819 "default bound relaxed for a type parameter, but \
1820 this does nothing because the given bound is not \
1821 a default. Only `?Sized` is supported");
1822 tcx.try_add_builtin_trait(kind_id, bounds);
1827 _ if kind_id.is_ok() => {
1828 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1830 // No lang item for Sized, so we can't add it as a bound.
1835 /// Returns the early-bound lifetimes declared in this generics
1836 /// listing. For anything other than fns/methods, this is just all
1837 /// the lifetimes that are declared. For fns or methods, we have to
1838 /// screen out those that do not appear in any where-clauses etc using
1839 /// `resolve_lifetime::early_bound_lifetimes`.
1840 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1841 ast_generics: &hir::Generics)
1842 -> Vec<hir::LifetimeDef>
1845 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1846 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1850 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1852 ast_generics: &hir::Generics,
1853 base_predicates: &ty::GenericPredicates<'tcx>)
1854 -> ty::GenericPredicates<'tcx>
1857 let mut result = base_predicates.clone();
1859 // Collect the predicates that were written inline by the user on each
1860 // type parameter (e.g., `<T:Foo>`).
1861 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1862 let index = index as u32;
1863 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1864 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1867 SizedByDefault::Yes,
1869 let predicates = bounds.predicates(ccx.tcx, param_ty);
1870 result.predicates.extend(space, predicates.into_iter());
1873 // Collect the region predicates that were declared inline as
1874 // well. In the case of parameters declared on a fn or method, we
1875 // have to be careful to only iterate over early-bound regions.
1876 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1877 for (index, param) in early_lifetimes.iter().enumerate() {
1878 let index = index as u32;
1880 ty::ReEarlyBound(ty::EarlyBoundRegion {
1881 param_id: param.lifetime.id,
1884 name: param.lifetime.name
1886 for bound in ¶m.bounds {
1887 let bound_region = ast_region_to_region(ccx.tcx, bound);
1888 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1889 result.predicates.push(space, outlives.to_predicate());
1893 // Add in the bounds that appear in the where-clause
1894 let where_clause = &ast_generics.where_clause;
1895 for predicate in &where_clause.predicates {
1897 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1898 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1900 &*bound_pred.bounded_ty);
1902 for bound in bound_pred.bounds.iter() {
1904 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1905 let mut projections = Vec::new();
1908 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1913 result.predicates.push(space, trait_ref.to_predicate());
1915 for projection in &projections {
1916 result.predicates.push(space, projection.to_predicate());
1920 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1921 let region = ast_region_to_region(tcx, lifetime);
1922 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1923 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1929 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1930 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1931 for bound in ®ion_pred.bounds {
1932 let r2 = ast_region_to_region(tcx, bound);
1933 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1934 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1938 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1940 tcx.sess.span_bug(eq_pred.span,
1941 "Equality constraints are not yet \
1942 implemented (#20041)")
1950 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1952 ast_generics: &hir::Generics,
1953 base_generics: &ty::Generics<'tcx>)
1954 -> ty::Generics<'tcx>
1957 let mut result = base_generics.clone();
1959 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1960 for (i, l) in early_lifetimes.iter().enumerate() {
1961 let bounds = l.bounds.iter()
1962 .map(|l| ast_region_to_region(tcx, l))
1964 let def = ty::RegionParameterDef { name: l.lifetime.name,
1967 def_id: DefId::local(l.lifetime.id),
1969 result.regions.push(space, def);
1972 assert!(result.types.is_empty_in(space));
1974 // Now create the real type parameters.
1975 for i in 0..ast_generics.ty_params.len() {
1976 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1977 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1978 result.types.push(space, def);
1984 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1990 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1992 for leaf_ty in ty.walk() {
1993 if let ty::TyParam(p) = leaf_ty.sty {
1994 if p.space == space && p.idx >= index {
1995 span_err!(ccx.tcx.sess, path.span, E0128,
1996 "type parameters with a default cannot use \
1997 forward declared identifiers");
1999 return ccx.tcx.types.err
2007 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2008 ast_generics: &hir::Generics,
2011 -> ty::TypeParameterDef<'tcx>
2013 let param = &ast_generics.ty_params[index as usize];
2016 match tcx.ty_param_defs.borrow().get(¶m.id) {
2017 Some(d) => { return d.clone(); }
2021 let default = param.default.as_ref().map(
2022 |def| convert_default_type_parameter(ccx, def, space, index)
2025 let object_lifetime_default =
2026 compute_object_lifetime_default(ccx, param.id,
2027 ¶m.bounds, &ast_generics.where_clause);
2029 let parent = tcx.map.get_parent(param.id);
2031 let def = ty::TypeParameterDef {
2035 def_id: DefId::local(param.id),
2036 default_def_id: DefId::local(parent),
2038 object_lifetime_default: object_lifetime_default,
2041 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2046 /// Scan the bounds and where-clauses on a parameter to extract bounds
2047 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2048 /// This runs as part of computing the minimal type scheme, so we
2049 /// intentionally avoid just asking astconv to convert all the where
2050 /// clauses into a `ty::Predicate`. This is because that could induce
2051 /// artificial cycles.
2052 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2053 param_id: ast::NodeId,
2054 param_bounds: &[hir::TyParamBound],
2055 where_clause: &hir::WhereClause)
2056 -> ty::ObjectLifetimeDefault
2058 let inline_bounds = from_bounds(ccx, param_bounds);
2059 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2060 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2061 .chain(where_bounds)
2063 return if all_bounds.len() > 1 {
2064 ty::ObjectLifetimeDefault::Ambiguous
2065 } else if all_bounds.len() == 0 {
2066 ty::ObjectLifetimeDefault::BaseDefault
2068 ty::ObjectLifetimeDefault::Specific(
2069 all_bounds.into_iter().next().unwrap())
2072 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2073 bounds: &[hir::TyParamBound])
2077 .filter_map(|bound| {
2079 hir::TraitTyParamBound(..) =>
2081 hir::RegionTyParamBound(ref lifetime) =>
2082 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2088 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2089 param_id: ast::NodeId,
2090 predicates: &[hir::WherePredicate])
2094 .flat_map(|predicate| {
2096 hir::WherePredicate::BoundPredicate(ref data) => {
2097 if data.bound_lifetimes.is_empty() &&
2098 is_param(ccx.tcx, &data.bounded_ty, param_id)
2100 from_bounds(ccx, &data.bounds).into_iter()
2102 Vec::new().into_iter()
2105 hir::WherePredicate::RegionPredicate(..) |
2106 hir::WherePredicate::EqPredicate(..) => {
2107 Vec::new().into_iter()
2115 enum SizedByDefault { Yes, No, }
2117 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2118 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2119 /// built-in trait (formerly known as kind): Send.
2120 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2121 param_ty: ty::Ty<'tcx>,
2122 ast_bounds: &[hir::TyParamBound],
2123 sized_by_default: SizedByDefault,
2125 -> astconv::Bounds<'tcx>
2128 conv_param_bounds(astconv,
2133 if let SizedByDefault::Yes = sized_by_default {
2134 add_unsized_bound(astconv,
2135 &mut bounds.builtin_bounds,
2140 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2145 /// Converts a specific TyParamBound from the AST into a set of
2146 /// predicates that apply to the self-type. A vector is returned
2147 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2148 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2149 /// and `<T as Bar>::X == i32`).
2150 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2152 bound: &hir::TyParamBound)
2153 -> Vec<ty::Predicate<'tcx>>
2156 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2157 let mut projections = Vec::new();
2158 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2159 projections.into_iter()
2160 .map(|p| p.to_predicate())
2161 .chain(Some(pred.to_predicate()))
2164 hir::RegionTyParamBound(ref lifetime) => {
2165 let region = ast_region_to_region(astconv.tcx(), lifetime);
2166 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2167 vec![ty::Predicate::TypeOutlives(pred)]
2169 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2175 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2177 trait_ref: &hir::PolyTraitRef,
2178 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2179 -> ty::PolyTraitRef<'tcx>
2181 astconv::instantiate_poly_trait_ref(astconv,
2188 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2190 param_ty: ty::Ty<'tcx>,
2191 ast_bounds: &[hir::TyParamBound])
2192 -> astconv::Bounds<'tcx>
2194 let tcx = astconv.tcx();
2195 let astconv::PartitionedBounds {
2199 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2201 let mut projection_bounds = Vec::new();
2203 let trait_bounds: Vec<ty::PolyTraitRef> =
2205 .map(|bound| conv_poly_trait_ref(astconv,
2208 &mut projection_bounds))
2211 let region_bounds: Vec<ty::Region> =
2212 region_bounds.into_iter()
2213 .map(|r| ast_region_to_region(tcx, r))
2217 region_bounds: region_bounds,
2218 builtin_bounds: builtin_bounds,
2219 trait_bounds: trait_bounds,
2220 projection_bounds: projection_bounds,
2224 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2225 ccx: &CrateCtxt<'a, 'tcx>,
2227 ast_generics: &hir::Generics,
2229 -> ty::TypeScheme<'tcx>
2231 for i in &decl.inputs {
2232 match (*i).pat.node {
2233 hir::PatIdent(_, _, _) => (),
2234 hir::PatWild(hir::PatWildSingle) => (),
2236 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2237 "patterns aren't allowed in foreign function declarations");
2242 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2244 let rb = BindingRscope::new();
2245 let input_tys = decl.inputs
2247 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2250 let output = match decl.output {
2251 hir::Return(ref ty) =>
2252 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2253 hir::DefaultReturn(..) =>
2254 ty::FnConverging(ccx.tcx.mk_nil()),
2255 hir::NoReturn(..) =>
2259 let t_fn = ccx.tcx.mk_fn(None,
2260 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2262 unsafety: hir::Unsafety::Unsafe,
2263 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2265 variadic: decl.variadic}),
2269 generics: ty_generics,
2274 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2275 ty_generics: &ty::Generics<'tcx>)
2279 ty_generics.types.map(
2280 |def| ccx.tcx.mk_param_from_def(def));
2283 ty_generics.regions.map(
2284 |def| def.to_early_bound_region());
2286 Substs::new(types, regions)
2289 /// Verifies that the explicit self type of a method matches the impl
2290 /// or trait. This is a bit weird but basically because right now we
2291 /// don't handle the general case, but instead map it to one of
2292 /// several pre-defined options using various heuristics, this method
2293 /// comes back to check after the fact that explicit type the user
2294 /// wrote actually matches what the pre-defined option said.
2295 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2296 ccx: &CrateCtxt<'a, 'tcx>,
2298 method_type: Rc<ty::Method<'tcx>>,
2299 required_type: Ty<'tcx>,
2300 explicit_self: &hir::ExplicitSelf,
2301 body_id: ast::NodeId)
2304 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2305 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2306 let base_type = match typ.sty {
2307 ty::TyRef(_, tm) => tm.ty,
2308 ty::TyBox(typ) => typ,
2312 let body_scope = tcx.region_maps.item_extent(body_id);
2314 // "Required type" comes from the trait definition. It may
2315 // contain late-bound regions from the method, but not the
2316 // trait (since traits only have early-bound region
2318 assert!(!base_type.has_regions_escaping_depth(1));
2319 let required_type_free =
2320 liberate_early_bound_regions(
2322 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2324 // The "base type" comes from the impl. It too may have late-bound
2325 // regions from the method.
2326 assert!(!base_type.has_regions_escaping_depth(1));
2327 let base_type_free =
2328 liberate_early_bound_regions(
2330 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2332 debug!("required_type={:?} required_type_free={:?} \
2333 base_type={:?} base_type_free={:?}",
2339 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2340 drop(::require_same_types(tcx,
2347 format!("mismatched self type: expected `{}`",
2351 // We could conceviably add more free-region relations here,
2352 // but since this code is just concerned with checking that
2353 // the `&Self` types etc match up, it's not really necessary.
2354 // It would just allow people to be more approximate in some
2355 // cases. In any case, we can do it later as we feel the need;
2356 // I'd like this function to go away eventually.
2357 let free_regions = FreeRegionMap::new();
2359 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2362 fn liberate_early_bound_regions<'tcx,T>(
2363 tcx: &ty::ctxt<'tcx>,
2364 scope: region::CodeExtent,
2367 where T : TypeFoldable<'tcx>
2370 * Convert early-bound regions into free regions; normally this is done by
2371 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2372 * method-self-type check is kind of hacky and done very early in the process,
2373 * before we really have a `ParameterEnvironment` to check.
2376 tcx.fold_regions(value, &mut false, |region, _| {
2378 ty::ReEarlyBound(data) => {
2379 let def_id = DefId::local(data.param_id);
2380 ty::ReFree(ty::FreeRegion { scope: scope,
2381 bound_region: ty::BrNamed(def_id, data.name) })
2389 /// Checks that all the type parameters on an impl
2390 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2391 ast_generics: &hir::Generics,
2393 impl_items: &[P<hir::ImplItem>])
2395 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2396 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2397 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2399 // The trait reference is an input, so find all type parameters
2400 // reachable from there, to start (if this is an inherent impl,
2401 // then just examine the self type).
2402 let mut input_parameters: HashSet<_> =
2403 ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2404 if let Some(ref trait_ref) = impl_trait_ref {
2405 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2408 ctp::identify_constrained_type_params(tcx,
2409 impl_predicates.predicates.as_slice(),
2411 &mut input_parameters);
2413 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2414 let param_ty = ty::ParamTy { space: TypeSpace,
2416 name: ty_param.name };
2417 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2418 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2422 // Every lifetime used in an associated type must be constrained.
2424 let lifetimes_in_associated_types: HashSet<_> =
2426 .map(|item| tcx.impl_or_trait_item(DefId::local(item.id)))
2427 .filter_map(|item| match item {
2428 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2429 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2431 .flat_map(|ty| ctp::parameters_for_type(ty))
2432 .filter_map(|p| match p {
2433 ctp::Parameter::Type(_) => None,
2434 ctp::Parameter::Region(r) => Some(r),
2438 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2439 let region = ty::EarlyBoundRegion { param_id: lifetime_def.lifetime.id,
2441 index: index as u32,
2442 name: lifetime_def.lifetime.name };
2444 lifetimes_in_associated_types.contains(®ion) && // (*)
2445 !input_parameters.contains(&ctp::Parameter::Region(region))
2447 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2448 "lifetime", ®ion.name.to_string());
2452 // (*) This is a horrible concession to reality. I think it'd be
2453 // better to just ban unconstrianed lifetimes outright, but in
2454 // practice people do non-hygenic macros like:
2457 // macro_rules! __impl_slice_eq1 {
2458 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2459 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2466 // In a concession to backwards compatbility, we continue to
2467 // permit those, so long as the lifetimes aren't used in
2468 // associated types. I believe this is sound, because lifetimes
2469 // used elsewhere are not projected back out.
2472 fn report_unused_parameter(tcx: &ty::ctxt,
2477 span_err!(tcx.sess, span, E0207,
2478 "the {} parameter `{}` is not constrained by the \
2479 impl trait, self type, or predicates",