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 let body_scope = ccx.tcx.region_maps.call_site_extent(impl_item.id, body_id);
893 check_method_self_type(ccx,
894 &BindingRscope::new(),
895 ccx.method_ty(impl_item.id),
903 enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
905 hir::ItemTrait(_, _, _, ref trait_items) => {
906 let trait_def = trait_def_of_item(ccx, it);
907 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
908 ccx.ensure_super_predicates(it.span, ccx.tcx.map.local_def_id(it.id));
909 convert_trait_predicates(ccx, it);
910 let trait_predicates = tcx.lookup_predicates(ccx.tcx.map.local_def_id(it.id));
912 debug!("convert: trait_bounds={:?}", trait_predicates);
914 // Convert all the associated types.
915 for trait_item in trait_items {
916 match trait_item.node {
917 hir::ConstTraitItem(ref ty, ref default) => {
918 let ty = ccx.icx(&trait_predicates)
919 .to_ty(&ExplicitRscope, ty);
920 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
922 generics: trait_def.generics.clone(),
925 convert_associated_const(ccx,
926 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
937 // Convert all the associated types.
938 for trait_item in trait_items {
939 match trait_item.node {
940 hir::TypeTraitItem(_, ref opt_ty) => {
941 let typ = opt_ty.as_ref().map({
942 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
945 convert_associated_type(ccx,
946 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
956 let methods = trait_items.iter().filter_map(|ti| {
957 let sig = match ti.node {
958 hir::MethodTraitItem(ref sig, _) => sig,
961 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
964 // Run convert_methods on the trait methods.
966 TraitContainer(ccx.tcx.map.local_def_id(it.id)),
972 // Add an entry mapping
973 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
974 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
975 match trait_item.node {
976 hir::ConstTraitItem(..) => {
977 ty::ConstTraitItemId(def_id)
979 hir::MethodTraitItem(..) => {
980 ty::MethodTraitItemId(def_id)
982 hir::TypeTraitItem(..) => {
983 ty::TypeTraitItemId(def_id)
987 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
990 // This must be done after `collect_trait_methods` so that
991 // we have a method type stored for every method.
992 for trait_item in trait_items {
993 let (sig, the_scope, the_id) = match trait_item.node {
994 hir::MethodTraitItem(ref sig, Some(ref body)) => {
996 ccx.tcx.region_maps.call_site_extent(trait_item.id, body.id);
997 (sig, body_scope, body.id)
999 hir::MethodTraitItem(ref sig, None) => {
1000 let item_scope = ccx.tcx.region_maps.item_extent(trait_item.id);
1001 (sig, item_scope, it.id)
1005 check_method_self_type(ccx,
1006 &BindingRscope::new(),
1007 ccx.method_ty(trait_item.id),
1014 hir::ItemStruct(ref struct_def, _) => {
1015 let (scheme, predicates) = convert_typed_item(ccx, it);
1016 write_ty_to_tcx(tcx, it.id, scheme.ty);
1018 let it_def_id = ccx.tcx.map.local_def_id(it.id);
1019 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
1021 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
1022 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1025 if !struct_def.is_struct() {
1026 convert_variant_ctor(tcx, struct_def.id(), variant, scheme, predicates);
1029 hir::ItemTy(_, ref generics) => {
1030 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1031 let (scheme, _) = convert_typed_item(ccx, it);
1032 write_ty_to_tcx(tcx, it.id, scheme.ty);
1035 // This call populates the type cache with the converted type
1036 // of the item in passing. All we have to do here is to write
1037 // it into the node type table.
1038 let (scheme, _) = convert_typed_item(ccx, it);
1039 write_ty_to_tcx(tcx, it.id, scheme.ty);
1044 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1045 ctor_id: ast::NodeId,
1046 variant: ty::VariantDef<'tcx>,
1047 scheme: ty::TypeScheme<'tcx>,
1048 predicates: ty::GenericPredicates<'tcx>) {
1049 let ctor_ty = match variant.kind() {
1050 VariantKind::Unit | VariantKind::Struct => scheme.ty,
1051 VariantKind::Tuple => {
1052 let inputs: Vec<_> =
1055 .map(|field| field.unsubst_ty())
1057 tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
1062 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1063 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
1064 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
1066 generics: scheme.generics,
1071 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1072 def: ty::AdtDefMaster<'tcx>,
1073 scheme: ty::TypeScheme<'tcx>,
1074 predicates: ty::GenericPredicates<'tcx>,
1075 variants: &[hir::Variant]) {
1076 // fill the field types
1077 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1078 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
1079 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1082 // Convert the ctor, if any. This also registers the variant as
1084 convert_variant_ctor(
1086 variant.node.data.id(),
1094 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1098 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
1099 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1100 let fields = def.fields().iter().map(|f| {
1101 let fid = tcx.map.local_def_id(f.node.id);
1103 hir::NamedField(name, vis) => {
1104 let dup_span = seen_fields.get(&name).cloned();
1105 if let Some(prev_span) = dup_span {
1106 span_err!(tcx.sess, f.span, E0124,
1107 "field `{}` is already declared",
1109 span_note!(tcx.sess, prev_span, "previously declared here");
1111 seen_fields.insert(name, f.span);
1114 ty::FieldDefData::new(fid, name, vis)
1116 hir::UnnamedField(vis) => {
1117 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1121 ty::VariantDefData {
1129 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1131 def: &hir::VariantData)
1132 -> ty::AdtDefMaster<'tcx>
1135 let did = tcx.map.local_def_id(it.id);
1136 let ctor_id = if !def.is_struct() {
1137 tcx.map.local_def_id(def.id())
1143 ty::AdtKind::Struct,
1144 vec![convert_struct_variant(tcx, ctor_id, it.name, 0, def)]
1148 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1151 -> ty::AdtDefMaster<'tcx>
1153 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1155 e: &hir::Expr) -> Option<ty::Disr> {
1156 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1158 let hint = UncheckedExprHint(repr_ty);
1159 match const_eval::eval_const_expr_partial(tcx, e, hint, None) {
1160 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1161 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1163 let sign_desc = if repr_ty.is_signed() {
1168 span_err!(tcx.sess, e.span, E0079,
1169 "expected {} integer constant",
1174 span_err!(tcx.sess, err.span, E0080,
1175 "constant evaluation error: {}",
1177 if !e.span.contains(err.span) {
1178 tcx.sess.span_note(e.span, "for enum discriminant here");
1185 fn report_discrim_overflow(tcx: &ty::ctxt,
1188 repr_type: attr::IntType,
1189 prev_val: ty::Disr) {
1190 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1191 let computed_value = repr_type.disr_string(computed_value);
1192 let prev_val = repr_type.disr_string(prev_val);
1193 let repr_type = repr_type.to_ty(tcx);
1194 span_err!(tcx.sess, variant_span, E0370,
1195 "enum discriminant overflowed on value after {}: {}; \
1196 set explicitly via {} = {} if that is desired outcome",
1197 prev_val, repr_type, variant_name, computed_value);
1200 fn next_disr(tcx: &ty::ctxt,
1202 repr_type: attr::IntType,
1203 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1204 if let Some(prev_disr_val) = prev_disr_val {
1205 let result = repr_type.disr_incr(prev_disr_val);
1206 if let None = result {
1207 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1208 repr_type, prev_disr_val);
1212 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1215 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1218 -> ty::VariantDefData<'tcx, 'tcx>
1220 let did = tcx.map.local_def_id(v.node.data.id());
1221 let name = v.node.name;
1222 convert_struct_variant(tcx, did, name, disr, &v.node.data)
1224 let did = tcx.map.local_def_id(it.id);
1225 let repr_hints = tcx.lookup_repr_hints(did);
1226 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1227 let mut prev_disr = None;
1228 let variants = def.variants.iter().map(|v| {
1229 let disr = match v.node.disr_expr {
1230 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1231 None => next_disr(tcx, v, repr_type, prev_disr)
1232 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1234 let v = convert_enum_variant(tcx, v, disr);
1235 prev_disr = Some(disr);
1238 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1241 /// Ensures that the super-predicates of the trait with def-id
1242 /// trait_def_id are converted and stored. This does NOT ensure that
1243 /// the transitive super-predicates are converted; that is the job of
1244 /// the `ensure_super_predicates()` method in the `AstConv` impl
1245 /// above. Returns a list of trait def-ids that must be ensured as
1246 /// well to guarantee that the transitive superpredicates are
1248 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1249 trait_def_id: DefId)
1254 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1256 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1259 // If this trait comes from an external crate, then all of the
1260 // supertraits it may depend on also must come from external
1261 // crates, and hence all of them already have their
1262 // super-predicates "converted" (and available from crate
1263 // meta-data), so there is no need to transitively test them.
1267 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1268 let superpredicates = superpredicates.unwrap_or_else(|| {
1269 let item = match ccx.tcx.map.get(trait_node_id) {
1270 hir_map::NodeItem(item) => item,
1271 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1274 let (generics, bounds) = match item.node {
1275 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1276 _ => tcx.sess.span_bug(item.span,
1277 "ensure_super_predicates_step invoked on non-trait"),
1280 // In-scope when converting the superbounds for `Trait` are
1281 // that `Self:Trait` as well as any bounds that appear on the
1283 let trait_def = trait_def_of_item(ccx, item);
1284 let self_predicate = ty::GenericPredicates {
1285 predicates: VecPerParamSpace::new(vec![],
1286 vec![trait_def.trait_ref.to_predicate()],
1289 let scope = &(generics, &self_predicate);
1291 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1292 let self_param_ty = tcx.mk_self_type();
1293 let superbounds1 = compute_bounds(&ccx.icx(scope),
1299 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1301 // Convert any explicit superbounds in the where clause,
1302 // e.g. `trait Foo where Self : Bar`:
1303 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1305 // Combine the two lists to form the complete set of superbounds:
1306 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1307 let superpredicates = ty::GenericPredicates {
1308 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1310 debug!("superpredicates for trait {:?} = {:?}",
1311 tcx.map.local_def_id(item.id),
1314 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1319 let def_ids: Vec<_> = superpredicates.predicates
1321 .filter_map(|p| p.to_opt_poly_trait_ref())
1322 .map(|tr| tr.def_id())
1325 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1330 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1332 -> &'tcx ty::TraitDef<'tcx>
1334 let def_id = ccx.tcx.map.local_def_id(it.id);
1337 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1341 let (unsafety, generics, items) = match it.node {
1342 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1343 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1346 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1347 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1348 ccx.tcx.sess.span_err(
1350 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1351 which traits can use parenthetical notation");
1352 fileline_help!(ccx.tcx.sess, it.span,
1353 "add `#![feature(unboxed_closures)]` to \
1354 the crate attributes to use it");
1357 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1359 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1361 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1362 match trait_item.node {
1363 hir::TypeTraitItem(..) => Some(trait_item.name),
1368 let trait_ref = ty::TraitRef {
1373 let trait_def = ty::TraitDef {
1374 paren_sugar: paren_sugar,
1376 generics: ty_generics,
1377 trait_ref: trait_ref,
1378 associated_type_names: associated_type_names,
1379 nonblanket_impls: RefCell::new(FnvHashMap()),
1380 blanket_impls: RefCell::new(vec![]),
1381 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1384 return tcx.intern_trait_def(trait_def);
1386 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1387 generics: &hir::Generics)
1392 // Creates a no-op substitution for the trait's type parameters.
1397 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1398 def_id: tcx.map.local_def_id(def.lifetime.id),
1401 name: def.lifetime.name
1405 // Start with the generics in the type parameters...
1410 .map(|(i, def)| tcx.mk_param(TypeSpace,
1411 i as u32, def.name))
1414 // ...and also create the `Self` parameter.
1415 let self_ty = tcx.mk_self_type();
1417 Substs::new_trait(types, regions, self_ty)
1421 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1422 trait_node_id: ast::NodeId,
1423 assoc_name: ast::Name)
1426 let item = match ccx.tcx.map.get(trait_node_id) {
1427 hir_map::NodeItem(item) => item,
1428 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1431 let trait_items = match item.node {
1432 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1433 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1436 trait_items.iter().any(|trait_item| {
1437 match trait_item.node {
1438 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1444 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1446 let trait_def = trait_def_of_item(ccx, it);
1448 let def_id = ccx.tcx.map.local_def_id(it.id);
1450 let (generics, items) = match it.node {
1451 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1455 &format!("trait_def_of_item invoked on {:?}", s));
1459 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1461 // `ty_generic_predicates` below will consider the bounds on the type
1462 // parameters (including `Self`) and the explicit where-clauses,
1463 // but to get the full set of predicates on a trait we need to add
1464 // in the supertrait bounds and anything declared on the
1465 // associated types.
1466 let mut base_predicates = super_predicates;
1468 // Add in a predicate that `Self:Trait` (where `Trait` is the
1469 // current trait). This is needed for builtin bounds.
1470 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1471 base_predicates.predicates.push(SelfSpace, self_predicate);
1473 // add in the explicit where-clauses
1474 let mut trait_predicates =
1475 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1477 let assoc_predicates = predicates_for_associated_types(ccx,
1480 trait_def.trait_ref,
1482 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1484 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1485 assert!(prev_predicates.is_none());
1489 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1490 ast_generics: &hir::Generics,
1491 trait_predicates: &ty::GenericPredicates<'tcx>,
1492 self_trait_ref: ty::TraitRef<'tcx>,
1493 trait_items: &[hir::TraitItem])
1494 -> Vec<ty::Predicate<'tcx>>
1496 trait_items.iter().flat_map(|trait_item| {
1497 let bounds = match trait_item.node {
1498 hir::TypeTraitItem(ref bounds, _) => bounds,
1500 return vec!().into_iter();
1504 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1507 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1510 SizedByDefault::Yes,
1513 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1518 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1520 -> ty::TypeScheme<'tcx>
1522 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1523 match ccx.tcx.map.find(node_id) {
1524 Some(hir_map::NodeItem(item)) => {
1525 type_scheme_of_item(ccx, &*item)
1527 Some(hir_map::NodeForeignItem(foreign_item)) => {
1528 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1529 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1532 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1533 in get_item_type_scheme(): {:?}",
1538 ccx.tcx.lookup_item_type(def_id)
1542 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1544 -> ty::TypeScheme<'tcx>
1546 memoized(&ccx.tcx.tcache,
1547 ccx.tcx.map.local_def_id(it.id),
1548 |_| compute_type_scheme_of_item(ccx, it))
1551 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1553 -> ty::TypeScheme<'tcx>
1557 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1558 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1559 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1561 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1562 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1563 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1564 let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1565 ty::TypeScheme { ty: ty, generics: ty_generics }
1567 hir::ItemTy(ref t, ref generics) => {
1568 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1569 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1570 ty::TypeScheme { ty: ty, generics: ty_generics }
1572 hir::ItemEnum(ref ei, ref generics) => {
1573 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1574 let substs = mk_item_substs(ccx, &ty_generics);
1575 let def = convert_enum_def(tcx, it, ei);
1576 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1577 ty::TypeScheme { ty: t, generics: ty_generics }
1579 hir::ItemStruct(ref si, ref generics) => {
1580 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1581 let substs = mk_item_substs(ccx, &ty_generics);
1582 let def = convert_struct_def(tcx, it, si);
1583 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1584 ty::TypeScheme { ty: t, generics: ty_generics }
1586 hir::ItemDefaultImpl(..) |
1587 hir::ItemTrait(..) |
1590 hir::ItemForeignMod(..) |
1591 hir::ItemExternCrate(..) |
1592 hir::ItemUse(..) => {
1595 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1601 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1603 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1607 let tag = type_scheme_of_item(ccx, it);
1608 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1609 let predicates = match it.node {
1610 hir::ItemStatic(..) | hir::ItemConst(..) => {
1611 ty::GenericPredicates::empty()
1613 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1614 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1616 hir::ItemTy(_, ref generics) => {
1617 ty_generic_predicates_for_type_or_impl(ccx, generics)
1619 hir::ItemEnum(_, ref generics) => {
1620 ty_generic_predicates_for_type_or_impl(ccx, generics)
1622 hir::ItemStruct(_, ref generics) => {
1623 ty_generic_predicates_for_type_or_impl(ccx, generics)
1625 hir::ItemDefaultImpl(..) |
1626 hir::ItemTrait(..) |
1627 hir::ItemExternCrate(..) |
1631 hir::ItemForeignMod(..) => {
1634 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1639 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1640 predicates.clone());
1641 assert!(prev_predicates.is_none());
1644 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1645 let object_lifetime_default_reprs: String =
1646 scheme.generics.types.iter()
1647 .map(|t| match t.object_lifetime_default {
1648 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1649 d => format!("{:?}", d),
1651 .collect::<Vec<String>>()
1654 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1657 return (scheme, predicates);
1660 fn type_scheme_of_foreign_item<'a, 'tcx>(
1661 ccx: &CrateCtxt<'a, 'tcx>,
1662 it: &hir::ForeignItem,
1664 -> ty::TypeScheme<'tcx>
1666 memoized(&ccx.tcx.tcache,
1667 ccx.tcx.map.local_def_id(it.id),
1668 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1671 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1672 ccx: &CrateCtxt<'a, 'tcx>,
1673 it: &hir::ForeignItem,
1675 -> ty::TypeScheme<'tcx>
1678 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1679 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1681 hir::ForeignItemStatic(ref t, _) => {
1683 generics: ty::Generics::empty(),
1684 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1690 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1691 it: &hir::ForeignItem)
1693 // For reasons I cannot fully articulate, I do so hate the AST
1694 // map, and I regard each time that I use it as a personal and
1695 // moral failing, but at the moment it seems like the only
1696 // convenient way to extract the ABI. - ndm
1698 let abi = tcx.map.get_foreign_abi(it.id);
1700 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1701 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1703 let predicates = match it.node {
1704 hir::ForeignItemFn(_, ref generics) => {
1705 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1707 hir::ForeignItemStatic(..) => {
1708 ty::GenericPredicates::empty()
1712 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1714 assert!(prev_predicates.is_none());
1717 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1718 generics: &hir::Generics)
1719 -> ty::Generics<'tcx> {
1720 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1723 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1724 generics: &hir::Generics)
1725 -> ty::GenericPredicates<'tcx>
1727 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1730 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1731 trait_id: ast::NodeId,
1732 substs: &'tcx Substs<'tcx>,
1733 ast_generics: &hir::Generics)
1734 -> ty::Generics<'tcx>
1736 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1737 ccx.tcx.map.local_def_id(trait_id), substs);
1739 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1741 // Add in the self type parameter.
1743 // Something of a hack: use the node id for the trait, also as
1744 // the node id for the Self type parameter.
1745 let param_id = trait_id;
1747 let parent = ccx.tcx.map.get_parent(param_id);
1749 let def = ty::TypeParameterDef {
1752 name: special_idents::type_self.name,
1753 def_id: ccx.tcx.map.local_def_id(param_id),
1754 default_def_id: ccx.tcx.map.local_def_id(parent),
1756 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1759 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1761 generics.types.push(SelfSpace, def);
1766 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1767 generics: &hir::Generics,
1768 base_generics: &ty::Generics<'tcx>)
1769 -> ty::Generics<'tcx>
1771 ty_generics(ccx, FnSpace, generics, base_generics)
1774 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1775 generics: &hir::Generics,
1776 base_predicates: &ty::GenericPredicates<'tcx>)
1777 -> ty::GenericPredicates<'tcx>
1779 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1782 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1783 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1784 bounds: &mut ty::BuiltinBounds,
1785 ast_bounds: &[hir::TyParamBound],
1788 let tcx = astconv.tcx();
1790 // Try to find an unbound in bounds.
1791 let mut unbound = None;
1792 for ab in ast_bounds {
1793 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1794 if unbound.is_none() {
1795 assert!(ptr.bound_lifetimes.is_empty());
1796 unbound = Some(ptr.trait_ref.clone());
1798 span_err!(tcx.sess, span, E0203,
1799 "type parameter has more than one relaxed default \
1800 bound, only one is supported");
1805 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1808 // FIXME(#8559) currently requires the unbound to be built-in.
1809 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1811 Ok(kind_id) if trait_def_id != kind_id => {
1812 tcx.sess.span_warn(span,
1813 "default bound relaxed for a type parameter, but \
1814 this does nothing because the given bound is not \
1815 a default. Only `?Sized` is supported");
1816 tcx.try_add_builtin_trait(kind_id, bounds);
1821 _ if kind_id.is_ok() => {
1822 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1824 // No lang item for Sized, so we can't add it as a bound.
1829 /// Returns the early-bound lifetimes declared in this generics
1830 /// listing. For anything other than fns/methods, this is just all
1831 /// the lifetimes that are declared. For fns or methods, we have to
1832 /// screen out those that do not appear in any where-clauses etc using
1833 /// `resolve_lifetime::early_bound_lifetimes`.
1834 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1835 ast_generics: &hir::Generics)
1836 -> Vec<hir::LifetimeDef>
1839 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1840 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1844 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1846 ast_generics: &hir::Generics,
1847 base_predicates: &ty::GenericPredicates<'tcx>)
1848 -> ty::GenericPredicates<'tcx>
1851 let mut result = base_predicates.clone();
1853 // Collect the predicates that were written inline by the user on each
1854 // type parameter (e.g., `<T:Foo>`).
1855 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1856 let index = index as u32;
1857 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1858 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1861 SizedByDefault::Yes,
1863 let predicates = bounds.predicates(ccx.tcx, param_ty);
1864 result.predicates.extend(space, predicates.into_iter());
1867 // Collect the region predicates that were declared inline as
1868 // well. In the case of parameters declared on a fn or method, we
1869 // have to be careful to only iterate over early-bound regions.
1870 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1871 for (index, param) in early_lifetimes.iter().enumerate() {
1872 let index = index as u32;
1873 let def_id = tcx.map.local_def_id(param.lifetime.id);
1875 ty::ReEarlyBound(ty::EarlyBoundRegion {
1879 name: param.lifetime.name
1881 for bound in ¶m.bounds {
1882 let bound_region = ast_region_to_region(ccx.tcx, bound);
1883 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1884 result.predicates.push(space, outlives.to_predicate());
1888 // Add in the bounds that appear in the where-clause
1889 let where_clause = &ast_generics.where_clause;
1890 for predicate in &where_clause.predicates {
1892 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1893 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1895 &*bound_pred.bounded_ty);
1897 for bound in bound_pred.bounds.iter() {
1899 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1900 let mut projections = Vec::new();
1903 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1908 result.predicates.push(space, trait_ref.to_predicate());
1910 for projection in &projections {
1911 result.predicates.push(space, projection.to_predicate());
1915 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1916 let region = ast_region_to_region(tcx, lifetime);
1917 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1918 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1924 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1925 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1926 for bound in ®ion_pred.bounds {
1927 let r2 = ast_region_to_region(tcx, bound);
1928 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1929 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1933 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1935 tcx.sess.span_bug(eq_pred.span,
1936 "Equality constraints are not yet \
1937 implemented (#20041)")
1945 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1947 ast_generics: &hir::Generics,
1948 base_generics: &ty::Generics<'tcx>)
1949 -> ty::Generics<'tcx>
1952 let mut result = base_generics.clone();
1954 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1955 for (i, l) in early_lifetimes.iter().enumerate() {
1956 let bounds = l.bounds.iter()
1957 .map(|l| ast_region_to_region(tcx, l))
1959 let def = ty::RegionParameterDef { name: l.lifetime.name,
1962 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1964 result.regions.push(space, def);
1967 assert!(result.types.is_empty_in(space));
1969 // Now create the real type parameters.
1970 for i in 0..ast_generics.ty_params.len() {
1971 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1972 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1973 result.types.push(space, def);
1979 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1985 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1987 for leaf_ty in ty.walk() {
1988 if let ty::TyParam(p) = leaf_ty.sty {
1989 if p.space == space && p.idx >= index {
1990 span_err!(ccx.tcx.sess, path.span, E0128,
1991 "type parameters with a default cannot use \
1992 forward declared identifiers");
1994 return ccx.tcx.types.err
2002 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2003 ast_generics: &hir::Generics,
2006 -> ty::TypeParameterDef<'tcx>
2008 let param = &ast_generics.ty_params[index as usize];
2011 match tcx.ty_param_defs.borrow().get(¶m.id) {
2012 Some(d) => { return d.clone(); }
2016 let default = param.default.as_ref().map(
2017 |def| convert_default_type_parameter(ccx, def, space, index)
2020 let object_lifetime_default =
2021 compute_object_lifetime_default(ccx, param.id,
2022 ¶m.bounds, &ast_generics.where_clause);
2024 let parent = tcx.map.get_parent(param.id);
2026 let def = ty::TypeParameterDef {
2030 def_id: ccx.tcx.map.local_def_id(param.id),
2031 default_def_id: ccx.tcx.map.local_def_id(parent),
2033 object_lifetime_default: object_lifetime_default,
2036 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2041 /// Scan the bounds and where-clauses on a parameter to extract bounds
2042 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2043 /// This runs as part of computing the minimal type scheme, so we
2044 /// intentionally avoid just asking astconv to convert all the where
2045 /// clauses into a `ty::Predicate`. This is because that could induce
2046 /// artificial cycles.
2047 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2048 param_id: ast::NodeId,
2049 param_bounds: &[hir::TyParamBound],
2050 where_clause: &hir::WhereClause)
2051 -> ty::ObjectLifetimeDefault
2053 let inline_bounds = from_bounds(ccx, param_bounds);
2054 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2055 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2056 .chain(where_bounds)
2058 return if all_bounds.len() > 1 {
2059 ty::ObjectLifetimeDefault::Ambiguous
2060 } else if all_bounds.len() == 0 {
2061 ty::ObjectLifetimeDefault::BaseDefault
2063 ty::ObjectLifetimeDefault::Specific(
2064 all_bounds.into_iter().next().unwrap())
2067 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2068 bounds: &[hir::TyParamBound])
2072 .filter_map(|bound| {
2074 hir::TraitTyParamBound(..) =>
2076 hir::RegionTyParamBound(ref lifetime) =>
2077 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2083 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2084 param_id: ast::NodeId,
2085 predicates: &[hir::WherePredicate])
2089 .flat_map(|predicate| {
2091 hir::WherePredicate::BoundPredicate(ref data) => {
2092 if data.bound_lifetimes.is_empty() &&
2093 is_param(ccx.tcx, &data.bounded_ty, param_id)
2095 from_bounds(ccx, &data.bounds).into_iter()
2097 Vec::new().into_iter()
2100 hir::WherePredicate::RegionPredicate(..) |
2101 hir::WherePredicate::EqPredicate(..) => {
2102 Vec::new().into_iter()
2110 enum SizedByDefault { Yes, No, }
2112 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2113 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2114 /// built-in trait (formerly known as kind): Send.
2115 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2116 param_ty: ty::Ty<'tcx>,
2117 ast_bounds: &[hir::TyParamBound],
2118 sized_by_default: SizedByDefault,
2120 -> astconv::Bounds<'tcx>
2123 conv_param_bounds(astconv,
2128 if let SizedByDefault::Yes = sized_by_default {
2129 add_unsized_bound(astconv,
2130 &mut bounds.builtin_bounds,
2135 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2140 /// Converts a specific TyParamBound from the AST into a set of
2141 /// predicates that apply to the self-type. A vector is returned
2142 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2143 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2144 /// and `<T as Bar>::X == i32`).
2145 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2147 bound: &hir::TyParamBound)
2148 -> Vec<ty::Predicate<'tcx>>
2151 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2152 let mut projections = Vec::new();
2153 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2154 projections.into_iter()
2155 .map(|p| p.to_predicate())
2156 .chain(Some(pred.to_predicate()))
2159 hir::RegionTyParamBound(ref lifetime) => {
2160 let region = ast_region_to_region(astconv.tcx(), lifetime);
2161 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2162 vec![ty::Predicate::TypeOutlives(pred)]
2164 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2170 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2172 trait_ref: &hir::PolyTraitRef,
2173 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2174 -> ty::PolyTraitRef<'tcx>
2176 astconv::instantiate_poly_trait_ref(astconv,
2183 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2185 param_ty: ty::Ty<'tcx>,
2186 ast_bounds: &[hir::TyParamBound])
2187 -> astconv::Bounds<'tcx>
2189 let tcx = astconv.tcx();
2190 let astconv::PartitionedBounds {
2194 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2196 let mut projection_bounds = Vec::new();
2198 let trait_bounds: Vec<ty::PolyTraitRef> =
2200 .map(|bound| conv_poly_trait_ref(astconv,
2203 &mut projection_bounds))
2206 let region_bounds: Vec<ty::Region> =
2207 region_bounds.into_iter()
2208 .map(|r| ast_region_to_region(tcx, r))
2212 region_bounds: region_bounds,
2213 builtin_bounds: builtin_bounds,
2214 trait_bounds: trait_bounds,
2215 projection_bounds: projection_bounds,
2219 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2220 ccx: &CrateCtxt<'a, 'tcx>,
2222 ast_generics: &hir::Generics,
2224 -> ty::TypeScheme<'tcx>
2226 for i in &decl.inputs {
2227 match (*i).pat.node {
2228 hir::PatIdent(_, _, _) => (),
2231 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2232 "patterns aren't allowed in foreign function declarations");
2237 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2239 let rb = BindingRscope::new();
2240 let input_tys = decl.inputs
2242 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2245 let output = match decl.output {
2246 hir::Return(ref ty) =>
2247 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2248 hir::DefaultReturn(..) =>
2249 ty::FnConverging(ccx.tcx.mk_nil()),
2250 hir::NoReturn(..) =>
2254 let t_fn = ccx.tcx.mk_fn(None,
2255 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2257 unsafety: hir::Unsafety::Unsafe,
2258 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2260 variadic: decl.variadic}),
2264 generics: ty_generics,
2269 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2270 ty_generics: &ty::Generics<'tcx>)
2274 ty_generics.types.map(
2275 |def| ccx.tcx.mk_param_from_def(def));
2278 ty_generics.regions.map(
2279 |def| def.to_early_bound_region());
2281 Substs::new(types, regions)
2284 /// Verifies that the explicit self type of a method matches the impl
2285 /// or trait. This is a bit weird but basically because right now we
2286 /// don't handle the general case, but instead map it to one of
2287 /// several pre-defined options using various heuristics, this method
2288 /// comes back to check after the fact that explicit type the user
2289 /// wrote actually matches what the pre-defined option said.
2290 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2291 ccx: &CrateCtxt<'a, 'tcx>,
2293 method_type: Rc<ty::Method<'tcx>>,
2294 required_type: Ty<'tcx>,
2295 explicit_self: &hir::ExplicitSelf,
2296 body_scope: region::CodeExtent,
2297 body_id: ast::NodeId)
2300 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2301 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2302 let base_type = match typ.sty {
2303 ty::TyRef(_, tm) => tm.ty,
2304 ty::TyBox(typ) => typ,
2308 // "Required type" comes from the trait definition. It may
2309 // contain late-bound regions from the method, but not the
2310 // trait (since traits only have early-bound region
2312 assert!(!base_type.has_regions_escaping_depth(1));
2313 let required_type_free =
2314 liberate_early_bound_regions(
2316 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2318 // The "base type" comes from the impl. It too may have late-bound
2319 // regions from the method.
2320 assert!(!base_type.has_regions_escaping_depth(1));
2321 let base_type_free =
2322 liberate_early_bound_regions(
2324 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2326 debug!("required_type={:?} required_type_free={:?} \
2327 base_type={:?} base_type_free={:?}",
2333 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2334 drop(::require_same_types(tcx,
2341 format!("mismatched self type: expected `{}`",
2345 // We could conceviably add more free-region relations here,
2346 // but since this code is just concerned with checking that
2347 // the `&Self` types etc match up, it's not really necessary.
2348 // It would just allow people to be more approximate in some
2349 // cases. In any case, we can do it later as we feel the need;
2350 // I'd like this function to go away eventually.
2351 let free_regions = FreeRegionMap::new();
2353 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2356 fn liberate_early_bound_regions<'tcx,T>(
2357 tcx: &ty::ctxt<'tcx>,
2358 scope: region::CodeExtent,
2361 where T : TypeFoldable<'tcx>
2364 * Convert early-bound regions into free regions; normally this is done by
2365 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2366 * method-self-type check is kind of hacky and done very early in the process,
2367 * before we really have a `ParameterEnvironment` to check.
2370 tcx.fold_regions(value, &mut false, |region, _| {
2372 ty::ReEarlyBound(data) => {
2373 ty::ReFree(ty::FreeRegion {
2375 bound_region: ty::BrNamed(data.def_id, data.name)
2384 /// Checks that all the type parameters on an impl
2385 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2386 ast_generics: &hir::Generics,
2387 impl_predicates: &mut ty::GenericPredicates<'tcx>,
2390 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2391 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2393 assert!(impl_predicates.predicates.is_empty_in(FnSpace));
2394 assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
2396 // The trait reference is an input, so find all type parameters
2397 // reachable from there, to start (if this is an inherent impl,
2398 // then just examine the self type).
2399 let mut input_parameters: HashSet<_> =
2400 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2401 if let Some(ref trait_ref) = impl_trait_ref {
2402 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2405 ctp::setup_constraining_predicates(tcx,
2406 impl_predicates.predicates.get_mut_slice(TypeSpace),
2408 &mut input_parameters);
2410 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2411 let param_ty = ty::ParamTy { space: TypeSpace,
2413 name: ty_param.name };
2414 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2415 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2420 fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2421 ast_generics: &hir::Generics,
2423 impl_items: &[hir::ImplItem])
2425 // Every lifetime used in an associated type must be constrained.
2426 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2427 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2428 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2430 let mut input_parameters: HashSet<_> =
2431 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2432 if let Some(ref trait_ref) = impl_trait_ref {
2433 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2435 ctp::identify_constrained_type_params(tcx,
2436 &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
2438 let lifetimes_in_associated_types: HashSet<_> =
2440 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2441 .filter_map(|item| match item {
2442 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2443 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2445 .flat_map(|ty| ctp::parameters_for_type(ty, true))
2446 .filter_map(|p| match p {
2447 ctp::Parameter::Type(_) => None,
2448 ctp::Parameter::Region(r) => Some(r),
2452 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2453 let def_id = tcx.map.local_def_id(lifetime_def.lifetime.id);
2454 let region = ty::EarlyBoundRegion { def_id: def_id,
2456 index: index as u32,
2457 name: lifetime_def.lifetime.name };
2459 lifetimes_in_associated_types.contains(®ion) && // (*)
2460 !input_parameters.contains(&ctp::Parameter::Region(region))
2462 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2463 "lifetime", ®ion.name.to_string());
2467 // (*) This is a horrible concession to reality. I think it'd be
2468 // better to just ban unconstrianed lifetimes outright, but in
2469 // practice people do non-hygenic macros like:
2472 // macro_rules! __impl_slice_eq1 {
2473 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2474 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2481 // In a concession to backwards compatbility, we continue to
2482 // permit those, so long as the lifetimes aren't used in
2483 // associated types. I believe this is sound, because lifetimes
2484 // used elsewhere are not projected back out.
2487 fn report_unused_parameter(tcx: &ty::ctxt,
2492 span_err!(tcx.sess, span, E0207,
2493 "the {} parameter `{}` is not constrained by the \
2494 impl trait, self type, or predicates",