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 ty_generics = ty_generics_for_type_or_impl(ccx, generics);
779 let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
781 debug!("convert: impl_bounds={:?}", ty_predicates);
783 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
784 write_ty_to_tcx(tcx, it.id, selfty);
786 tcx.register_item_type(ccx.tcx.map.local_def_id(it.id),
787 TypeScheme { generics: ty_generics.clone(),
789 tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
790 ty_predicates.clone());
791 if let &Some(ref ast_trait_ref) = opt_trait_ref {
792 tcx.impl_trait_refs.borrow_mut().insert(
793 ccx.tcx.map.local_def_id(it.id),
794 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
800 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), None);
804 // If there is a trait reference, treat the methods as always public.
805 // This is to work around some incorrect behavior in privacy checking:
806 // when the method belongs to a trait, it should acquire the privacy
807 // from the trait, not the impl. Forcing the visibility to be public
808 // makes things sorta work.
809 let parent_visibility = if opt_trait_ref.is_some() {
815 // Convert all the associated consts.
816 // Also, check if there are any duplicate associated items
817 let mut seen_type_items = FnvHashSet();
818 let mut seen_value_items = FnvHashSet();
820 for impl_item in impl_items {
821 let seen_items = match impl_item.node {
822 hir::TypeImplItem(_) => &mut seen_type_items,
823 _ => &mut seen_value_items,
825 if !seen_items.insert(impl_item.name) {
826 let desc = match impl_item.node {
827 hir::ConstImplItem(_, _) => "associated constant",
828 hir::TypeImplItem(_) => "associated type",
829 hir::MethodImplItem(ref sig, _) =>
830 match sig.explicit_self.node {
831 hir::SelfStatic => "associated function",
836 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
839 if let hir::ConstImplItem(ref ty, _) = impl_item.node {
840 let ty = ccx.icx(&ty_predicates)
841 .to_ty(&ExplicitRscope, &*ty);
842 tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
844 generics: ty_generics.clone(),
847 convert_associated_const(ccx, ImplContainer(ccx.tcx.map.local_def_id(it.id)),
848 impl_item.name, impl_item.id,
849 impl_item.vis.inherit_from(parent_visibility),
850 ty, true /* has_value */);
854 // Convert all the associated types.
855 for impl_item in impl_items {
856 if let hir::TypeImplItem(ref ty) = impl_item.node {
857 if opt_trait_ref.is_none() {
858 span_err!(tcx.sess, impl_item.span, E0202,
859 "associated types are not allowed in inherent impls");
862 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
864 convert_associated_type(ccx, ImplContainer(ccx.tcx.map.local_def_id(it.id)),
865 impl_item.name, impl_item.id, impl_item.vis,
870 let methods = impl_items.iter().filter_map(|ii| {
871 if let hir::MethodImplItem(ref sig, _) = ii.node {
872 // if the method specifies a visibility, use that, otherwise
873 // inherit the visibility from the impl (so `foo` in `pub impl
874 // { fn foo(); }` is public, but private in `impl { fn
876 let method_vis = ii.vis.inherit_from(parent_visibility);
877 Some((sig, ii.id, ii.name, method_vis, ii.span))
883 ImplContainer(ccx.tcx.map.local_def_id(it.id)),
889 for impl_item in impl_items {
890 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
891 let body_id = body.id;
892 check_method_self_type(ccx,
893 &BindingRscope::new(),
894 ccx.method_ty(impl_item.id),
901 enforce_impl_params_are_constrained(tcx,
903 ccx.tcx.map.local_def_id(it.id),
906 hir::ItemTrait(_, _, _, ref trait_items) => {
907 let trait_def = trait_def_of_item(ccx, it);
908 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
909 ccx.ensure_super_predicates(it.span, ccx.tcx.map.local_def_id(it.id));
910 convert_trait_predicates(ccx, it);
911 let trait_predicates = tcx.lookup_predicates(ccx.tcx.map.local_def_id(it.id));
913 debug!("convert: trait_bounds={:?}", trait_predicates);
915 // Convert all the associated types.
916 for trait_item in trait_items {
917 match trait_item.node {
918 hir::ConstTraitItem(ref ty, ref default) => {
919 let ty = ccx.icx(&trait_predicates)
920 .to_ty(&ExplicitRscope, ty);
921 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
923 generics: trait_def.generics.clone(),
926 convert_associated_const(ccx,
927 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
938 // Convert all the associated types.
939 for trait_item in trait_items {
940 match trait_item.node {
941 hir::TypeTraitItem(_, ref opt_ty) => {
942 let typ = opt_ty.as_ref().map({
943 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
946 convert_associated_type(ccx,
947 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
957 let methods = trait_items.iter().filter_map(|ti| {
958 let sig = match ti.node {
959 hir::MethodTraitItem(ref sig, _) => sig,
962 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
965 // Run convert_methods on the trait methods.
967 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
973 // Add an entry mapping
974 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
975 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
976 match trait_item.node {
977 hir::ConstTraitItem(..) => {
978 ty::ConstTraitItemId(def_id)
980 hir::MethodTraitItem(..) => {
981 ty::MethodTraitItemId(def_id)
983 hir::TypeTraitItem(..) => {
984 ty::TypeTraitItemId(def_id)
988 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
991 // This must be done after `collect_trait_methods` so that
992 // we have a method type stored for every method.
993 for trait_item in trait_items {
994 let sig = match trait_item.node {
995 hir::MethodTraitItem(ref sig, _) => sig,
998 check_method_self_type(ccx,
999 &BindingRscope::new(),
1000 ccx.method_ty(trait_item.id),
1006 hir::ItemStruct(ref struct_def, _) => {
1007 let (scheme, predicates) = convert_typed_item(ccx, it);
1008 write_ty_to_tcx(tcx, it.id, scheme.ty);
1010 let it_def_id = ccx.tcx.map.local_def_id(it.id);
1011 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
1013 for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
1014 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1017 if let Some(ctor_id) = struct_def.ctor_id {
1018 convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
1021 hir::ItemTy(_, ref generics) => {
1022 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1023 let (scheme, _) = convert_typed_item(ccx, it);
1024 write_ty_to_tcx(tcx, it.id, scheme.ty);
1027 // This call populates the type cache with the converted type
1028 // of the item in passing. All we have to do here is to write
1029 // it into the node type table.
1030 let (scheme, _) = convert_typed_item(ccx, it);
1031 write_ty_to_tcx(tcx, it.id, scheme.ty);
1036 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1037 ctor_id: ast::NodeId,
1038 variant: ty::VariantDef<'tcx>,
1039 scheme: ty::TypeScheme<'tcx>,
1040 predicates: ty::GenericPredicates<'tcx>) {
1041 let ctor_ty = match variant.kind() {
1042 VariantKind::Unit | VariantKind::Dict => scheme.ty,
1043 VariantKind::Tuple => {
1044 let inputs: Vec<_> =
1047 .map(|field| field.unsubst_ty())
1049 tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
1054 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1055 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
1056 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
1058 generics: scheme.generics,
1063 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1064 def: ty::AdtDefMaster<'tcx>,
1065 scheme: ty::TypeScheme<'tcx>,
1066 predicates: ty::GenericPredicates<'tcx>,
1067 variants: &[P<hir::Variant>]) {
1069 let icx = ccx.icx(&predicates);
1071 // fill the field types
1072 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1073 match variant.node.kind {
1074 hir::TupleVariantKind(ref args) => {
1075 let rs = ExplicitRscope;
1076 let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
1077 for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
1078 field.fulfill_ty(ty);
1082 hir::StructVariantKind(ref struct_def) => {
1083 for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
1084 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1089 // Convert the ctor, if any. This also registers the variant as
1091 convert_variant_ctor(
1101 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1105 def: &hir::StructDef,
1106 ctor_id: DefId) -> ty::VariantDefData<'tcx, 'tcx> {
1107 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1108 let fields = def.fields.iter().map(|f| {
1109 let fid = tcx.map.local_def_id(f.node.id);
1111 hir::NamedField(name, vis) => {
1112 let dup_span = seen_fields.get(&name).cloned();
1113 if let Some(prev_span) = dup_span {
1114 span_err!(tcx.sess, f.span, E0124,
1115 "field `{}` is already declared",
1117 span_note!(tcx.sess, prev_span, "previously declared here");
1119 seen_fields.insert(name, f.span);
1122 ty::FieldDefData::new(fid, name, vis)
1124 hir::UnnamedField(vis) => {
1125 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1129 ty::VariantDefData {
1138 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1140 def: &hir::StructDef)
1141 -> ty::AdtDefMaster<'tcx>
1144 let did = tcx.map.local_def_id(it.id);
1145 let ctor_id = def.ctor_id.map_or(did,
1146 |ctor_id| tcx.map.local_def_id(ctor_id));
1149 ty::AdtKind::Struct,
1150 vec![convert_struct_variant(tcx, did, it.name, 0, def, ctor_id)]
1154 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1157 -> ty::AdtDefMaster<'tcx>
1159 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1161 e: &hir::Expr) -> Option<ty::Disr> {
1162 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1164 let hint = UncheckedExprHint(repr_ty);
1165 match const_eval::eval_const_expr_partial(tcx, e, hint) {
1166 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1167 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1169 let sign_desc = if repr_ty.is_signed() {
1174 span_err!(tcx.sess, e.span, E0079,
1175 "expected {} integer constant",
1180 span_err!(tcx.sess, err.span, E0080,
1181 "constant evaluation error: {}",
1183 if !e.span.contains(err.span) {
1184 tcx.sess.span_note(e.span, "for enum discriminant here");
1191 fn report_discrim_overflow(tcx: &ty::ctxt,
1194 repr_type: attr::IntType,
1195 prev_val: ty::Disr) {
1196 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1197 let computed_value = repr_type.disr_string(computed_value);
1198 let prev_val = repr_type.disr_string(prev_val);
1199 let repr_type = repr_type.to_ty(tcx);
1200 span_err!(tcx.sess, variant_span, E0370,
1201 "enum discriminant overflowed on value after {}: {}; \
1202 set explicitly via {} = {} if that is desired outcome",
1203 prev_val, repr_type, variant_name, computed_value);
1206 fn next_disr(tcx: &ty::ctxt,
1208 repr_type: attr::IntType,
1209 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1210 if let Some(prev_disr_val) = prev_disr_val {
1211 let result = repr_type.disr_incr(prev_disr_val);
1212 if let None = result {
1213 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1214 repr_type, prev_disr_val);
1218 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1221 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1224 -> ty::VariantDefData<'tcx, 'tcx>
1226 let did = tcx.map.local_def_id(v.node.id);
1227 let name = v.node.name;
1229 hir::TupleVariantKind(ref va) => {
1230 ty::VariantDefData {
1234 fields: va.iter().map(|&hir::VariantArg { id, .. }| {
1235 ty::FieldDefData::new(
1236 tcx.map.local_def_id(id),
1237 special_idents::unnamed_field.name,
1238 hir::Visibility::Public
1244 hir::StructVariantKind(ref def) => {
1245 convert_struct_variant(tcx, did, name, disr, &def, did)
1249 let did = tcx.map.local_def_id(it.id);
1250 let repr_hints = tcx.lookup_repr_hints(did);
1251 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1252 let mut prev_disr = None;
1253 let variants = def.variants.iter().map(|v| {
1254 let disr = match v.node.disr_expr {
1255 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1256 None => next_disr(tcx, v, repr_type, prev_disr)
1257 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1259 let v = convert_enum_variant(tcx, v, disr);
1260 prev_disr = Some(disr);
1263 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1266 /// Ensures that the super-predicates of the trait with def-id
1267 /// trait_def_id are converted and stored. This does NOT ensure that
1268 /// the transitive super-predicates are converted; that is the job of
1269 /// the `ensure_super_predicates()` method in the `AstConv` impl
1270 /// above. Returns a list of trait def-ids that must be ensured as
1271 /// well to guarantee that the transitive superpredicates are
1273 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1274 trait_def_id: DefId)
1279 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1281 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1284 // If this trait comes from an external crate, then all of the
1285 // supertraits it may depend on also must come from external
1286 // crates, and hence all of them already have their
1287 // super-predicates "converted" (and available from crate
1288 // meta-data), so there is no need to transitively test them.
1292 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1293 let superpredicates = superpredicates.unwrap_or_else(|| {
1294 let item = match ccx.tcx.map.get(trait_node_id) {
1295 hir_map::NodeItem(item) => item,
1296 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1299 let (generics, bounds) = match item.node {
1300 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1301 _ => tcx.sess.span_bug(item.span,
1302 "ensure_super_predicates_step invoked on non-trait"),
1305 // In-scope when converting the superbounds for `Trait` are
1306 // that `Self:Trait` as well as any bounds that appear on the
1308 let trait_def = trait_def_of_item(ccx, item);
1309 let self_predicate = ty::GenericPredicates {
1310 predicates: VecPerParamSpace::new(vec![],
1311 vec![trait_def.trait_ref.to_predicate()],
1314 let scope = &(generics, &self_predicate);
1316 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1317 let self_param_ty = tcx.mk_self_type();
1318 let superbounds1 = compute_bounds(&ccx.icx(scope),
1324 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1326 // Convert any explicit superbounds in the where clause,
1327 // e.g. `trait Foo where Self : Bar`:
1328 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1330 // Combine the two lists to form the complete set of superbounds:
1331 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1332 let superpredicates = ty::GenericPredicates {
1333 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1335 debug!("superpredicates for trait {:?} = {:?}",
1336 tcx.map.local_def_id(item.id),
1339 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1344 let def_ids: Vec<_> = superpredicates.predicates
1346 .filter_map(|p| p.to_opt_poly_trait_ref())
1347 .map(|tr| tr.def_id())
1350 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1355 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1357 -> &'tcx ty::TraitDef<'tcx>
1359 let def_id = ccx.tcx.map.local_def_id(it.id);
1362 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1366 let (unsafety, generics, items) = match it.node {
1367 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1368 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1371 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1372 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1373 ccx.tcx.sess.span_err(
1375 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1376 which traits can use parenthetical notation");
1377 fileline_help!(ccx.tcx.sess, it.span,
1378 "add `#![feature(unboxed_closures)]` to \
1379 the crate attributes to use it");
1382 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1384 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1386 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1387 match trait_item.node {
1388 hir::TypeTraitItem(..) => Some(trait_item.name),
1393 let trait_ref = ty::TraitRef {
1398 let trait_def = ty::TraitDef {
1399 paren_sugar: paren_sugar,
1401 generics: ty_generics,
1402 trait_ref: trait_ref,
1403 associated_type_names: associated_type_names,
1404 nonblanket_impls: RefCell::new(FnvHashMap()),
1405 blanket_impls: RefCell::new(vec![]),
1406 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1409 return tcx.intern_trait_def(trait_def);
1411 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1412 generics: &hir::Generics)
1417 // Creates a no-op substitution for the trait's type parameters.
1422 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1423 def_id: tcx.map.local_def_id(def.lifetime.id),
1426 name: def.lifetime.name
1430 // Start with the generics in the type parameters...
1435 .map(|(i, def)| tcx.mk_param(TypeSpace,
1436 i as u32, def.name))
1439 // ...and also create the `Self` parameter.
1440 let self_ty = tcx.mk_self_type();
1442 Substs::new_trait(types, regions, self_ty)
1446 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1447 trait_node_id: ast::NodeId,
1448 assoc_name: ast::Name)
1451 let item = match ccx.tcx.map.get(trait_node_id) {
1452 hir_map::NodeItem(item) => item,
1453 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1456 let trait_items = match item.node {
1457 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1458 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1461 trait_items.iter().any(|trait_item| {
1462 match trait_item.node {
1463 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1469 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1471 let trait_def = trait_def_of_item(ccx, it);
1473 let def_id = ccx.tcx.map.local_def_id(it.id);
1475 let (generics, items) = match it.node {
1476 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1480 &format!("trait_def_of_item invoked on {:?}", s));
1484 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1486 // `ty_generic_predicates` below will consider the bounds on the type
1487 // parameters (including `Self`) and the explicit where-clauses,
1488 // but to get the full set of predicates on a trait we need to add
1489 // in the supertrait bounds and anything declared on the
1490 // associated types.
1491 let mut base_predicates = super_predicates;
1493 // Add in a predicate that `Self:Trait` (where `Trait` is the
1494 // current trait). This is needed for builtin bounds.
1495 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1496 base_predicates.predicates.push(SelfSpace, self_predicate);
1498 // add in the explicit where-clauses
1499 let mut trait_predicates =
1500 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1502 let assoc_predicates = predicates_for_associated_types(ccx,
1505 trait_def.trait_ref,
1507 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1509 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1510 assert!(prev_predicates.is_none());
1514 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1515 ast_generics: &hir::Generics,
1516 trait_predicates: &ty::GenericPredicates<'tcx>,
1517 self_trait_ref: ty::TraitRef<'tcx>,
1518 trait_items: &[P<hir::TraitItem>])
1519 -> Vec<ty::Predicate<'tcx>>
1521 trait_items.iter().flat_map(|trait_item| {
1522 let bounds = match trait_item.node {
1523 hir::TypeTraitItem(ref bounds, _) => bounds,
1525 return vec!().into_iter();
1529 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1532 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1535 SizedByDefault::Yes,
1538 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1543 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1545 -> ty::TypeScheme<'tcx>
1547 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1548 match ccx.tcx.map.find(node_id) {
1549 Some(hir_map::NodeItem(item)) => {
1550 type_scheme_of_item(ccx, &*item)
1552 Some(hir_map::NodeForeignItem(foreign_item)) => {
1553 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1554 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1557 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1558 in get_item_type_scheme(): {:?}",
1563 ccx.tcx.lookup_item_type(def_id)
1567 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1569 -> ty::TypeScheme<'tcx>
1571 memoized(&ccx.tcx.tcache,
1572 ccx.tcx.map.local_def_id(it.id),
1573 |_| compute_type_scheme_of_item(ccx, it))
1576 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1578 -> ty::TypeScheme<'tcx>
1582 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1583 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1584 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1586 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1587 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1588 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1589 let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1590 ty::TypeScheme { ty: ty, generics: ty_generics }
1592 hir::ItemTy(ref t, ref generics) => {
1593 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1594 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1595 ty::TypeScheme { ty: ty, generics: ty_generics }
1597 hir::ItemEnum(ref ei, ref generics) => {
1598 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1599 let substs = mk_item_substs(ccx, &ty_generics);
1600 let def = convert_enum_def(tcx, it, ei);
1601 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1602 ty::TypeScheme { ty: t, generics: ty_generics }
1604 hir::ItemStruct(ref si, ref generics) => {
1605 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1606 let substs = mk_item_substs(ccx, &ty_generics);
1607 let def = convert_struct_def(tcx, it, si);
1608 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1609 ty::TypeScheme { ty: t, generics: ty_generics }
1611 hir::ItemDefaultImpl(..) |
1612 hir::ItemTrait(..) |
1615 hir::ItemForeignMod(..) |
1616 hir::ItemExternCrate(..) |
1617 hir::ItemUse(..) => {
1620 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1626 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1628 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1632 let tag = type_scheme_of_item(ccx, it);
1633 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1634 let predicates = match it.node {
1635 hir::ItemStatic(..) | hir::ItemConst(..) => {
1636 ty::GenericPredicates::empty()
1638 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1639 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1641 hir::ItemTy(_, ref generics) => {
1642 ty_generic_predicates_for_type_or_impl(ccx, generics)
1644 hir::ItemEnum(_, ref generics) => {
1645 ty_generic_predicates_for_type_or_impl(ccx, generics)
1647 hir::ItemStruct(_, ref generics) => {
1648 ty_generic_predicates_for_type_or_impl(ccx, generics)
1650 hir::ItemDefaultImpl(..) |
1651 hir::ItemTrait(..) |
1652 hir::ItemExternCrate(..) |
1656 hir::ItemForeignMod(..) => {
1659 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1664 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1665 predicates.clone());
1666 assert!(prev_predicates.is_none());
1669 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1670 let object_lifetime_default_reprs: String =
1671 scheme.generics.types.iter()
1672 .map(|t| match t.object_lifetime_default {
1673 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1674 d => format!("{:?}", d),
1676 .collect::<Vec<String>>()
1679 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1682 return (scheme, predicates);
1685 fn type_scheme_of_foreign_item<'a, 'tcx>(
1686 ccx: &CrateCtxt<'a, 'tcx>,
1687 it: &hir::ForeignItem,
1689 -> ty::TypeScheme<'tcx>
1691 memoized(&ccx.tcx.tcache,
1692 ccx.tcx.map.local_def_id(it.id),
1693 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1696 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1697 ccx: &CrateCtxt<'a, 'tcx>,
1698 it: &hir::ForeignItem,
1700 -> ty::TypeScheme<'tcx>
1703 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1704 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1706 hir::ForeignItemStatic(ref t, _) => {
1708 generics: ty::Generics::empty(),
1709 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1715 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1716 it: &hir::ForeignItem)
1718 // For reasons I cannot fully articulate, I do so hate the AST
1719 // map, and I regard each time that I use it as a personal and
1720 // moral failing, but at the moment it seems like the only
1721 // convenient way to extract the ABI. - ndm
1723 let abi = tcx.map.get_foreign_abi(it.id);
1725 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1726 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1728 let predicates = match it.node {
1729 hir::ForeignItemFn(_, ref generics) => {
1730 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1732 hir::ForeignItemStatic(..) => {
1733 ty::GenericPredicates::empty()
1737 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1739 assert!(prev_predicates.is_none());
1742 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1743 generics: &hir::Generics)
1744 -> ty::Generics<'tcx> {
1745 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1748 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1749 generics: &hir::Generics)
1750 -> ty::GenericPredicates<'tcx>
1752 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1755 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1756 trait_id: ast::NodeId,
1757 substs: &'tcx Substs<'tcx>,
1758 ast_generics: &hir::Generics)
1759 -> ty::Generics<'tcx>
1761 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1762 ccx.tcx.map.local_def_id(trait_id), substs);
1764 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1766 // Add in the self type parameter.
1768 // Something of a hack: use the node id for the trait, also as
1769 // the node id for the Self type parameter.
1770 let param_id = trait_id;
1772 let parent = ccx.tcx.map.get_parent(param_id);
1774 let def = ty::TypeParameterDef {
1777 name: special_idents::type_self.name,
1778 def_id: ccx.tcx.map.local_def_id(param_id),
1779 default_def_id: ccx.tcx.map.local_def_id(parent),
1781 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1784 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1786 generics.types.push(SelfSpace, def);
1791 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1792 generics: &hir::Generics,
1793 base_generics: &ty::Generics<'tcx>)
1794 -> ty::Generics<'tcx>
1796 ty_generics(ccx, FnSpace, generics, base_generics)
1799 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1800 generics: &hir::Generics,
1801 base_predicates: &ty::GenericPredicates<'tcx>)
1802 -> ty::GenericPredicates<'tcx>
1804 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1807 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1808 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1809 bounds: &mut ty::BuiltinBounds,
1810 ast_bounds: &[hir::TyParamBound],
1813 let tcx = astconv.tcx();
1815 // Try to find an unbound in bounds.
1816 let mut unbound = None;
1817 for ab in ast_bounds {
1818 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1819 if unbound.is_none() {
1820 assert!(ptr.bound_lifetimes.is_empty());
1821 unbound = Some(ptr.trait_ref.clone());
1823 span_err!(tcx.sess, span, E0203,
1824 "type parameter has more than one relaxed default \
1825 bound, only one is supported");
1830 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1833 // FIXME(#8559) currently requires the unbound to be built-in.
1834 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1836 Ok(kind_id) if trait_def_id != kind_id => {
1837 tcx.sess.span_warn(span,
1838 "default bound relaxed for a type parameter, but \
1839 this does nothing because the given bound is not \
1840 a default. Only `?Sized` is supported");
1841 tcx.try_add_builtin_trait(kind_id, bounds);
1846 _ if kind_id.is_ok() => {
1847 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1849 // No lang item for Sized, so we can't add it as a bound.
1854 /// Returns the early-bound lifetimes declared in this generics
1855 /// listing. For anything other than fns/methods, this is just all
1856 /// the lifetimes that are declared. For fns or methods, we have to
1857 /// screen out those that do not appear in any where-clauses etc using
1858 /// `resolve_lifetime::early_bound_lifetimes`.
1859 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1860 ast_generics: &hir::Generics)
1861 -> Vec<hir::LifetimeDef>
1864 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1865 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1869 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1871 ast_generics: &hir::Generics,
1872 base_predicates: &ty::GenericPredicates<'tcx>)
1873 -> ty::GenericPredicates<'tcx>
1876 let mut result = base_predicates.clone();
1878 // Collect the predicates that were written inline by the user on each
1879 // type parameter (e.g., `<T:Foo>`).
1880 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1881 let index = index as u32;
1882 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1883 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1886 SizedByDefault::Yes,
1888 let predicates = bounds.predicates(ccx.tcx, param_ty);
1889 result.predicates.extend(space, predicates.into_iter());
1892 // Collect the region predicates that were declared inline as
1893 // well. In the case of parameters declared on a fn or method, we
1894 // have to be careful to only iterate over early-bound regions.
1895 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1896 for (index, param) in early_lifetimes.iter().enumerate() {
1897 let index = index as u32;
1898 let def_id = tcx.map.local_def_id(param.lifetime.id);
1900 ty::ReEarlyBound(ty::EarlyBoundRegion {
1904 name: param.lifetime.name
1906 for bound in ¶m.bounds {
1907 let bound_region = ast_region_to_region(ccx.tcx, bound);
1908 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1909 result.predicates.push(space, outlives.to_predicate());
1913 // Add in the bounds that appear in the where-clause
1914 let where_clause = &ast_generics.where_clause;
1915 for predicate in &where_clause.predicates {
1917 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1918 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1920 &*bound_pred.bounded_ty);
1922 for bound in bound_pred.bounds.iter() {
1924 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1925 let mut projections = Vec::new();
1928 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1933 result.predicates.push(space, trait_ref.to_predicate());
1935 for projection in &projections {
1936 result.predicates.push(space, projection.to_predicate());
1940 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1941 let region = ast_region_to_region(tcx, lifetime);
1942 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1943 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1949 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1950 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1951 for bound in ®ion_pred.bounds {
1952 let r2 = ast_region_to_region(tcx, bound);
1953 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1954 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1958 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1960 tcx.sess.span_bug(eq_pred.span,
1961 "Equality constraints are not yet \
1962 implemented (#20041)")
1970 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1972 ast_generics: &hir::Generics,
1973 base_generics: &ty::Generics<'tcx>)
1974 -> ty::Generics<'tcx>
1977 let mut result = base_generics.clone();
1979 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1980 for (i, l) in early_lifetimes.iter().enumerate() {
1981 let bounds = l.bounds.iter()
1982 .map(|l| ast_region_to_region(tcx, l))
1984 let def = ty::RegionParameterDef { name: l.lifetime.name,
1987 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1989 result.regions.push(space, def);
1992 assert!(result.types.is_empty_in(space));
1994 // Now create the real type parameters.
1995 for i in 0..ast_generics.ty_params.len() {
1996 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1997 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1998 result.types.push(space, def);
2004 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2010 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
2012 for leaf_ty in ty.walk() {
2013 if let ty::TyParam(p) = leaf_ty.sty {
2014 if p.space == space && p.idx >= index {
2015 span_err!(ccx.tcx.sess, path.span, E0128,
2016 "type parameters with a default cannot use \
2017 forward declared identifiers");
2019 return ccx.tcx.types.err
2027 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2028 ast_generics: &hir::Generics,
2031 -> ty::TypeParameterDef<'tcx>
2033 let param = &ast_generics.ty_params[index as usize];
2036 match tcx.ty_param_defs.borrow().get(¶m.id) {
2037 Some(d) => { return d.clone(); }
2041 let default = param.default.as_ref().map(
2042 |def| convert_default_type_parameter(ccx, def, space, index)
2045 let object_lifetime_default =
2046 compute_object_lifetime_default(ccx, param.id,
2047 ¶m.bounds, &ast_generics.where_clause);
2049 let parent = tcx.map.get_parent(param.id);
2051 let def = ty::TypeParameterDef {
2055 def_id: ccx.tcx.map.local_def_id(param.id),
2056 default_def_id: ccx.tcx.map.local_def_id(parent),
2058 object_lifetime_default: object_lifetime_default,
2061 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2066 /// Scan the bounds and where-clauses on a parameter to extract bounds
2067 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2068 /// This runs as part of computing the minimal type scheme, so we
2069 /// intentionally avoid just asking astconv to convert all the where
2070 /// clauses into a `ty::Predicate`. This is because that could induce
2071 /// artificial cycles.
2072 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2073 param_id: ast::NodeId,
2074 param_bounds: &[hir::TyParamBound],
2075 where_clause: &hir::WhereClause)
2076 -> ty::ObjectLifetimeDefault
2078 let inline_bounds = from_bounds(ccx, param_bounds);
2079 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2080 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2081 .chain(where_bounds)
2083 return if all_bounds.len() > 1 {
2084 ty::ObjectLifetimeDefault::Ambiguous
2085 } else if all_bounds.len() == 0 {
2086 ty::ObjectLifetimeDefault::BaseDefault
2088 ty::ObjectLifetimeDefault::Specific(
2089 all_bounds.into_iter().next().unwrap())
2092 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2093 bounds: &[hir::TyParamBound])
2097 .filter_map(|bound| {
2099 hir::TraitTyParamBound(..) =>
2101 hir::RegionTyParamBound(ref lifetime) =>
2102 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2108 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2109 param_id: ast::NodeId,
2110 predicates: &[hir::WherePredicate])
2114 .flat_map(|predicate| {
2116 hir::WherePredicate::BoundPredicate(ref data) => {
2117 if data.bound_lifetimes.is_empty() &&
2118 is_param(ccx.tcx, &data.bounded_ty, param_id)
2120 from_bounds(ccx, &data.bounds).into_iter()
2122 Vec::new().into_iter()
2125 hir::WherePredicate::RegionPredicate(..) |
2126 hir::WherePredicate::EqPredicate(..) => {
2127 Vec::new().into_iter()
2135 enum SizedByDefault { Yes, No, }
2137 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2138 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2139 /// built-in trait (formerly known as kind): Send.
2140 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2141 param_ty: ty::Ty<'tcx>,
2142 ast_bounds: &[hir::TyParamBound],
2143 sized_by_default: SizedByDefault,
2145 -> astconv::Bounds<'tcx>
2148 conv_param_bounds(astconv,
2153 if let SizedByDefault::Yes = sized_by_default {
2154 add_unsized_bound(astconv,
2155 &mut bounds.builtin_bounds,
2160 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2165 /// Converts a specific TyParamBound from the AST into a set of
2166 /// predicates that apply to the self-type. A vector is returned
2167 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2168 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2169 /// and `<T as Bar>::X == i32`).
2170 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2172 bound: &hir::TyParamBound)
2173 -> Vec<ty::Predicate<'tcx>>
2176 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2177 let mut projections = Vec::new();
2178 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2179 projections.into_iter()
2180 .map(|p| p.to_predicate())
2181 .chain(Some(pred.to_predicate()))
2184 hir::RegionTyParamBound(ref lifetime) => {
2185 let region = ast_region_to_region(astconv.tcx(), lifetime);
2186 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2187 vec![ty::Predicate::TypeOutlives(pred)]
2189 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2195 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2197 trait_ref: &hir::PolyTraitRef,
2198 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2199 -> ty::PolyTraitRef<'tcx>
2201 astconv::instantiate_poly_trait_ref(astconv,
2208 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2210 param_ty: ty::Ty<'tcx>,
2211 ast_bounds: &[hir::TyParamBound])
2212 -> astconv::Bounds<'tcx>
2214 let tcx = astconv.tcx();
2215 let astconv::PartitionedBounds {
2219 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2221 let mut projection_bounds = Vec::new();
2223 let trait_bounds: Vec<ty::PolyTraitRef> =
2225 .map(|bound| conv_poly_trait_ref(astconv,
2228 &mut projection_bounds))
2231 let region_bounds: Vec<ty::Region> =
2232 region_bounds.into_iter()
2233 .map(|r| ast_region_to_region(tcx, r))
2237 region_bounds: region_bounds,
2238 builtin_bounds: builtin_bounds,
2239 trait_bounds: trait_bounds,
2240 projection_bounds: projection_bounds,
2244 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2245 ccx: &CrateCtxt<'a, 'tcx>,
2247 ast_generics: &hir::Generics,
2249 -> ty::TypeScheme<'tcx>
2251 for i in &decl.inputs {
2252 match (*i).pat.node {
2253 hir::PatIdent(_, _, _) => (),
2254 hir::PatWild(hir::PatWildSingle) => (),
2256 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2257 "patterns aren't allowed in foreign function declarations");
2262 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2264 let rb = BindingRscope::new();
2265 let input_tys = decl.inputs
2267 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2270 let output = match decl.output {
2271 hir::Return(ref ty) =>
2272 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2273 hir::DefaultReturn(..) =>
2274 ty::FnConverging(ccx.tcx.mk_nil()),
2275 hir::NoReturn(..) =>
2279 let t_fn = ccx.tcx.mk_fn(None,
2280 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2282 unsafety: hir::Unsafety::Unsafe,
2283 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2285 variadic: decl.variadic}),
2289 generics: ty_generics,
2294 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2295 ty_generics: &ty::Generics<'tcx>)
2299 ty_generics.types.map(
2300 |def| ccx.tcx.mk_param_from_def(def));
2303 ty_generics.regions.map(
2304 |def| def.to_early_bound_region());
2306 Substs::new(types, regions)
2309 /// Verifies that the explicit self type of a method matches the impl
2310 /// or trait. This is a bit weird but basically because right now we
2311 /// don't handle the general case, but instead map it to one of
2312 /// several pre-defined options using various heuristics, this method
2313 /// comes back to check after the fact that explicit type the user
2314 /// wrote actually matches what the pre-defined option said.
2315 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2316 ccx: &CrateCtxt<'a, 'tcx>,
2318 method_type: Rc<ty::Method<'tcx>>,
2319 required_type: Ty<'tcx>,
2320 explicit_self: &hir::ExplicitSelf,
2321 body_id: ast::NodeId)
2324 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2325 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2326 let base_type = match typ.sty {
2327 ty::TyRef(_, tm) => tm.ty,
2328 ty::TyBox(typ) => typ,
2332 let body_scope = tcx.region_maps.item_extent(body_id);
2334 // "Required type" comes from the trait definition. It may
2335 // contain late-bound regions from the method, but not the
2336 // trait (since traits only have early-bound region
2338 assert!(!base_type.has_regions_escaping_depth(1));
2339 let required_type_free =
2340 liberate_early_bound_regions(
2342 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2344 // The "base type" comes from the impl. It too may have late-bound
2345 // regions from the method.
2346 assert!(!base_type.has_regions_escaping_depth(1));
2347 let base_type_free =
2348 liberate_early_bound_regions(
2350 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2352 debug!("required_type={:?} required_type_free={:?} \
2353 base_type={:?} base_type_free={:?}",
2359 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2360 drop(::require_same_types(tcx,
2367 format!("mismatched self type: expected `{}`",
2371 // We could conceviably add more free-region relations here,
2372 // but since this code is just concerned with checking that
2373 // the `&Self` types etc match up, it's not really necessary.
2374 // It would just allow people to be more approximate in some
2375 // cases. In any case, we can do it later as we feel the need;
2376 // I'd like this function to go away eventually.
2377 let free_regions = FreeRegionMap::new();
2379 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2382 fn liberate_early_bound_regions<'tcx,T>(
2383 tcx: &ty::ctxt<'tcx>,
2384 scope: region::CodeExtent,
2387 where T : TypeFoldable<'tcx>
2390 * Convert early-bound regions into free regions; normally this is done by
2391 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2392 * method-self-type check is kind of hacky and done very early in the process,
2393 * before we really have a `ParameterEnvironment` to check.
2396 tcx.fold_regions(value, &mut false, |region, _| {
2398 ty::ReEarlyBound(data) => {
2399 ty::ReFree(ty::FreeRegion {
2401 bound_region: ty::BrNamed(data.def_id, data.name)
2410 /// Checks that all the type parameters on an impl
2411 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2412 ast_generics: &hir::Generics,
2414 impl_items: &[P<hir::ImplItem>])
2416 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2417 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2418 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2420 // The trait reference is an input, so find all type parameters
2421 // reachable from there, to start (if this is an inherent impl,
2422 // then just examine the self type).
2423 let mut input_parameters: HashSet<_> =
2424 ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2425 if let Some(ref trait_ref) = impl_trait_ref {
2426 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2429 ctp::identify_constrained_type_params(tcx,
2430 impl_predicates.predicates.as_slice(),
2432 &mut input_parameters);
2434 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2435 let param_ty = ty::ParamTy { space: TypeSpace,
2437 name: ty_param.name };
2438 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2439 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2443 // Every lifetime used in an associated type must be constrained.
2445 let lifetimes_in_associated_types: HashSet<_> =
2447 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2448 .filter_map(|item| match item {
2449 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2450 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2452 .flat_map(|ty| ctp::parameters_for_type(ty))
2453 .filter_map(|p| match p {
2454 ctp::Parameter::Type(_) => None,
2455 ctp::Parameter::Region(r) => Some(r),
2459 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2460 let def_id = tcx.map.local_def_id(lifetime_def.lifetime.id);
2461 let region = ty::EarlyBoundRegion { def_id: def_id,
2463 index: index as u32,
2464 name: lifetime_def.lifetime.name };
2466 lifetimes_in_associated_types.contains(®ion) && // (*)
2467 !input_parameters.contains(&ctp::Parameter::Region(region))
2469 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2470 "lifetime", ®ion.name.to_string());
2474 // (*) This is a horrible concession to reality. I think it'd be
2475 // better to just ban unconstrianed lifetimes outright, but in
2476 // practice people do non-hygenic macros like:
2479 // macro_rules! __impl_slice_eq1 {
2480 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2481 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2488 // In a concession to backwards compatbility, we continue to
2489 // permit those, so long as the lifetimes aren't used in
2490 // associated types. I believe this is sound, because lifetimes
2491 // used elsewhere are not projected back out.
2494 fn report_unused_parameter(tcx: &ty::ctxt,
2499 span_err!(tcx.sess, span, E0207,
2500 "the {} parameter `{}` is not constrained by the \
2501 impl trait, self type, or predicates",