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,
605 let fty = ccx.tcx.mk_fn(Some(def_id),
606 ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
607 debug!("method {} (id {}) has type {:?}",
609 ccx.tcx.register_item_type(def_id, TypeScheme {
610 generics: ty_method.generics.clone(),
613 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
615 write_ty_to_tcx(ccx.tcx, id, fty);
617 debug!("writing method type: def_id={:?} mty={:?}",
620 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
621 ty::MethodTraitItem(Rc::new(ty_method)));
624 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
625 struct_generics: &ty::Generics<'tcx>,
626 struct_predicates: &ty::GenericPredicates<'tcx>,
627 v: &hir::StructField,
628 ty_f: ty::FieldDefMaster<'tcx>)
630 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
632 write_ty_to_tcx(ccx.tcx, v.node.id, tt);
634 /* add the field to the tcache */
635 ccx.tcx.register_item_type(DefId::local(v.node.id),
637 generics: struct_generics.clone(),
640 ccx.tcx.predicates.borrow_mut().insert(DefId::local(v.node.id),
641 struct_predicates.clone());
644 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
645 container: ImplOrTraitItemContainer,
648 vis: hir::Visibility,
650 default: Option<&hir::Expr>)
652 ccx.tcx.predicates.borrow_mut().insert(DefId::local(id),
653 ty::GenericPredicates::empty());
655 write_ty_to_tcx(ccx.tcx, id, ty);
656 let default_id = default.map(|expr| DefId::local(expr.id));
658 let associated_const = Rc::new(ty::AssociatedConst {
661 def_id: DefId::local(id),
662 container: container,
666 ccx.tcx.impl_or_trait_items.borrow_mut()
667 .insert(DefId::local(id), ty::ConstTraitItem(associated_const));
670 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
671 container: ImplOrTraitItemContainer,
674 vis: hir::Visibility,
675 ty: Option<Ty<'tcx>>)
677 let associated_type = Rc::new(ty::AssociatedType {
681 def_id: DefId::local(id),
684 ccx.tcx.impl_or_trait_items.borrow_mut()
685 .insert(DefId::local(id), ty::TypeTraitItem(associated_type));
688 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
689 container: ImplOrTraitItemContainer,
691 untransformed_rcvr_ty: Ty<'tcx>,
692 rcvr_ty_generics: &ty::Generics<'tcx>,
693 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
694 where I: Iterator<Item=(&'i hir::MethodSig, ast::NodeId, ast::Name, hir::Visibility, Span)>
696 debug!("convert_methods(untransformed_rcvr_ty={:?}, rcvr_ty_generics={:?}, \
697 rcvr_ty_predicates={:?})",
698 untransformed_rcvr_ty,
702 for (sig, id, name, vis, _span) in methods {
709 untransformed_rcvr_ty,
715 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
717 generics: &hir::Generics,
718 thing: &'static str) {
719 let mut warn = false;
721 for ty_param in generics.ty_params.iter() {
722 for bound in ty_param.bounds.iter() {
724 hir::TraitTyParamBound(..) => {
727 hir::RegionTyParamBound(..) => { }
733 // According to accepted RFC #XXX, we should
734 // eventually accept these, but it will not be
735 // part of this PR. Still, convert to warning to
736 // make bootstrapping easier.
737 span_warn!(ccx.tcx.sess, span, E0122,
738 "trait bounds are not (yet) enforced \
744 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
746 debug!("convert: item {} with id {}", it.name, it.id);
748 // These don't define types.
749 hir::ItemExternCrate(_) | hir::ItemUse(_) |
750 hir::ItemForeignMod(_) | hir::ItemMod(_) => {
752 hir::ItemEnum(ref enum_definition, _) => {
753 let (scheme, predicates) = convert_typed_item(ccx, it);
754 write_ty_to_tcx(tcx, it.id, scheme.ty);
755 convert_enum_variant_types(ccx,
756 tcx.lookup_adt_def_master(DefId::local(it.id)),
759 &enum_definition.variants);
761 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
763 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
768 tcx.record_trait_has_default_impl(trait_ref.def_id);
770 tcx.impl_trait_refs.borrow_mut().insert(DefId::local(it.id), Some(trait_ref));
777 // Create generics from the generics specified in the impl head.
778 debug!("convert: ast_generics={:?}", generics);
779 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
780 let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
782 debug!("convert: impl_bounds={:?}", ty_predicates);
784 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
785 write_ty_to_tcx(tcx, it.id, selfty);
787 tcx.register_item_type(DefId::local(it.id),
788 TypeScheme { generics: ty_generics.clone(),
790 tcx.predicates.borrow_mut().insert(DefId::local(it.id),
791 ty_predicates.clone());
792 if let &Some(ref ast_trait_ref) = opt_trait_ref {
793 tcx.impl_trait_refs.borrow_mut().insert(
795 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
801 tcx.impl_trait_refs.borrow_mut().insert(DefId::local(it.id), None);
805 // If there is a trait reference, treat the methods as always public.
806 // This is to work around some incorrect behavior in privacy checking:
807 // when the method belongs to a trait, it should acquire the privacy
808 // from the trait, not the impl. Forcing the visibility to be public
809 // makes things sorta work.
810 let parent_visibility = if opt_trait_ref.is_some() {
816 // Convert all the associated consts.
817 // Also, check if there are any duplicate associated items
818 let mut seen_type_items = FnvHashSet();
819 let mut seen_value_items = FnvHashSet();
821 for impl_item in impl_items {
822 let seen_items = match impl_item.node {
823 hir::TypeImplItem(_) => &mut seen_type_items,
824 _ => &mut seen_value_items,
826 if !seen_items.insert(impl_item.name) {
827 let desc = match impl_item.node {
828 hir::ConstImplItem(_, _) => "associated constant",
829 hir::TypeImplItem(_) => "associated type",
830 hir::MethodImplItem(ref sig, _) =>
831 match sig.explicit_self.node {
832 hir::SelfStatic => "associated function",
837 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
840 if let hir::ConstImplItem(ref ty, ref expr) = impl_item.node {
841 let ty = ccx.icx(&ty_predicates)
842 .to_ty(&ExplicitRscope, &*ty);
843 tcx.register_item_type(DefId::local(impl_item.id),
845 generics: ty_generics.clone(),
848 convert_associated_const(ccx, ImplContainer(DefId::local(it.id)),
849 impl_item.name, impl_item.id,
850 impl_item.vis.inherit_from(parent_visibility),
855 // Convert all the associated types.
856 for impl_item in impl_items {
857 if let hir::TypeImplItem(ref ty) = impl_item.node {
858 if opt_trait_ref.is_none() {
859 span_err!(tcx.sess, impl_item.span, E0202,
860 "associated types are not allowed in inherent impls");
863 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
865 convert_associated_type(ccx, ImplContainer(DefId::local(it.id)),
866 impl_item.name, impl_item.id, impl_item.vis,
871 let methods = impl_items.iter().filter_map(|ii| {
872 if let hir::MethodImplItem(ref sig, _) = ii.node {
873 // if the method specifies a visibility, use that, otherwise
874 // inherit the visibility from the impl (so `foo` in `pub impl
875 // { fn foo(); }` is public, but private in `impl { fn
877 let method_vis = ii.vis.inherit_from(parent_visibility);
878 Some((sig, ii.id, ii.name, method_vis, ii.span))
884 ImplContainer(DefId::local(it.id)),
890 for impl_item in impl_items {
891 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
892 let body_id = body.id;
893 check_method_self_type(ccx,
894 &BindingRscope::new(),
895 ccx.method_ty(impl_item.id),
902 enforce_impl_params_are_constrained(tcx,
907 hir::ItemTrait(_, _, _, ref trait_items) => {
908 let trait_def = trait_def_of_item(ccx, it);
909 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
910 ccx.ensure_super_predicates(it.span, DefId::local(it.id));
911 convert_trait_predicates(ccx, it);
912 let trait_predicates = tcx.lookup_predicates(DefId::local(it.id));
914 debug!("convert: trait_bounds={:?}", trait_predicates);
916 // Convert all the associated types.
917 for trait_item in trait_items {
918 match trait_item.node {
919 hir::ConstTraitItem(ref ty, ref default) => {
920 let ty = ccx.icx(&trait_predicates)
921 .to_ty(&ExplicitRscope, ty);
922 tcx.register_item_type(DefId::local(trait_item.id),
924 generics: trait_def.generics.clone(),
927 convert_associated_const(ccx, TraitContainer(DefId::local(it.id)),
928 trait_item.name, trait_item.id,
929 hir::Public, ty, default.as_ref().map(|d| &**d));
935 // Convert all the associated types.
936 for trait_item in trait_items {
937 match trait_item.node {
938 hir::TypeTraitItem(_, ref opt_ty) => {
939 let typ = opt_ty.as_ref().map({
940 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
943 convert_associated_type(ccx, TraitContainer(DefId::local(it.id)),
944 trait_item.name, trait_item.id, hir::Public,
951 let methods = trait_items.iter().filter_map(|ti| {
952 let sig = match ti.node {
953 hir::MethodTraitItem(ref sig, _) => sig,
956 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
959 // Run convert_methods on the trait methods.
961 TraitContainer(DefId::local(it.id)),
967 // Add an entry mapping
968 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
969 let def_id = DefId::local(trait_item.id);
970 match trait_item.node {
971 hir::ConstTraitItem(..) => {
972 ty::ConstTraitItemId(def_id)
974 hir::MethodTraitItem(..) => {
975 ty::MethodTraitItemId(def_id)
977 hir::TypeTraitItem(..) => {
978 ty::TypeTraitItemId(def_id)
982 tcx.trait_item_def_ids.borrow_mut().insert(DefId::local(it.id), trait_item_def_ids);
984 // This must be done after `collect_trait_methods` so that
985 // we have a method type stored for every method.
986 for trait_item in trait_items {
987 let sig = match trait_item.node {
988 hir::MethodTraitItem(ref sig, _) => sig,
991 check_method_self_type(ccx,
992 &BindingRscope::new(),
993 ccx.method_ty(trait_item.id),
999 hir::ItemStruct(ref struct_def, _) => {
1000 let (scheme, predicates) = convert_typed_item(ccx, it);
1001 write_ty_to_tcx(tcx, it.id, scheme.ty);
1003 let variant = tcx.lookup_adt_def_master(DefId::local(it.id)).struct_variant();
1005 for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
1006 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1009 if let Some(ctor_id) = struct_def.ctor_id {
1010 convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
1013 hir::ItemTy(_, ref generics) => {
1014 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1015 let (scheme, _) = convert_typed_item(ccx, it);
1016 write_ty_to_tcx(tcx, it.id, scheme.ty);
1019 // This call populates the type cache with the converted type
1020 // of the item in passing. All we have to do here is to write
1021 // it into the node type table.
1022 let (scheme, _) = convert_typed_item(ccx, it);
1023 write_ty_to_tcx(tcx, it.id, scheme.ty);
1028 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1029 ctor_id: ast::NodeId,
1030 variant: ty::VariantDef<'tcx>,
1031 scheme: ty::TypeScheme<'tcx>,
1032 predicates: ty::GenericPredicates<'tcx>) {
1033 let ctor_ty = match variant.kind() {
1034 VariantKind::Unit | VariantKind::Dict => scheme.ty,
1035 VariantKind::Tuple => {
1036 let inputs: Vec<_> =
1039 .map(|field| field.unsubst_ty())
1041 tcx.mk_ctor_fn(DefId::local(ctor_id),
1046 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1047 tcx.predicates.borrow_mut().insert(DefId::local(ctor_id), predicates);
1048 tcx.register_item_type(DefId::local(ctor_id),
1050 generics: scheme.generics,
1055 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1056 def: ty::AdtDefMaster<'tcx>,
1057 scheme: ty::TypeScheme<'tcx>,
1058 predicates: ty::GenericPredicates<'tcx>,
1059 variants: &[P<hir::Variant>]) {
1061 let icx = ccx.icx(&predicates);
1063 // fill the field types
1064 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1065 match variant.node.kind {
1066 hir::TupleVariantKind(ref args) => {
1067 let rs = ExplicitRscope;
1068 let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
1069 for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
1070 field.fulfill_ty(ty);
1074 hir::StructVariantKind(ref struct_def) => {
1075 for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
1076 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1081 // Convert the ctor, if any. This also registers the variant as
1083 convert_variant_ctor(
1093 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1097 def: &hir::StructDef) -> ty::VariantDefData<'tcx, 'tcx> {
1098 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1099 let fields = def.fields.iter().map(|f| {
1100 let fid = DefId::local(f.node.id);
1102 hir::NamedField(name, vis) => {
1103 let dup_span = seen_fields.get(&name).cloned();
1104 if let Some(prev_span) = dup_span {
1105 span_err!(tcx.sess, f.span, E0124,
1106 "field `{}` is already declared",
1108 span_note!(tcx.sess, prev_span, "previously declared here");
1110 seen_fields.insert(name, f.span);
1113 ty::FieldDefData::new(fid, name, vis)
1115 hir::UnnamedField(vis) => {
1116 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1120 ty::VariantDefData {
1128 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1130 def: &hir::StructDef)
1131 -> ty::AdtDefMaster<'tcx>
1134 let did = DefId::local(it.id);
1137 ty::AdtKind::Struct,
1138 vec![convert_struct_variant(tcx, did, it.name, 0, def)]
1142 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1145 -> ty::AdtDefMaster<'tcx>
1147 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1149 e: &hir::Expr) -> Option<ty::Disr> {
1150 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1152 let hint = UncheckedExprHint(repr_ty);
1153 match const_eval::eval_const_expr_partial(tcx, e, hint) {
1154 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1155 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1157 let sign_desc = if repr_ty.is_signed() {
1162 span_err!(tcx.sess, e.span, E0079,
1163 "expected {} integer constant",
1168 span_err!(tcx.sess, err.span, E0080,
1169 "constant evaluation error: {}",
1176 fn report_discrim_overflow(tcx: &ty::ctxt,
1179 repr_type: attr::IntType,
1180 prev_val: ty::Disr) {
1181 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1182 let computed_value = repr_type.disr_string(computed_value);
1183 let prev_val = repr_type.disr_string(prev_val);
1184 let repr_type = repr_type.to_ty(tcx);
1185 span_err!(tcx.sess, variant_span, E0370,
1186 "enum discriminant overflowed on value after {}: {}; \
1187 set explicitly via {} = {} if that is desired outcome",
1188 prev_val, repr_type, variant_name, computed_value);
1191 fn next_disr(tcx: &ty::ctxt,
1193 repr_type: attr::IntType,
1194 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1195 if let Some(prev_disr_val) = prev_disr_val {
1196 let result = repr_type.disr_incr(prev_disr_val);
1197 if let None = result {
1198 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1199 repr_type, prev_disr_val);
1203 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1206 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1209 -> ty::VariantDefData<'tcx, 'tcx>
1211 let did = DefId::local(v.node.id);
1212 let name = v.node.name;
1214 hir::TupleVariantKind(ref va) => {
1215 ty::VariantDefData {
1219 fields: va.iter().map(|&hir::VariantArg { id, .. }| {
1220 ty::FieldDefData::new(
1222 special_idents::unnamed_field.name,
1223 hir::Visibility::Public
1228 hir::StructVariantKind(ref def) => {
1229 convert_struct_variant(tcx, did, name, disr, &def)
1233 let did = DefId::local(it.id);
1234 let repr_hints = tcx.lookup_repr_hints(did);
1235 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1236 let mut prev_disr = None;
1237 let variants = def.variants.iter().map(|v| {
1238 let disr = match v.node.disr_expr {
1239 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1240 None => next_disr(tcx, v, repr_type, prev_disr)
1241 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1243 let v = convert_enum_variant(tcx, v, disr);
1244 prev_disr = Some(disr);
1247 tcx.intern_adt_def(DefId::local(it.id), ty::AdtKind::Enum, variants)
1250 /// Ensures that the super-predicates of the trait with def-id
1251 /// trait_def_id are converted and stored. This does NOT ensure that
1252 /// the transitive super-predicates are converted; that is the job of
1253 /// the `ensure_super_predicates()` method in the `AstConv` impl
1254 /// above. Returns a list of trait def-ids that must be ensured as
1255 /// well to guarantee that the transitive superpredicates are
1257 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1258 trait_def_id: DefId)
1263 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1265 if trait_def_id.krate != LOCAL_CRATE {
1266 // If this trait comes from an external crate, then all of the
1267 // supertraits it may depend on also must come from external
1268 // crates, and hence all of them already have their
1269 // super-predicates "converted" (and available from crate
1270 // meta-data), so there is no need to transitively test them.
1274 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1275 let superpredicates = superpredicates.unwrap_or_else(|| {
1276 let trait_node_id = trait_def_id.node;
1278 let item = match ccx.tcx.map.get(trait_node_id) {
1279 hir_map::NodeItem(item) => item,
1280 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1283 let (generics, bounds) = match item.node {
1284 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1285 _ => tcx.sess.span_bug(item.span,
1286 "ensure_super_predicates_step invoked on non-trait"),
1289 // In-scope when converting the superbounds for `Trait` are
1290 // that `Self:Trait` as well as any bounds that appear on the
1292 let trait_def = trait_def_of_item(ccx, item);
1293 let self_predicate = ty::GenericPredicates {
1294 predicates: VecPerParamSpace::new(vec![],
1295 vec![trait_def.trait_ref.to_predicate()],
1298 let scope = &(generics, &self_predicate);
1300 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1301 let self_param_ty = tcx.mk_self_type();
1302 let superbounds1 = compute_bounds(&ccx.icx(scope),
1308 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1310 // Convert any explicit superbounds in the where clause,
1311 // e.g. `trait Foo where Self : Bar`:
1312 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1314 // Combine the two lists to form the complete set of superbounds:
1315 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1316 let superpredicates = ty::GenericPredicates {
1317 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1319 debug!("superpredicates for trait {:?} = {:?}",
1320 DefId::local(item.id),
1323 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1328 let def_ids: Vec<_> = superpredicates.predicates
1330 .filter_map(|p| p.to_opt_poly_trait_ref())
1331 .map(|tr| tr.def_id())
1334 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1339 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1341 -> &'tcx ty::TraitDef<'tcx>
1343 let def_id = DefId::local(it.id);
1346 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1350 let (unsafety, generics, items) = match it.node {
1351 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1352 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1355 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1356 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1357 ccx.tcx.sess.span_err(
1359 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1360 which traits can use parenthetical notation");
1361 fileline_help!(ccx.tcx.sess, it.span,
1362 "add `#![feature(unboxed_closures)]` to \
1363 the crate attributes to use it");
1366 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1368 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1370 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1371 match trait_item.node {
1372 hir::TypeTraitItem(..) => Some(trait_item.name),
1377 let trait_ref = ty::TraitRef {
1382 let trait_def = ty::TraitDef {
1383 paren_sugar: paren_sugar,
1385 generics: ty_generics,
1386 trait_ref: trait_ref,
1387 associated_type_names: associated_type_names,
1388 nonblanket_impls: RefCell::new(FnvHashMap()),
1389 blanket_impls: RefCell::new(vec![]),
1390 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1393 return tcx.intern_trait_def(trait_def);
1395 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1396 generics: &hir::Generics)
1401 // Creates a no-op substitution for the trait's type parameters.
1406 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1407 param_id: def.lifetime.id,
1410 name: def.lifetime.name
1414 // Start with the generics in the type parameters...
1419 .map(|(i, def)| tcx.mk_param(TypeSpace,
1420 i as u32, def.name))
1423 // ...and also create the `Self` parameter.
1424 let self_ty = tcx.mk_self_type();
1426 Substs::new_trait(types, regions, self_ty)
1430 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1431 trait_node_id: ast::NodeId,
1432 assoc_name: ast::Name)
1435 let item = match ccx.tcx.map.get(trait_node_id) {
1436 hir_map::NodeItem(item) => item,
1437 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1440 let trait_items = match item.node {
1441 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1442 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1445 trait_items.iter().any(|trait_item| {
1446 match trait_item.node {
1447 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1453 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1455 let trait_def = trait_def_of_item(ccx, it);
1457 let def_id = DefId::local(it.id);
1459 let (generics, items) = match it.node {
1460 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1464 &format!("trait_def_of_item invoked on {:?}", s));
1468 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1470 // `ty_generic_predicates` below will consider the bounds on the type
1471 // parameters (including `Self`) and the explicit where-clauses,
1472 // but to get the full set of predicates on a trait we need to add
1473 // in the supertrait bounds and anything declared on the
1474 // associated types.
1475 let mut base_predicates = super_predicates;
1477 // Add in a predicate that `Self:Trait` (where `Trait` is the
1478 // current trait). This is needed for builtin bounds.
1479 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1480 base_predicates.predicates.push(SelfSpace, self_predicate);
1482 // add in the explicit where-clauses
1483 let mut trait_predicates =
1484 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1486 let assoc_predicates = predicates_for_associated_types(ccx,
1489 trait_def.trait_ref,
1491 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1493 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1494 assert!(prev_predicates.is_none());
1498 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1499 ast_generics: &hir::Generics,
1500 trait_predicates: &ty::GenericPredicates<'tcx>,
1501 self_trait_ref: ty::TraitRef<'tcx>,
1502 trait_items: &[P<hir::TraitItem>])
1503 -> Vec<ty::Predicate<'tcx>>
1505 trait_items.iter().flat_map(|trait_item| {
1506 let bounds = match trait_item.node {
1507 hir::TypeTraitItem(ref bounds, _) => bounds,
1509 return vec!().into_iter();
1513 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1516 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1519 SizedByDefault::Yes,
1522 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1527 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1529 -> ty::TypeScheme<'tcx>
1531 if def_id.krate != LOCAL_CRATE {
1532 return ccx.tcx.lookup_item_type(def_id);
1535 match ccx.tcx.map.find(def_id.node) {
1536 Some(hir_map::NodeItem(item)) => {
1537 type_scheme_of_item(ccx, &*item)
1539 Some(hir_map::NodeForeignItem(foreign_item)) => {
1540 let abi = ccx.tcx.map.get_foreign_abi(def_id.node);
1541 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1544 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1545 in get_item_type_scheme(): {:?}",
1551 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1553 -> ty::TypeScheme<'tcx>
1555 memoized(&ccx.tcx.tcache,
1556 DefId::local(it.id),
1557 |_| compute_type_scheme_of_item(ccx, it))
1560 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1562 -> ty::TypeScheme<'tcx>
1566 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1567 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1568 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1570 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1571 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1572 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1573 let ty = tcx.mk_fn(Some(DefId::local(it.id)), tcx.mk_bare_fn(tofd));
1574 ty::TypeScheme { ty: ty, generics: ty_generics }
1576 hir::ItemTy(ref t, ref generics) => {
1577 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1578 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1579 ty::TypeScheme { ty: ty, generics: ty_generics }
1581 hir::ItemEnum(ref ei, ref generics) => {
1582 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1583 let substs = mk_item_substs(ccx, &ty_generics);
1584 let def = convert_enum_def(tcx, it, ei);
1585 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1586 ty::TypeScheme { ty: t, generics: ty_generics }
1588 hir::ItemStruct(ref si, ref generics) => {
1589 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1590 let substs = mk_item_substs(ccx, &ty_generics);
1591 let def = convert_struct_def(tcx, it, si);
1592 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1593 ty::TypeScheme { ty: t, generics: ty_generics }
1595 hir::ItemDefaultImpl(..) |
1596 hir::ItemTrait(..) |
1599 hir::ItemForeignMod(..) |
1600 hir::ItemExternCrate(..) |
1601 hir::ItemUse(..) => {
1604 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1610 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1612 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1616 let tag = type_scheme_of_item(ccx, it);
1617 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1618 let predicates = match it.node {
1619 hir::ItemStatic(..) | hir::ItemConst(..) => {
1620 ty::GenericPredicates::empty()
1622 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1623 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1625 hir::ItemTy(_, ref generics) => {
1626 ty_generic_predicates_for_type_or_impl(ccx, generics)
1628 hir::ItemEnum(_, ref generics) => {
1629 ty_generic_predicates_for_type_or_impl(ccx, generics)
1631 hir::ItemStruct(_, ref generics) => {
1632 ty_generic_predicates_for_type_or_impl(ccx, generics)
1634 hir::ItemDefaultImpl(..) |
1635 hir::ItemTrait(..) |
1636 hir::ItemExternCrate(..) |
1640 hir::ItemForeignMod(..) => {
1643 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1648 let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id),
1649 predicates.clone());
1650 assert!(prev_predicates.is_none());
1653 if tcx.has_attr(DefId::local(it.id), "rustc_object_lifetime_default") {
1654 let object_lifetime_default_reprs: String =
1655 scheme.generics.types.iter()
1656 .map(|t| match t.object_lifetime_default {
1657 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1658 d => format!("{:?}", d),
1660 .collect::<Vec<String>>()
1663 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1666 return (scheme, predicates);
1669 fn type_scheme_of_foreign_item<'a, 'tcx>(
1670 ccx: &CrateCtxt<'a, 'tcx>,
1671 it: &hir::ForeignItem,
1673 -> ty::TypeScheme<'tcx>
1675 memoized(&ccx.tcx.tcache,
1676 DefId::local(it.id),
1677 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1680 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1681 ccx: &CrateCtxt<'a, 'tcx>,
1682 it: &hir::ForeignItem,
1684 -> ty::TypeScheme<'tcx>
1687 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1688 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1690 hir::ForeignItemStatic(ref t, _) => {
1692 generics: ty::Generics::empty(),
1693 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1699 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1700 it: &hir::ForeignItem)
1702 // For reasons I cannot fully articulate, I do so hate the AST
1703 // map, and I regard each time that I use it as a personal and
1704 // moral failing, but at the moment it seems like the only
1705 // convenient way to extract the ABI. - ndm
1707 let abi = tcx.map.get_foreign_abi(it.id);
1709 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1710 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1712 let predicates = match it.node {
1713 hir::ForeignItemFn(_, ref generics) => {
1714 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1716 hir::ForeignItemStatic(..) => {
1717 ty::GenericPredicates::empty()
1721 let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id), predicates);
1722 assert!(prev_predicates.is_none());
1725 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1726 generics: &hir::Generics)
1727 -> ty::Generics<'tcx> {
1728 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1731 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1732 generics: &hir::Generics)
1733 -> ty::GenericPredicates<'tcx>
1735 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1738 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1739 trait_id: ast::NodeId,
1740 substs: &'tcx Substs<'tcx>,
1741 ast_generics: &hir::Generics)
1742 -> ty::Generics<'tcx>
1744 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1745 DefId::local(trait_id), substs);
1747 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1749 // Add in the self type parameter.
1751 // Something of a hack: use the node id for the trait, also as
1752 // the node id for the Self type parameter.
1753 let param_id = trait_id;
1755 let parent = ccx.tcx.map.get_parent(param_id);
1757 let def = ty::TypeParameterDef {
1760 name: special_idents::type_self.name,
1761 def_id: DefId::local(param_id),
1762 default_def_id: DefId::local(parent),
1764 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1767 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1769 generics.types.push(SelfSpace, def);
1774 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1775 generics: &hir::Generics,
1776 base_generics: &ty::Generics<'tcx>)
1777 -> ty::Generics<'tcx>
1779 ty_generics(ccx, FnSpace, generics, base_generics)
1782 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1783 generics: &hir::Generics,
1784 base_predicates: &ty::GenericPredicates<'tcx>)
1785 -> ty::GenericPredicates<'tcx>
1787 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1790 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1791 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1792 bounds: &mut ty::BuiltinBounds,
1793 ast_bounds: &[hir::TyParamBound],
1796 let tcx = astconv.tcx();
1798 // Try to find an unbound in bounds.
1799 let mut unbound = None;
1800 for ab in ast_bounds {
1801 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1802 if unbound.is_none() {
1803 assert!(ptr.bound_lifetimes.is_empty());
1804 unbound = Some(ptr.trait_ref.clone());
1806 span_err!(tcx.sess, span, E0203,
1807 "type parameter has more than one relaxed default \
1808 bound, only one is supported");
1813 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1816 // FIXME(#8559) currently requires the unbound to be built-in.
1817 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1819 Ok(kind_id) if trait_def_id != kind_id => {
1820 tcx.sess.span_warn(span,
1821 "default bound relaxed for a type parameter, but \
1822 this does nothing because the given bound is not \
1823 a default. Only `?Sized` is supported");
1824 tcx.try_add_builtin_trait(kind_id, bounds);
1829 _ if kind_id.is_ok() => {
1830 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1832 // No lang item for Sized, so we can't add it as a bound.
1837 /// Returns the early-bound lifetimes declared in this generics
1838 /// listing. For anything other than fns/methods, this is just all
1839 /// the lifetimes that are declared. For fns or methods, we have to
1840 /// screen out those that do not appear in any where-clauses etc using
1841 /// `resolve_lifetime::early_bound_lifetimes`.
1842 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1843 ast_generics: &hir::Generics)
1844 -> Vec<hir::LifetimeDef>
1847 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1848 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1852 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1854 ast_generics: &hir::Generics,
1855 base_predicates: &ty::GenericPredicates<'tcx>)
1856 -> ty::GenericPredicates<'tcx>
1859 let mut result = base_predicates.clone();
1861 // Collect the predicates that were written inline by the user on each
1862 // type parameter (e.g., `<T:Foo>`).
1863 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1864 let index = index as u32;
1865 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1866 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1869 SizedByDefault::Yes,
1871 let predicates = bounds.predicates(ccx.tcx, param_ty);
1872 result.predicates.extend(space, predicates.into_iter());
1875 // Collect the region predicates that were declared inline as
1876 // well. In the case of parameters declared on a fn or method, we
1877 // have to be careful to only iterate over early-bound regions.
1878 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1879 for (index, param) in early_lifetimes.iter().enumerate() {
1880 let index = index as u32;
1882 ty::ReEarlyBound(ty::EarlyBoundRegion {
1883 param_id: param.lifetime.id,
1886 name: param.lifetime.name
1888 for bound in ¶m.bounds {
1889 let bound_region = ast_region_to_region(ccx.tcx, bound);
1890 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1891 result.predicates.push(space, outlives.to_predicate());
1895 // Add in the bounds that appear in the where-clause
1896 let where_clause = &ast_generics.where_clause;
1897 for predicate in &where_clause.predicates {
1899 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1900 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1902 &*bound_pred.bounded_ty);
1904 for bound in bound_pred.bounds.iter() {
1906 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1907 let mut projections = Vec::new();
1910 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1915 result.predicates.push(space, trait_ref.to_predicate());
1917 for projection in &projections {
1918 result.predicates.push(space, projection.to_predicate());
1922 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1923 let region = ast_region_to_region(tcx, lifetime);
1924 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1925 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1931 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1932 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1933 for bound in ®ion_pred.bounds {
1934 let r2 = ast_region_to_region(tcx, bound);
1935 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1936 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1940 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1942 tcx.sess.span_bug(eq_pred.span,
1943 "Equality constraints are not yet \
1944 implemented (#20041)")
1952 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1954 ast_generics: &hir::Generics,
1955 base_generics: &ty::Generics<'tcx>)
1956 -> ty::Generics<'tcx>
1959 let mut result = base_generics.clone();
1961 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1962 for (i, l) in early_lifetimes.iter().enumerate() {
1963 let bounds = l.bounds.iter()
1964 .map(|l| ast_region_to_region(tcx, l))
1966 let def = ty::RegionParameterDef { name: l.lifetime.name,
1969 def_id: DefId::local(l.lifetime.id),
1971 result.regions.push(space, def);
1974 assert!(result.types.is_empty_in(space));
1976 // Now create the real type parameters.
1977 for i in 0..ast_generics.ty_params.len() {
1978 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1979 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1980 result.types.push(space, def);
1986 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1992 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1994 for leaf_ty in ty.walk() {
1995 if let ty::TyParam(p) = leaf_ty.sty {
1996 if p.space == space && p.idx >= index {
1997 span_err!(ccx.tcx.sess, path.span, E0128,
1998 "type parameters with a default cannot use \
1999 forward declared identifiers");
2001 return ccx.tcx.types.err
2009 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2010 ast_generics: &hir::Generics,
2013 -> ty::TypeParameterDef<'tcx>
2015 let param = &ast_generics.ty_params[index as usize];
2018 match tcx.ty_param_defs.borrow().get(¶m.id) {
2019 Some(d) => { return d.clone(); }
2023 let default = param.default.as_ref().map(
2024 |def| convert_default_type_parameter(ccx, def, space, index)
2027 let object_lifetime_default =
2028 compute_object_lifetime_default(ccx, param.id,
2029 ¶m.bounds, &ast_generics.where_clause);
2031 let parent = tcx.map.get_parent(param.id);
2033 let def = ty::TypeParameterDef {
2037 def_id: DefId::local(param.id),
2038 default_def_id: DefId::local(parent),
2040 object_lifetime_default: object_lifetime_default,
2043 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2048 /// Scan the bounds and where-clauses on a parameter to extract bounds
2049 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2050 /// This runs as part of computing the minimal type scheme, so we
2051 /// intentionally avoid just asking astconv to convert all the where
2052 /// clauses into a `ty::Predicate`. This is because that could induce
2053 /// artificial cycles.
2054 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2055 param_id: ast::NodeId,
2056 param_bounds: &[hir::TyParamBound],
2057 where_clause: &hir::WhereClause)
2058 -> ty::ObjectLifetimeDefault
2060 let inline_bounds = from_bounds(ccx, param_bounds);
2061 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2062 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2063 .chain(where_bounds)
2065 return if all_bounds.len() > 1 {
2066 ty::ObjectLifetimeDefault::Ambiguous
2067 } else if all_bounds.len() == 0 {
2068 ty::ObjectLifetimeDefault::BaseDefault
2070 ty::ObjectLifetimeDefault::Specific(
2071 all_bounds.into_iter().next().unwrap())
2074 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2075 bounds: &[hir::TyParamBound])
2079 .filter_map(|bound| {
2081 hir::TraitTyParamBound(..) =>
2083 hir::RegionTyParamBound(ref lifetime) =>
2084 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2090 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2091 param_id: ast::NodeId,
2092 predicates: &[hir::WherePredicate])
2096 .flat_map(|predicate| {
2098 hir::WherePredicate::BoundPredicate(ref data) => {
2099 if data.bound_lifetimes.is_empty() &&
2100 is_param(ccx.tcx, &data.bounded_ty, param_id)
2102 from_bounds(ccx, &data.bounds).into_iter()
2104 Vec::new().into_iter()
2107 hir::WherePredicate::RegionPredicate(..) |
2108 hir::WherePredicate::EqPredicate(..) => {
2109 Vec::new().into_iter()
2117 enum SizedByDefault { Yes, No, }
2119 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2120 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2121 /// built-in trait (formerly known as kind): Send.
2122 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2123 param_ty: ty::Ty<'tcx>,
2124 ast_bounds: &[hir::TyParamBound],
2125 sized_by_default: SizedByDefault,
2127 -> astconv::Bounds<'tcx>
2130 conv_param_bounds(astconv,
2135 if let SizedByDefault::Yes = sized_by_default {
2136 add_unsized_bound(astconv,
2137 &mut bounds.builtin_bounds,
2142 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2147 /// Converts a specific TyParamBound from the AST into a set of
2148 /// predicates that apply to the self-type. A vector is returned
2149 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2150 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2151 /// and `<T as Bar>::X == i32`).
2152 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2154 bound: &hir::TyParamBound)
2155 -> Vec<ty::Predicate<'tcx>>
2158 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2159 let mut projections = Vec::new();
2160 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2161 projections.into_iter()
2162 .map(|p| p.to_predicate())
2163 .chain(Some(pred.to_predicate()))
2166 hir::RegionTyParamBound(ref lifetime) => {
2167 let region = ast_region_to_region(astconv.tcx(), lifetime);
2168 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2169 vec![ty::Predicate::TypeOutlives(pred)]
2171 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2177 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2179 trait_ref: &hir::PolyTraitRef,
2180 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2181 -> ty::PolyTraitRef<'tcx>
2183 astconv::instantiate_poly_trait_ref(astconv,
2190 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2192 param_ty: ty::Ty<'tcx>,
2193 ast_bounds: &[hir::TyParamBound])
2194 -> astconv::Bounds<'tcx>
2196 let tcx = astconv.tcx();
2197 let astconv::PartitionedBounds {
2201 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2203 let mut projection_bounds = Vec::new();
2205 let trait_bounds: Vec<ty::PolyTraitRef> =
2207 .map(|bound| conv_poly_trait_ref(astconv,
2210 &mut projection_bounds))
2213 let region_bounds: Vec<ty::Region> =
2214 region_bounds.into_iter()
2215 .map(|r| ast_region_to_region(tcx, r))
2219 region_bounds: region_bounds,
2220 builtin_bounds: builtin_bounds,
2221 trait_bounds: trait_bounds,
2222 projection_bounds: projection_bounds,
2226 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2227 ccx: &CrateCtxt<'a, 'tcx>,
2229 ast_generics: &hir::Generics,
2231 -> ty::TypeScheme<'tcx>
2233 for i in &decl.inputs {
2234 match (*i).pat.node {
2235 hir::PatIdent(_, _, _) => (),
2236 hir::PatWild(hir::PatWildSingle) => (),
2238 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2239 "patterns aren't allowed in foreign function declarations");
2244 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2246 let rb = BindingRscope::new();
2247 let input_tys = decl.inputs
2249 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2252 let output = match decl.output {
2253 hir::Return(ref ty) =>
2254 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2255 hir::DefaultReturn(..) =>
2256 ty::FnConverging(ccx.tcx.mk_nil()),
2257 hir::NoReturn(..) =>
2261 let t_fn = ccx.tcx.mk_fn(None,
2262 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2264 unsafety: hir::Unsafety::Unsafe,
2265 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2267 variadic: decl.variadic}),
2271 generics: ty_generics,
2276 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2277 ty_generics: &ty::Generics<'tcx>)
2281 ty_generics.types.map(
2282 |def| ccx.tcx.mk_param_from_def(def));
2285 ty_generics.regions.map(
2286 |def| def.to_early_bound_region());
2288 Substs::new(types, regions)
2291 /// Verifies that the explicit self type of a method matches the impl
2292 /// or trait. This is a bit weird but basically because right now we
2293 /// don't handle the general case, but instead map it to one of
2294 /// several pre-defined options using various heuristics, this method
2295 /// comes back to check after the fact that explicit type the user
2296 /// wrote actually matches what the pre-defined option said.
2297 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2298 ccx: &CrateCtxt<'a, 'tcx>,
2300 method_type: Rc<ty::Method<'tcx>>,
2301 required_type: Ty<'tcx>,
2302 explicit_self: &hir::ExplicitSelf,
2303 body_id: ast::NodeId)
2306 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2307 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2308 let base_type = match typ.sty {
2309 ty::TyRef(_, tm) => tm.ty,
2310 ty::TyBox(typ) => typ,
2314 let body_scope = tcx.region_maps.item_extent(body_id);
2316 // "Required type" comes from the trait definition. It may
2317 // contain late-bound regions from the method, but not the
2318 // trait (since traits only have early-bound region
2320 assert!(!base_type.has_regions_escaping_depth(1));
2321 let required_type_free =
2322 liberate_early_bound_regions(
2324 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2326 // The "base type" comes from the impl. It too may have late-bound
2327 // regions from the method.
2328 assert!(!base_type.has_regions_escaping_depth(1));
2329 let base_type_free =
2330 liberate_early_bound_regions(
2332 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2334 debug!("required_type={:?} required_type_free={:?} \
2335 base_type={:?} base_type_free={:?}",
2341 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2342 drop(::require_same_types(tcx,
2349 format!("mismatched self type: expected `{}`",
2353 // We could conceviably add more free-region relations here,
2354 // but since this code is just concerned with checking that
2355 // the `&Self` types etc match up, it's not really necessary.
2356 // It would just allow people to be more approximate in some
2357 // cases. In any case, we can do it later as we feel the need;
2358 // I'd like this function to go away eventually.
2359 let free_regions = FreeRegionMap::new();
2361 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2364 fn liberate_early_bound_regions<'tcx,T>(
2365 tcx: &ty::ctxt<'tcx>,
2366 scope: region::CodeExtent,
2369 where T : TypeFoldable<'tcx>
2372 * Convert early-bound regions into free regions; normally this is done by
2373 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2374 * method-self-type check is kind of hacky and done very early in the process,
2375 * before we really have a `ParameterEnvironment` to check.
2378 tcx.fold_regions(value, &mut false, |region, _| {
2380 ty::ReEarlyBound(data) => {
2381 let def_id = DefId::local(data.param_id);
2382 ty::ReFree(ty::FreeRegion { scope: scope,
2383 bound_region: ty::BrNamed(def_id, data.name) })
2391 /// Checks that all the type parameters on an impl
2392 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2393 ast_generics: &hir::Generics,
2395 impl_items: &[P<hir::ImplItem>])
2397 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2398 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2399 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2401 // The trait reference is an input, so find all type parameters
2402 // reachable from there, to start (if this is an inherent impl,
2403 // then just examine the self type).
2404 let mut input_parameters: HashSet<_> =
2405 ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2406 if let Some(ref trait_ref) = impl_trait_ref {
2407 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2410 ctp::identify_constrained_type_params(tcx,
2411 impl_predicates.predicates.as_slice(),
2413 &mut input_parameters);
2415 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2416 let param_ty = ty::ParamTy { space: TypeSpace,
2418 name: ty_param.name };
2419 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2420 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2424 // Every lifetime used in an associated type must be constrained.
2426 let lifetimes_in_associated_types: HashSet<_> =
2428 .map(|item| tcx.impl_or_trait_item(DefId::local(item.id)))
2429 .filter_map(|item| match item {
2430 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2431 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2433 .flat_map(|ty| ctp::parameters_for_type(ty))
2434 .filter_map(|p| match p {
2435 ctp::Parameter::Type(_) => None,
2436 ctp::Parameter::Region(r) => Some(r),
2440 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2441 let region = ty::EarlyBoundRegion { param_id: lifetime_def.lifetime.id,
2443 index: index as u32,
2444 name: lifetime_def.lifetime.name };
2446 lifetimes_in_associated_types.contains(®ion) && // (*)
2447 !input_parameters.contains(&ctp::Parameter::Region(region))
2449 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2450 "lifetime", ®ion.name.to_string());
2454 // (*) This is a horrible concession to reality. I think it'd be
2455 // better to just ban unconstrianed lifetimes outright, but in
2456 // practice people do non-hygenic macros like:
2459 // macro_rules! __impl_slice_eq1 {
2460 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2461 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2468 // In a concession to backwards compatbility, we continue to
2469 // permit those, so long as the lifetimes aren't used in
2470 // associated types. I believe this is sound, because lifetimes
2471 // used elsewhere are not projected back out.
2474 fn report_unused_parameter(tcx: &ty::ctxt,
2479 span_err!(tcx.sess, span, E0207,
2480 "the {} parameter `{}` is not constrained by the \
2481 impl trait, self type, or predicates",