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::intravisit;
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 ccx.tcx.map.krate().visit_all_items(&mut visitor);
113 let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
114 ccx.tcx.map.krate().visit_all_items(&mut visitor);
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> intravisit::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);
172 ///////////////////////////////////////////////////////////////////////////
173 // Second phase: collection proper.
175 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
176 ccx: &'a CrateCtxt<'a, 'tcx>
179 impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
180 fn visit_item(&mut self, i: &hir::Item) {
181 convert_item(self.ccx, i);
182 intravisit::walk_item(self, i);
184 fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
185 convert_foreign_item(self.ccx, i);
186 intravisit::walk_foreign_item(self, i);
190 ///////////////////////////////////////////////////////////////////////////
191 // Utility types and common code for the above passes.
193 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
194 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
195 ItemCtxt { ccx: self, param_bounds: param_bounds }
198 fn method_ty(&self, method_id: ast::NodeId) -> Rc<ty::Method<'tcx>> {
199 let def_id = self.tcx.map.local_def_id(method_id);
200 match *self.tcx.impl_or_trait_items.borrow().get(&def_id).unwrap() {
201 ty::MethodTraitItem(ref mty) => mty.clone(),
203 self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id));
208 fn cycle_check<F,R>(&self,
210 request: AstConvRequest,
212 -> Result<R,ErrorReported>
213 where F: FnOnce() -> Result<R,ErrorReported>
216 let mut stack = self.stack.borrow_mut();
217 match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
220 let cycle = &stack[i..];
221 self.report_cycle(span, cycle);
222 return Err(ErrorReported);
230 self.stack.borrow_mut().pop();
234 fn report_cycle(&self,
236 cycle: &[AstConvRequest])
238 assert!(!cycle.is_empty());
241 span_err!(tcx.sess, span, E0391,
242 "unsupported cyclic reference between types/traits detected");
245 AstConvRequest::GetItemTypeScheme(def_id) |
246 AstConvRequest::GetTraitDef(def_id) => {
248 &format!("the cycle begins when processing `{}`...",
249 tcx.item_path_str(def_id)));
251 AstConvRequest::EnsureSuperPredicates(def_id) => {
253 &format!("the cycle begins when computing the supertraits of `{}`...",
254 tcx.item_path_str(def_id)));
256 AstConvRequest::GetTypeParameterBounds(id) => {
257 let def = tcx.type_parameter_def(id);
259 &format!("the cycle begins when computing the bounds \
260 for type parameter `{}`...",
265 for request in &cycle[1..] {
267 AstConvRequest::GetItemTypeScheme(def_id) |
268 AstConvRequest::GetTraitDef(def_id) => {
270 &format!("...which then requires processing `{}`...",
271 tcx.item_path_str(def_id)));
273 AstConvRequest::EnsureSuperPredicates(def_id) => {
275 &format!("...which then requires computing the supertraits of `{}`...",
276 tcx.item_path_str(def_id)));
278 AstConvRequest::GetTypeParameterBounds(id) => {
279 let def = tcx.type_parameter_def(id);
281 &format!("...which then requires computing the bounds \
282 for type parameter `{}`...",
289 AstConvRequest::GetItemTypeScheme(def_id) |
290 AstConvRequest::GetTraitDef(def_id) => {
292 &format!("...which then again requires processing `{}`, completing the cycle.",
293 tcx.item_path_str(def_id)));
295 AstConvRequest::EnsureSuperPredicates(def_id) => {
297 &format!("...which then again requires computing the supertraits of `{}`, \
298 completing the cycle.",
299 tcx.item_path_str(def_id)));
301 AstConvRequest::GetTypeParameterBounds(id) => {
302 let def = tcx.type_parameter_def(id);
304 &format!("...which then again requires computing the bounds \
305 for type parameter `{}`, completing the cycle.",
311 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
312 fn get_trait_def(&self, trait_id: DefId)
313 -> &'tcx ty::TraitDef<'tcx>
317 if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
318 let item = match tcx.map.get(trait_id) {
319 hir_map::NodeItem(item) => item,
320 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
323 trait_def_of_item(self, &*item)
325 tcx.lookup_trait_def(trait_id)
329 /// Ensure that the (transitive) super predicates for
330 /// `trait_def_id` are available. This will report a cycle error
331 /// if a trait `X` (transitively) extends itself in some form.
332 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
333 -> Result<(), ErrorReported>
335 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
336 let def_ids = ensure_super_predicates_step(self, trait_def_id);
338 for def_id in def_ids {
339 try!(self.ensure_super_predicates(span, def_id));
347 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
348 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
349 ast_ty_to_ty(self, rs, ast_ty)
353 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
354 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
356 fn get_item_type_scheme(&self, span: Span, id: DefId)
357 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
359 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
360 Ok(type_scheme_of_def_id(self.ccx, id))
364 fn get_trait_def(&self, span: Span, id: DefId)
365 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
367 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
368 Ok(self.ccx.get_trait_def(id))
372 fn ensure_super_predicates(&self,
375 -> Result<(), ErrorReported>
377 debug!("ensure_super_predicates(trait_def_id={:?})",
380 self.ccx.ensure_super_predicates(span, trait_def_id)
384 fn get_type_parameter_bounds(&self,
386 node_id: ast::NodeId)
387 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
389 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
390 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
392 .filter_map(|p| p.to_opt_poly_trait_ref())
398 fn trait_defines_associated_type_named(&self,
400 assoc_name: ast::Name)
403 if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
404 trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
406 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
407 trait_def.associated_type_names.contains(&assoc_name)
412 _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
413 _substs: Option<&mut Substs<'tcx>>,
414 _space: Option<ParamSpace>,
415 span: Span) -> Ty<'tcx> {
416 span_err!(self.tcx().sess, span, E0121,
417 "the type placeholder `_` is not allowed within types on item signatures");
421 fn projected_ty(&self,
423 trait_ref: ty::TraitRef<'tcx>,
424 item_name: ast::Name)
427 self.tcx().mk_projection(trait_ref, item_name)
431 /// Interface used to find the bounds on a type parameter from within
432 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
433 trait GetTypeParameterBounds<'tcx> {
434 fn get_type_parameter_bounds(&self,
435 astconv: &AstConv<'tcx>,
437 node_id: ast::NodeId)
438 -> Vec<ty::Predicate<'tcx>>;
441 /// Find bounds from both elements of the tuple.
442 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
443 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
445 fn get_type_parameter_bounds(&self,
446 astconv: &AstConv<'tcx>,
448 node_id: ast::NodeId)
449 -> Vec<ty::Predicate<'tcx>>
451 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
452 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
457 /// Empty set of bounds.
458 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
459 fn get_type_parameter_bounds(&self,
460 _astconv: &AstConv<'tcx>,
462 _node_id: ast::NodeId)
463 -> Vec<ty::Predicate<'tcx>>
469 /// Find bounds from the parsed and converted predicates. This is
470 /// used when converting methods, because by that time the predicates
471 /// from the trait/impl have been fully converted.
472 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
473 fn get_type_parameter_bounds(&self,
474 astconv: &AstConv<'tcx>,
476 node_id: ast::NodeId)
477 -> Vec<ty::Predicate<'tcx>>
479 let def = astconv.tcx().type_parameter_def(node_id);
483 .filter(|predicate| {
485 ty::Predicate::Trait(ref data) => {
486 data.skip_binder().self_ty().is_param(def.space, def.index)
488 ty::Predicate::TypeOutlives(ref data) => {
489 data.skip_binder().0.is_param(def.space, def.index)
491 ty::Predicate::Equate(..) |
492 ty::Predicate::RegionOutlives(..) |
493 ty::Predicate::WellFormed(..) |
494 ty::Predicate::ObjectSafe(..) |
495 ty::Predicate::Projection(..) => {
505 /// Find bounds from hir::Generics. This requires scanning through the
506 /// AST. We do this to avoid having to convert *all* the bounds, which
507 /// would create artificial cycles. Instead we can only convert the
508 /// bounds for a type parameter `X` if `X::Foo` is used.
509 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
510 fn get_type_parameter_bounds(&self,
511 astconv: &AstConv<'tcx>,
513 node_id: ast::NodeId)
514 -> Vec<ty::Predicate<'tcx>>
516 // In the AST, bounds can derive from two places. Either
517 // written inline like `<T:Foo>` or in a where clause like
520 let def = astconv.tcx().type_parameter_def(node_id);
521 let ty = astconv.tcx().mk_param_from_def(&def);
526 .filter(|p| p.id == node_id)
527 .flat_map(|p| p.bounds.iter())
528 .flat_map(|b| predicates_from_bound(astconv, ty, b));
530 let from_where_clauses =
534 .filter_map(|wp| match *wp {
535 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
538 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
539 .flat_map(|bp| bp.bounds.iter())
540 .flat_map(|b| predicates_from_bound(astconv, ty, b));
542 from_ty_params.chain(from_where_clauses).collect()
546 /// Tests whether this is the AST for a reference to the type
547 /// parameter with id `param_id`. We use this so as to avoid running
548 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
549 /// conversion of the type to avoid inducing unnecessary cycles.
550 fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
552 param_id: ast::NodeId)
555 if let hir::TyPath(None, _) = ast_ty.node {
556 let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
557 match path_res.base_def {
558 def::DefSelfTy(Some(def_id), None) => {
559 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
561 def::DefTyParam(_, _, def_id, _) => {
562 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
574 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
575 container: ImplOrTraitItemContainer,
576 sig: &hir::MethodSig,
579 vis: hir::Visibility,
580 untransformed_rcvr_ty: Ty<'tcx>,
581 rcvr_ty_generics: &ty::Generics<'tcx>,
582 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
583 let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
585 let ty_generic_predicates =
586 ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
588 let (fty, explicit_self_category) =
589 astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
590 sig, untransformed_rcvr_ty);
592 let def_id = ccx.tcx.map.local_def_id(id);
593 let ty_method = ty::Method::new(name,
595 ty_generic_predicates,
597 explicit_self_category,
602 let fty = ccx.tcx.mk_fn(Some(def_id),
603 ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
604 debug!("method {} (id {}) has type {:?}",
606 ccx.tcx.register_item_type(def_id, TypeScheme {
607 generics: ty_method.generics.clone(),
610 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
612 write_ty_to_tcx(ccx.tcx, id, fty);
614 debug!("writing method type: def_id={:?} mty={:?}",
617 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
618 ty::MethodTraitItem(Rc::new(ty_method)));
621 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
622 struct_generics: &ty::Generics<'tcx>,
623 struct_predicates: &ty::GenericPredicates<'tcx>,
624 v: &hir::StructField,
625 ty_f: ty::FieldDefMaster<'tcx>)
627 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
629 write_ty_to_tcx(ccx.tcx, v.node.id, tt);
631 /* add the field to the tcache */
632 ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(v.node.id),
634 generics: struct_generics.clone(),
637 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(v.node.id),
638 struct_predicates.clone());
641 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
642 container: ImplOrTraitItemContainer,
645 vis: hir::Visibility,
649 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
650 ty::GenericPredicates::empty());
652 write_ty_to_tcx(ccx.tcx, id, ty);
654 let associated_const = Rc::new(ty::AssociatedConst {
657 def_id: ccx.tcx.map.local_def_id(id),
658 container: container,
662 ccx.tcx.impl_or_trait_items.borrow_mut()
663 .insert(ccx.tcx.map.local_def_id(id), ty::ConstTraitItem(associated_const));
666 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
667 container: ImplOrTraitItemContainer,
670 vis: hir::Visibility,
671 ty: Option<Ty<'tcx>>)
673 let associated_type = Rc::new(ty::AssociatedType {
677 def_id: ccx.tcx.map.local_def_id(id),
680 ccx.tcx.impl_or_trait_items.borrow_mut()
681 .insert(ccx.tcx.map.local_def_id(id), ty::TypeTraitItem(associated_type));
684 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
685 container: ImplOrTraitItemContainer,
687 untransformed_rcvr_ty: Ty<'tcx>,
688 rcvr_ty_generics: &ty::Generics<'tcx>,
689 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
690 where I: Iterator<Item=(&'i hir::MethodSig, ast::NodeId, ast::Name, hir::Visibility, Span)>
692 debug!("convert_methods(untransformed_rcvr_ty={:?}, rcvr_ty_generics={:?}, \
693 rcvr_ty_predicates={:?})",
694 untransformed_rcvr_ty,
698 for (sig, id, name, vis, _span) in methods {
705 untransformed_rcvr_ty,
711 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
713 generics: &hir::Generics,
714 thing: &'static str) {
715 let mut warn = false;
717 for ty_param in generics.ty_params.iter() {
718 for bound in ty_param.bounds.iter() {
720 hir::TraitTyParamBound(..) => {
723 hir::RegionTyParamBound(..) => { }
729 // According to accepted RFC #XXX, we should
730 // eventually accept these, but it will not be
731 // part of this PR. Still, convert to warning to
732 // make bootstrapping easier.
733 span_warn!(ccx.tcx.sess, span, E0122,
734 "trait bounds are not (yet) enforced \
740 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
742 debug!("convert: item {} with id {}", it.name, it.id);
744 // These don't define types.
745 hir::ItemExternCrate(_) | hir::ItemUse(_) |
746 hir::ItemForeignMod(_) | hir::ItemMod(_) => {
748 hir::ItemEnum(ref enum_definition, _) => {
749 let (scheme, predicates) = convert_typed_item(ccx, it);
750 write_ty_to_tcx(tcx, it.id, scheme.ty);
751 convert_enum_variant_types(ccx,
752 tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
755 &enum_definition.variants);
757 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
759 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
764 tcx.record_trait_has_default_impl(trait_ref.def_id);
766 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
774 // Create generics from the generics specified in the impl head.
775 debug!("convert: ast_generics={:?}", generics);
776 let def_id = ccx.tcx.map.local_def_id(it.id);
777 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
778 let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
780 debug!("convert: impl_bounds={:?}", ty_predicates);
782 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
783 write_ty_to_tcx(tcx, it.id, selfty);
785 tcx.register_item_type(def_id,
786 TypeScheme { generics: ty_generics.clone(),
788 if let &Some(ref ast_trait_ref) = opt_trait_ref {
789 tcx.impl_trait_refs.borrow_mut().insert(
791 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
797 tcx.impl_trait_refs.borrow_mut().insert(def_id, None);
800 enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id);
801 tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
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::ImplItemKind::Type(_) => &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::ImplItemKind::Const(_, _) => "associated constant",
828 hir::ImplItemKind::Type(_) => "associated type",
829 hir::ImplItemKind::Method(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::ImplItemKind::Const(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(def_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::ImplItemKind::Type(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(def_id),
865 impl_item.name, impl_item.id, impl_item.vis,
870 let methods = impl_items.iter().filter_map(|ii| {
871 if let hir::ImplItemKind::Method(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(def_id),
889 for impl_item in impl_items {
890 if let hir::ImplItemKind::Method(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_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
903 hir::ItemTrait(_, _, _, ref trait_items) => {
904 let trait_def = trait_def_of_item(ccx, it);
905 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
906 ccx.ensure_super_predicates(it.span, ccx.tcx.map.local_def_id(it.id));
907 convert_trait_predicates(ccx, it);
908 let trait_predicates = tcx.lookup_predicates(ccx.tcx.map.local_def_id(it.id));
910 debug!("convert: trait_bounds={:?}", trait_predicates);
912 // Convert all the associated types.
913 for trait_item in trait_items {
914 match trait_item.node {
915 hir::ConstTraitItem(ref ty, ref default) => {
916 let ty = ccx.icx(&trait_predicates)
917 .to_ty(&ExplicitRscope, ty);
918 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
920 generics: trait_def.generics.clone(),
923 convert_associated_const(ccx,
924 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
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,
944 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
954 let methods = trait_items.iter().filter_map(|ti| {
955 let sig = match ti.node {
956 hir::MethodTraitItem(ref sig, _) => sig,
959 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
962 // Run convert_methods on the trait methods.
964 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
970 // Add an entry mapping
971 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
972 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
973 match trait_item.node {
974 hir::ConstTraitItem(..) => {
975 ty::ConstTraitItemId(def_id)
977 hir::MethodTraitItem(..) => {
978 ty::MethodTraitItemId(def_id)
980 hir::TypeTraitItem(..) => {
981 ty::TypeTraitItemId(def_id)
985 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
988 // This must be done after `collect_trait_methods` so that
989 // we have a method type stored for every method.
990 for trait_item in trait_items {
991 let sig = match trait_item.node {
992 hir::MethodTraitItem(ref sig, _) => sig,
995 check_method_self_type(ccx,
996 &BindingRscope::new(),
997 ccx.method_ty(trait_item.id),
1003 hir::ItemStruct(ref struct_def, _) => {
1004 let (scheme, predicates) = convert_typed_item(ccx, it);
1005 write_ty_to_tcx(tcx, it.id, scheme.ty);
1007 let it_def_id = ccx.tcx.map.local_def_id(it.id);
1008 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
1010 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
1011 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1014 if !struct_def.is_struct() {
1015 convert_variant_ctor(tcx, struct_def.id(), variant, scheme, predicates);
1018 hir::ItemTy(_, ref generics) => {
1019 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1020 let (scheme, _) = convert_typed_item(ccx, it);
1021 write_ty_to_tcx(tcx, it.id, scheme.ty);
1024 // This call populates the type cache with the converted type
1025 // of the item in passing. All we have to do here is to write
1026 // it into the node type table.
1027 let (scheme, _) = convert_typed_item(ccx, it);
1028 write_ty_to_tcx(tcx, it.id, scheme.ty);
1033 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1034 ctor_id: ast::NodeId,
1035 variant: ty::VariantDef<'tcx>,
1036 scheme: ty::TypeScheme<'tcx>,
1037 predicates: ty::GenericPredicates<'tcx>) {
1038 let ctor_ty = match variant.kind() {
1039 VariantKind::Unit | VariantKind::Struct => scheme.ty,
1040 VariantKind::Tuple => {
1041 let inputs: Vec<_> =
1044 .map(|field| field.unsubst_ty())
1046 tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
1051 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1052 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
1053 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
1055 generics: scheme.generics,
1060 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1061 def: ty::AdtDefMaster<'tcx>,
1062 scheme: ty::TypeScheme<'tcx>,
1063 predicates: ty::GenericPredicates<'tcx>,
1064 variants: &[P<hir::Variant>]) {
1065 // fill the field types
1066 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1067 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
1068 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1071 // Convert the ctor, if any. This also registers the variant as
1073 convert_variant_ctor(
1075 variant.node.data.id(),
1083 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1087 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
1088 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1089 let fields = def.fields().iter().map(|f| {
1090 let fid = tcx.map.local_def_id(f.node.id);
1092 hir::NamedField(name, vis) => {
1093 let dup_span = seen_fields.get(&name).cloned();
1094 if let Some(prev_span) = dup_span {
1095 span_err!(tcx.sess, f.span, E0124,
1096 "field `{}` is already declared",
1098 span_note!(tcx.sess, prev_span, "previously declared here");
1100 seen_fields.insert(name, f.span);
1103 ty::FieldDefData::new(fid, name, vis)
1105 hir::UnnamedField(vis) => {
1106 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1110 ty::VariantDefData {
1118 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1120 def: &hir::VariantData)
1121 -> ty::AdtDefMaster<'tcx>
1124 let did = tcx.map.local_def_id(it.id);
1125 let ctor_id = if !def.is_struct() {
1126 tcx.map.local_def_id(def.id())
1132 ty::AdtKind::Struct,
1133 vec![convert_struct_variant(tcx, ctor_id, it.name, 0, def)]
1137 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1140 -> ty::AdtDefMaster<'tcx>
1142 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1144 e: &hir::Expr) -> Option<ty::Disr> {
1145 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1147 let hint = UncheckedExprHint(repr_ty);
1148 match const_eval::eval_const_expr_partial(tcx, e, hint, None) {
1149 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1150 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1152 let sign_desc = if repr_ty.is_signed() {
1157 span_err!(tcx.sess, e.span, E0079,
1158 "expected {} integer constant",
1163 span_err!(tcx.sess, err.span, E0080,
1164 "constant evaluation error: {}",
1166 if !e.span.contains(err.span) {
1167 tcx.sess.span_note(e.span, "for enum discriminant here");
1174 fn report_discrim_overflow(tcx: &ty::ctxt,
1177 repr_type: attr::IntType,
1178 prev_val: ty::Disr) {
1179 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1180 let computed_value = repr_type.disr_string(computed_value);
1181 let prev_val = repr_type.disr_string(prev_val);
1182 let repr_type = repr_type.to_ty(tcx);
1183 span_err!(tcx.sess, variant_span, E0370,
1184 "enum discriminant overflowed on value after {}: {}; \
1185 set explicitly via {} = {} if that is desired outcome",
1186 prev_val, repr_type, variant_name, computed_value);
1189 fn next_disr(tcx: &ty::ctxt,
1191 repr_type: attr::IntType,
1192 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1193 if let Some(prev_disr_val) = prev_disr_val {
1194 let result = repr_type.disr_incr(prev_disr_val);
1195 if let None = result {
1196 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1197 repr_type, prev_disr_val);
1201 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1204 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1207 -> ty::VariantDefData<'tcx, 'tcx>
1209 let did = tcx.map.local_def_id(v.node.data.id());
1210 let name = v.node.name;
1211 convert_struct_variant(tcx, did, name, disr, &v.node.data)
1213 let did = tcx.map.local_def_id(it.id);
1214 let repr_hints = tcx.lookup_repr_hints(did);
1215 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1216 let mut prev_disr = None;
1217 let variants = def.variants.iter().map(|v| {
1218 let disr = match v.node.disr_expr {
1219 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1220 None => next_disr(tcx, v, repr_type, prev_disr)
1221 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1223 let v = convert_enum_variant(tcx, v, disr);
1224 prev_disr = Some(disr);
1227 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1230 /// Ensures that the super-predicates of the trait with def-id
1231 /// trait_def_id are converted and stored. This does NOT ensure that
1232 /// the transitive super-predicates are converted; that is the job of
1233 /// the `ensure_super_predicates()` method in the `AstConv` impl
1234 /// above. Returns a list of trait def-ids that must be ensured as
1235 /// well to guarantee that the transitive superpredicates are
1237 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1238 trait_def_id: DefId)
1243 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1245 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1248 // If this trait comes from an external crate, then all of the
1249 // supertraits it may depend on also must come from external
1250 // crates, and hence all of them already have their
1251 // super-predicates "converted" (and available from crate
1252 // meta-data), so there is no need to transitively test them.
1256 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1257 let superpredicates = superpredicates.unwrap_or_else(|| {
1258 let item = match ccx.tcx.map.get(trait_node_id) {
1259 hir_map::NodeItem(item) => item,
1260 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1263 let (generics, bounds) = match item.node {
1264 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1265 _ => tcx.sess.span_bug(item.span,
1266 "ensure_super_predicates_step invoked on non-trait"),
1269 // In-scope when converting the superbounds for `Trait` are
1270 // that `Self:Trait` as well as any bounds that appear on the
1272 let trait_def = trait_def_of_item(ccx, item);
1273 let self_predicate = ty::GenericPredicates {
1274 predicates: VecPerParamSpace::new(vec![],
1275 vec![trait_def.trait_ref.to_predicate()],
1278 let scope = &(generics, &self_predicate);
1280 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1281 let self_param_ty = tcx.mk_self_type();
1282 let superbounds1 = compute_bounds(&ccx.icx(scope),
1288 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1290 // Convert any explicit superbounds in the where clause,
1291 // e.g. `trait Foo where Self : Bar`:
1292 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1294 // Combine the two lists to form the complete set of superbounds:
1295 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1296 let superpredicates = ty::GenericPredicates {
1297 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1299 debug!("superpredicates for trait {:?} = {:?}",
1300 tcx.map.local_def_id(item.id),
1303 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1308 let def_ids: Vec<_> = superpredicates.predicates
1310 .filter_map(|p| p.to_opt_poly_trait_ref())
1311 .map(|tr| tr.def_id())
1314 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1319 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1321 -> &'tcx ty::TraitDef<'tcx>
1323 let def_id = ccx.tcx.map.local_def_id(it.id);
1326 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1330 let (unsafety, generics, items) = match it.node {
1331 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1332 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1335 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1336 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1337 ccx.tcx.sess.span_err(
1339 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1340 which traits can use parenthetical notation");
1341 fileline_help!(ccx.tcx.sess, it.span,
1342 "add `#![feature(unboxed_closures)]` to \
1343 the crate attributes to use it");
1346 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1348 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1350 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1351 match trait_item.node {
1352 hir::TypeTraitItem(..) => Some(trait_item.name),
1357 let trait_ref = ty::TraitRef {
1362 let trait_def = ty::TraitDef {
1363 paren_sugar: paren_sugar,
1365 generics: ty_generics,
1366 trait_ref: trait_ref,
1367 associated_type_names: associated_type_names,
1368 nonblanket_impls: RefCell::new(FnvHashMap()),
1369 blanket_impls: RefCell::new(vec![]),
1370 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1373 return tcx.intern_trait_def(trait_def);
1375 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1376 generics: &hir::Generics)
1381 // Creates a no-op substitution for the trait's type parameters.
1386 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1387 def_id: tcx.map.local_def_id(def.lifetime.id),
1390 name: def.lifetime.name
1394 // Start with the generics in the type parameters...
1399 .map(|(i, def)| tcx.mk_param(TypeSpace,
1400 i as u32, def.name))
1403 // ...and also create the `Self` parameter.
1404 let self_ty = tcx.mk_self_type();
1406 Substs::new_trait(types, regions, self_ty)
1410 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1411 trait_node_id: ast::NodeId,
1412 assoc_name: ast::Name)
1415 let item = match ccx.tcx.map.get(trait_node_id) {
1416 hir_map::NodeItem(item) => item,
1417 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1420 let trait_items = match item.node {
1421 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1422 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1425 trait_items.iter().any(|trait_item| {
1426 match trait_item.node {
1427 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1433 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1435 let trait_def = trait_def_of_item(ccx, it);
1437 let def_id = ccx.tcx.map.local_def_id(it.id);
1439 let (generics, items) = match it.node {
1440 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1444 &format!("trait_def_of_item invoked on {:?}", s));
1448 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1450 // `ty_generic_predicates` below will consider the bounds on the type
1451 // parameters (including `Self`) and the explicit where-clauses,
1452 // but to get the full set of predicates on a trait we need to add
1453 // in the supertrait bounds and anything declared on the
1454 // associated types.
1455 let mut base_predicates = super_predicates;
1457 // Add in a predicate that `Self:Trait` (where `Trait` is the
1458 // current trait). This is needed for builtin bounds.
1459 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1460 base_predicates.predicates.push(SelfSpace, self_predicate);
1462 // add in the explicit where-clauses
1463 let mut trait_predicates =
1464 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1466 let assoc_predicates = predicates_for_associated_types(ccx,
1469 trait_def.trait_ref,
1471 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1473 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1474 assert!(prev_predicates.is_none());
1478 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1479 ast_generics: &hir::Generics,
1480 trait_predicates: &ty::GenericPredicates<'tcx>,
1481 self_trait_ref: ty::TraitRef<'tcx>,
1482 trait_items: &[P<hir::TraitItem>])
1483 -> Vec<ty::Predicate<'tcx>>
1485 trait_items.iter().flat_map(|trait_item| {
1486 let bounds = match trait_item.node {
1487 hir::TypeTraitItem(ref bounds, _) => bounds,
1489 return vec!().into_iter();
1493 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1496 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1499 SizedByDefault::Yes,
1502 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1507 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1509 -> ty::TypeScheme<'tcx>
1511 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1512 match ccx.tcx.map.find(node_id) {
1513 Some(hir_map::NodeItem(item)) => {
1514 type_scheme_of_item(ccx, &*item)
1516 Some(hir_map::NodeForeignItem(foreign_item)) => {
1517 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1518 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1521 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1522 in get_item_type_scheme(): {:?}",
1527 ccx.tcx.lookup_item_type(def_id)
1531 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1533 -> ty::TypeScheme<'tcx>
1535 memoized(&ccx.tcx.tcache,
1536 ccx.tcx.map.local_def_id(it.id),
1537 |_| compute_type_scheme_of_item(ccx, it))
1540 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1542 -> ty::TypeScheme<'tcx>
1546 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1547 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1548 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1550 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1551 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1552 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1553 let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1554 ty::TypeScheme { ty: ty, generics: ty_generics }
1556 hir::ItemTy(ref t, ref generics) => {
1557 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1558 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1559 ty::TypeScheme { ty: ty, generics: ty_generics }
1561 hir::ItemEnum(ref ei, ref generics) => {
1562 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1563 let substs = mk_item_substs(ccx, &ty_generics);
1564 let def = convert_enum_def(tcx, it, ei);
1565 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1566 ty::TypeScheme { ty: t, generics: ty_generics }
1568 hir::ItemStruct(ref si, ref generics) => {
1569 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1570 let substs = mk_item_substs(ccx, &ty_generics);
1571 let def = convert_struct_def(tcx, it, si);
1572 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1573 ty::TypeScheme { ty: t, generics: ty_generics }
1575 hir::ItemDefaultImpl(..) |
1576 hir::ItemTrait(..) |
1579 hir::ItemForeignMod(..) |
1580 hir::ItemExternCrate(..) |
1581 hir::ItemUse(..) => {
1584 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1590 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1592 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1596 let tag = type_scheme_of_item(ccx, it);
1597 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1598 let predicates = match it.node {
1599 hir::ItemStatic(..) | hir::ItemConst(..) => {
1600 ty::GenericPredicates::empty()
1602 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1603 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1605 hir::ItemTy(_, ref generics) => {
1606 ty_generic_predicates_for_type_or_impl(ccx, generics)
1608 hir::ItemEnum(_, ref generics) => {
1609 ty_generic_predicates_for_type_or_impl(ccx, generics)
1611 hir::ItemStruct(_, ref generics) => {
1612 ty_generic_predicates_for_type_or_impl(ccx, generics)
1614 hir::ItemDefaultImpl(..) |
1615 hir::ItemTrait(..) |
1616 hir::ItemExternCrate(..) |
1620 hir::ItemForeignMod(..) => {
1623 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1628 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1629 predicates.clone());
1630 assert!(prev_predicates.is_none());
1633 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1634 let object_lifetime_default_reprs: String =
1635 scheme.generics.types.iter()
1636 .map(|t| match t.object_lifetime_default {
1637 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1638 d => format!("{:?}", d),
1640 .collect::<Vec<String>>()
1643 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1646 return (scheme, predicates);
1649 fn type_scheme_of_foreign_item<'a, 'tcx>(
1650 ccx: &CrateCtxt<'a, 'tcx>,
1651 it: &hir::ForeignItem,
1653 -> ty::TypeScheme<'tcx>
1655 memoized(&ccx.tcx.tcache,
1656 ccx.tcx.map.local_def_id(it.id),
1657 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1660 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1661 ccx: &CrateCtxt<'a, 'tcx>,
1662 it: &hir::ForeignItem,
1664 -> ty::TypeScheme<'tcx>
1667 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1668 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1670 hir::ForeignItemStatic(ref t, _) => {
1672 generics: ty::Generics::empty(),
1673 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1679 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1680 it: &hir::ForeignItem)
1682 // For reasons I cannot fully articulate, I do so hate the AST
1683 // map, and I regard each time that I use it as a personal and
1684 // moral failing, but at the moment it seems like the only
1685 // convenient way to extract the ABI. - ndm
1687 let abi = tcx.map.get_foreign_abi(it.id);
1689 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1690 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1692 let predicates = match it.node {
1693 hir::ForeignItemFn(_, ref generics) => {
1694 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1696 hir::ForeignItemStatic(..) => {
1697 ty::GenericPredicates::empty()
1701 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1703 assert!(prev_predicates.is_none());
1706 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1707 generics: &hir::Generics)
1708 -> ty::Generics<'tcx> {
1709 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1712 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1713 generics: &hir::Generics)
1714 -> ty::GenericPredicates<'tcx>
1716 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1719 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1720 trait_id: ast::NodeId,
1721 substs: &'tcx Substs<'tcx>,
1722 ast_generics: &hir::Generics)
1723 -> ty::Generics<'tcx>
1725 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1726 ccx.tcx.map.local_def_id(trait_id), substs);
1728 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1730 // Add in the self type parameter.
1732 // Something of a hack: use the node id for the trait, also as
1733 // the node id for the Self type parameter.
1734 let param_id = trait_id;
1736 let parent = ccx.tcx.map.get_parent(param_id);
1738 let def = ty::TypeParameterDef {
1741 name: special_idents::type_self.name,
1742 def_id: ccx.tcx.map.local_def_id(param_id),
1743 default_def_id: ccx.tcx.map.local_def_id(parent),
1745 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1748 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1750 generics.types.push(SelfSpace, def);
1755 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1756 generics: &hir::Generics,
1757 base_generics: &ty::Generics<'tcx>)
1758 -> ty::Generics<'tcx>
1760 ty_generics(ccx, FnSpace, generics, base_generics)
1763 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1764 generics: &hir::Generics,
1765 base_predicates: &ty::GenericPredicates<'tcx>)
1766 -> ty::GenericPredicates<'tcx>
1768 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1771 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1772 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1773 bounds: &mut ty::BuiltinBounds,
1774 ast_bounds: &[hir::TyParamBound],
1777 let tcx = astconv.tcx();
1779 // Try to find an unbound in bounds.
1780 let mut unbound = None;
1781 for ab in ast_bounds {
1782 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1783 if unbound.is_none() {
1784 assert!(ptr.bound_lifetimes.is_empty());
1785 unbound = Some(ptr.trait_ref.clone());
1787 span_err!(tcx.sess, span, E0203,
1788 "type parameter has more than one relaxed default \
1789 bound, only one is supported");
1794 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1797 // FIXME(#8559) currently requires the unbound to be built-in.
1798 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1800 Ok(kind_id) if trait_def_id != kind_id => {
1801 tcx.sess.span_warn(span,
1802 "default bound relaxed for a type parameter, but \
1803 this does nothing because the given bound is not \
1804 a default. Only `?Sized` is supported");
1805 tcx.try_add_builtin_trait(kind_id, bounds);
1810 _ if kind_id.is_ok() => {
1811 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1813 // No lang item for Sized, so we can't add it as a bound.
1818 /// Returns the early-bound lifetimes declared in this generics
1819 /// listing. For anything other than fns/methods, this is just all
1820 /// the lifetimes that are declared. For fns or methods, we have to
1821 /// screen out those that do not appear in any where-clauses etc using
1822 /// `resolve_lifetime::early_bound_lifetimes`.
1823 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1824 ast_generics: &hir::Generics)
1825 -> Vec<hir::LifetimeDef>
1828 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1829 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1833 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1835 ast_generics: &hir::Generics,
1836 base_predicates: &ty::GenericPredicates<'tcx>)
1837 -> ty::GenericPredicates<'tcx>
1840 let mut result = base_predicates.clone();
1842 // Collect the predicates that were written inline by the user on each
1843 // type parameter (e.g., `<T:Foo>`).
1844 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1845 let index = index as u32;
1846 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1847 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1850 SizedByDefault::Yes,
1852 let predicates = bounds.predicates(ccx.tcx, param_ty);
1853 result.predicates.extend(space, predicates.into_iter());
1856 // Collect the region predicates that were declared inline as
1857 // well. In the case of parameters declared on a fn or method, we
1858 // have to be careful to only iterate over early-bound regions.
1859 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1860 for (index, param) in early_lifetimes.iter().enumerate() {
1861 let index = index as u32;
1862 let def_id = tcx.map.local_def_id(param.lifetime.id);
1864 ty::ReEarlyBound(ty::EarlyBoundRegion {
1868 name: param.lifetime.name
1870 for bound in ¶m.bounds {
1871 let bound_region = ast_region_to_region(ccx.tcx, bound);
1872 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1873 result.predicates.push(space, outlives.to_predicate());
1877 // Add in the bounds that appear in the where-clause
1878 let where_clause = &ast_generics.where_clause;
1879 for predicate in &where_clause.predicates {
1881 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1882 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1884 &*bound_pred.bounded_ty);
1886 for bound in bound_pred.bounds.iter() {
1888 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1889 let mut projections = Vec::new();
1892 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1897 result.predicates.push(space, trait_ref.to_predicate());
1899 for projection in &projections {
1900 result.predicates.push(space, projection.to_predicate());
1904 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1905 let region = ast_region_to_region(tcx, lifetime);
1906 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1907 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1913 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1914 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1915 for bound in ®ion_pred.bounds {
1916 let r2 = ast_region_to_region(tcx, bound);
1917 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1918 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1922 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1924 tcx.sess.span_bug(eq_pred.span,
1925 "Equality constraints are not yet \
1926 implemented (#20041)")
1934 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1936 ast_generics: &hir::Generics,
1937 base_generics: &ty::Generics<'tcx>)
1938 -> ty::Generics<'tcx>
1941 let mut result = base_generics.clone();
1943 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1944 for (i, l) in early_lifetimes.iter().enumerate() {
1945 let bounds = l.bounds.iter()
1946 .map(|l| ast_region_to_region(tcx, l))
1948 let def = ty::RegionParameterDef { name: l.lifetime.name,
1951 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1953 result.regions.push(space, def);
1956 assert!(result.types.is_empty_in(space));
1958 // Now create the real type parameters.
1959 for i in 0..ast_generics.ty_params.len() {
1960 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1961 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1962 result.types.push(space, def);
1968 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1974 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1976 for leaf_ty in ty.walk() {
1977 if let ty::TyParam(p) = leaf_ty.sty {
1978 if p.space == space && p.idx >= index {
1979 span_err!(ccx.tcx.sess, path.span, E0128,
1980 "type parameters with a default cannot use \
1981 forward declared identifiers");
1983 return ccx.tcx.types.err
1991 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1992 ast_generics: &hir::Generics,
1995 -> ty::TypeParameterDef<'tcx>
1997 let param = &ast_generics.ty_params[index as usize];
2000 match tcx.ty_param_defs.borrow().get(¶m.id) {
2001 Some(d) => { return d.clone(); }
2005 let default = param.default.as_ref().map(
2006 |def| convert_default_type_parameter(ccx, def, space, index)
2009 let object_lifetime_default =
2010 compute_object_lifetime_default(ccx, param.id,
2011 ¶m.bounds, &ast_generics.where_clause);
2013 let parent = tcx.map.get_parent(param.id);
2015 let def = ty::TypeParameterDef {
2019 def_id: ccx.tcx.map.local_def_id(param.id),
2020 default_def_id: ccx.tcx.map.local_def_id(parent),
2022 object_lifetime_default: object_lifetime_default,
2025 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2030 /// Scan the bounds and where-clauses on a parameter to extract bounds
2031 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2032 /// This runs as part of computing the minimal type scheme, so we
2033 /// intentionally avoid just asking astconv to convert all the where
2034 /// clauses into a `ty::Predicate`. This is because that could induce
2035 /// artificial cycles.
2036 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2037 param_id: ast::NodeId,
2038 param_bounds: &[hir::TyParamBound],
2039 where_clause: &hir::WhereClause)
2040 -> ty::ObjectLifetimeDefault
2042 let inline_bounds = from_bounds(ccx, param_bounds);
2043 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2044 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2045 .chain(where_bounds)
2047 return if all_bounds.len() > 1 {
2048 ty::ObjectLifetimeDefault::Ambiguous
2049 } else if all_bounds.len() == 0 {
2050 ty::ObjectLifetimeDefault::BaseDefault
2052 ty::ObjectLifetimeDefault::Specific(
2053 all_bounds.into_iter().next().unwrap())
2056 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2057 bounds: &[hir::TyParamBound])
2061 .filter_map(|bound| {
2063 hir::TraitTyParamBound(..) =>
2065 hir::RegionTyParamBound(ref lifetime) =>
2066 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2072 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2073 param_id: ast::NodeId,
2074 predicates: &[hir::WherePredicate])
2078 .flat_map(|predicate| {
2080 hir::WherePredicate::BoundPredicate(ref data) => {
2081 if data.bound_lifetimes.is_empty() &&
2082 is_param(ccx.tcx, &data.bounded_ty, param_id)
2084 from_bounds(ccx, &data.bounds).into_iter()
2086 Vec::new().into_iter()
2089 hir::WherePredicate::RegionPredicate(..) |
2090 hir::WherePredicate::EqPredicate(..) => {
2091 Vec::new().into_iter()
2099 enum SizedByDefault { Yes, No, }
2101 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2102 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2103 /// built-in trait (formerly known as kind): Send.
2104 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2105 param_ty: ty::Ty<'tcx>,
2106 ast_bounds: &[hir::TyParamBound],
2107 sized_by_default: SizedByDefault,
2109 -> astconv::Bounds<'tcx>
2112 conv_param_bounds(astconv,
2117 if let SizedByDefault::Yes = sized_by_default {
2118 add_unsized_bound(astconv,
2119 &mut bounds.builtin_bounds,
2124 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2129 /// Converts a specific TyParamBound from the AST into a set of
2130 /// predicates that apply to the self-type. A vector is returned
2131 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2132 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2133 /// and `<T as Bar>::X == i32`).
2134 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2136 bound: &hir::TyParamBound)
2137 -> Vec<ty::Predicate<'tcx>>
2140 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2141 let mut projections = Vec::new();
2142 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2143 projections.into_iter()
2144 .map(|p| p.to_predicate())
2145 .chain(Some(pred.to_predicate()))
2148 hir::RegionTyParamBound(ref lifetime) => {
2149 let region = ast_region_to_region(astconv.tcx(), lifetime);
2150 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2151 vec![ty::Predicate::TypeOutlives(pred)]
2153 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2159 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2161 trait_ref: &hir::PolyTraitRef,
2162 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2163 -> ty::PolyTraitRef<'tcx>
2165 astconv::instantiate_poly_trait_ref(astconv,
2172 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2174 param_ty: ty::Ty<'tcx>,
2175 ast_bounds: &[hir::TyParamBound])
2176 -> astconv::Bounds<'tcx>
2178 let tcx = astconv.tcx();
2179 let astconv::PartitionedBounds {
2183 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2185 let mut projection_bounds = Vec::new();
2187 let trait_bounds: Vec<ty::PolyTraitRef> =
2189 .map(|bound| conv_poly_trait_ref(astconv,
2192 &mut projection_bounds))
2195 let region_bounds: Vec<ty::Region> =
2196 region_bounds.into_iter()
2197 .map(|r| ast_region_to_region(tcx, r))
2201 region_bounds: region_bounds,
2202 builtin_bounds: builtin_bounds,
2203 trait_bounds: trait_bounds,
2204 projection_bounds: projection_bounds,
2208 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2209 ccx: &CrateCtxt<'a, 'tcx>,
2211 ast_generics: &hir::Generics,
2213 -> ty::TypeScheme<'tcx>
2215 for i in &decl.inputs {
2216 match (*i).pat.node {
2217 hir::PatIdent(_, _, _) => (),
2220 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2221 "patterns aren't allowed in foreign function declarations");
2226 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2228 let rb = BindingRscope::new();
2229 let input_tys = decl.inputs
2231 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2234 let output = match decl.output {
2235 hir::Return(ref ty) =>
2236 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2237 hir::DefaultReturn(..) =>
2238 ty::FnConverging(ccx.tcx.mk_nil()),
2239 hir::NoReturn(..) =>
2243 let t_fn = ccx.tcx.mk_fn(None,
2244 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2246 unsafety: hir::Unsafety::Unsafe,
2247 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2249 variadic: decl.variadic}),
2253 generics: ty_generics,
2258 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2259 ty_generics: &ty::Generics<'tcx>)
2263 ty_generics.types.map(
2264 |def| ccx.tcx.mk_param_from_def(def));
2267 ty_generics.regions.map(
2268 |def| def.to_early_bound_region());
2270 Substs::new(types, regions)
2273 /// Verifies that the explicit self type of a method matches the impl
2274 /// or trait. This is a bit weird but basically because right now we
2275 /// don't handle the general case, but instead map it to one of
2276 /// several pre-defined options using various heuristics, this method
2277 /// comes back to check after the fact that explicit type the user
2278 /// wrote actually matches what the pre-defined option said.
2279 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2280 ccx: &CrateCtxt<'a, 'tcx>,
2282 method_type: Rc<ty::Method<'tcx>>,
2283 required_type: Ty<'tcx>,
2284 explicit_self: &hir::ExplicitSelf,
2285 body_id: ast::NodeId)
2288 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2289 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2290 let base_type = match typ.sty {
2291 ty::TyRef(_, tm) => tm.ty,
2292 ty::TyBox(typ) => typ,
2296 let body_scope = tcx.region_maps.item_extent(body_id);
2298 // "Required type" comes from the trait definition. It may
2299 // contain late-bound regions from the method, but not the
2300 // trait (since traits only have early-bound region
2302 assert!(!base_type.has_regions_escaping_depth(1));
2303 let required_type_free =
2304 liberate_early_bound_regions(
2306 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2308 // The "base type" comes from the impl. It too may have late-bound
2309 // regions from the method.
2310 assert!(!base_type.has_regions_escaping_depth(1));
2311 let base_type_free =
2312 liberate_early_bound_regions(
2314 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2316 debug!("required_type={:?} required_type_free={:?} \
2317 base_type={:?} base_type_free={:?}",
2323 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2324 drop(::require_same_types(tcx,
2331 format!("mismatched self type: expected `{}`",
2335 // We could conceviably add more free-region relations here,
2336 // but since this code is just concerned with checking that
2337 // the `&Self` types etc match up, it's not really necessary.
2338 // It would just allow people to be more approximate in some
2339 // cases. In any case, we can do it later as we feel the need;
2340 // I'd like this function to go away eventually.
2341 let free_regions = FreeRegionMap::new();
2343 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2346 fn liberate_early_bound_regions<'tcx,T>(
2347 tcx: &ty::ctxt<'tcx>,
2348 scope: region::CodeExtent,
2351 where T : TypeFoldable<'tcx>
2354 * Convert early-bound regions into free regions; normally this is done by
2355 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2356 * method-self-type check is kind of hacky and done very early in the process,
2357 * before we really have a `ParameterEnvironment` to check.
2360 tcx.fold_regions(value, &mut false, |region, _| {
2362 ty::ReEarlyBound(data) => {
2363 ty::ReFree(ty::FreeRegion {
2365 bound_region: ty::BrNamed(data.def_id, data.name)
2374 /// Checks that all the type parameters on an impl
2375 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2376 ast_generics: &hir::Generics,
2377 impl_predicates: &mut ty::GenericPredicates<'tcx>,
2380 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2381 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2383 assert!(impl_predicates.predicates.is_empty_in(FnSpace));
2384 assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
2386 // The trait reference is an input, so find all type parameters
2387 // reachable from there, to start (if this is an inherent impl,
2388 // then just examine the self type).
2389 let mut input_parameters: HashSet<_> =
2390 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2391 if let Some(ref trait_ref) = impl_trait_ref {
2392 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2395 ctp::setup_constraining_predicates(tcx,
2396 impl_predicates.predicates.get_mut_slice(TypeSpace),
2398 &mut input_parameters);
2400 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2401 let param_ty = ty::ParamTy { space: TypeSpace,
2403 name: ty_param.name };
2404 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2405 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2410 fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2411 ast_generics: &hir::Generics,
2413 impl_items: &[P<hir::ImplItem>])
2415 // Every lifetime used in an associated type must be constrained.
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 let mut input_parameters: HashSet<_> =
2421 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2422 if let Some(ref trait_ref) = impl_trait_ref {
2423 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2425 ctp::identify_constrained_type_params(tcx,
2426 &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
2428 let lifetimes_in_associated_types: HashSet<_> =
2430 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2431 .filter_map(|item| match item {
2432 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2433 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2435 .flat_map(|ty| ctp::parameters_for_type(ty, true))
2436 .filter_map(|p| match p {
2437 ctp::Parameter::Type(_) => None,
2438 ctp::Parameter::Region(r) => Some(r),
2442 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2443 let def_id = tcx.map.local_def_id(lifetime_def.lifetime.id);
2444 let region = ty::EarlyBoundRegion { def_id: def_id,
2446 index: index as u32,
2447 name: lifetime_def.lifetime.name };
2449 lifetimes_in_associated_types.contains(®ion) && // (*)
2450 !input_parameters.contains(&ctp::Parameter::Region(region))
2452 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2453 "lifetime", ®ion.name.to_string());
2457 // (*) This is a horrible concession to reality. I think it'd be
2458 // better to just ban unconstrianed lifetimes outright, but in
2459 // practice people do non-hygenic macros like:
2462 // macro_rules! __impl_slice_eq1 {
2463 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2464 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2471 // In a concession to backwards compatbility, we continue to
2472 // permit those, so long as the lifetimes aren't used in
2473 // associated types. I believe this is sound, because lifetimes
2474 // used elsewhere are not projected back out.
2477 fn report_unused_parameter(tcx: &ty::ctxt,
2482 span_err!(tcx.sess, span, E0207,
2483 "the {} parameter `{}` is not constrained by the \
2484 impl trait, self type, or predicates",