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 two 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):
42 1. Trait/Type definitions
44 Conversion itself is done by simply walking each of the items in turn
45 and invoking an appropriate function (e.g., `trait_def_of_item` or
46 `convert_item`). However, it is possible that while converting an
47 item, we may need to compute the *type scheme* or *trait definition*
50 There are some shortcomings in this design:
52 - Before walking the set of supertraits for a given trait, you must
53 call `ensure_super_predicates` on that trait def-id. Otherwise,
54 `lookup_super_predicates` will result in ICEs.
55 - Because the type scheme includes defaults, cycles through type
56 parameter defaults are illegal even if those defaults are never
57 employed. This is not necessarily a bug.
61 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
64 use middle::def_id::DefId;
65 use constrained_type_params as ctp;
66 use middle::lang_items::SizedTraitLangItem;
67 use middle::resolve_lifetime;
68 use middle::const_eval::{self, ConstVal};
69 use middle::const_eval::EvalHint::UncheckedExprHint;
70 use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
71 use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
72 use middle::ty::{self, ToPolyTraitRef, Ty, TypeScheme};
73 use middle::ty::{VariantKind};
74 use middle::ty::fold::{TypeFolder};
75 use middle::ty::util::IntTypeExt;
77 use rustc::dep_graph::DepNode;
78 use rustc::front::map as hir_map;
79 use util::common::{ErrorReported, MemoizationMap};
80 use util::nodemap::{FnvHashMap, FnvHashSet};
83 use std::cell::RefCell;
84 use std::collections::HashSet;
90 use syntax::codemap::Span;
91 use syntax::parse::token::special_idents;
93 use rustc_front::hir::{self, PatKind};
94 use rustc_front::intravisit;
95 use rustc_front::print::pprust;
97 ///////////////////////////////////////////////////////////////////////////
100 pub fn collect_item_types(tcx: &ty::ctxt) {
101 let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) };
102 let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
103 ccx.tcx.visit_all_items_in_krate(DepNode::CollectItem, &mut visitor);
106 ///////////////////////////////////////////////////////////////////////////
108 struct CrateCtxt<'a,'tcx:'a> {
109 tcx: &'a ty::ctxt<'tcx>,
111 // This stack is used to identify cycles in the user's source.
112 // Note that these cycles can cross multiple items.
113 stack: RefCell<Vec<AstConvRequest>>,
116 /// Context specific to some particular item. This is what implements
117 /// AstConv. It has information about the predicates that are defined
118 /// on the trait. Unfortunately, this predicate information is
119 /// available in various different forms at various points in the
120 /// process. So we can't just store a pointer to e.g. the AST or the
121 /// parsed ty form, we have to be more flexible. To this end, the
122 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
123 /// that it uses to satisfy `get_type_parameter_bounds` requests.
124 /// This object might draw the information from the AST
125 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
126 /// or both (a tuple).
127 struct ItemCtxt<'a,'tcx:'a> {
128 ccx: &'a CrateCtxt<'a,'tcx>,
129 param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
132 #[derive(Copy, Clone, PartialEq, Eq)]
133 enum AstConvRequest {
134 GetItemTypeScheme(DefId),
136 EnsureSuperPredicates(DefId),
137 GetTypeParameterBounds(ast::NodeId),
140 ///////////////////////////////////////////////////////////////////////////
142 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
143 ccx: &'a CrateCtxt<'a, 'tcx>
146 impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
147 fn visit_item(&mut self, item: &hir::Item) {
148 convert_item(self.ccx, item);
152 ///////////////////////////////////////////////////////////////////////////
153 // Utility types and common code for the above passes.
155 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
156 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
157 ItemCtxt { ccx: self, param_bounds: param_bounds }
160 fn cycle_check<F,R>(&self,
162 request: AstConvRequest,
164 -> Result<R,ErrorReported>
165 where F: FnOnce() -> Result<R,ErrorReported>
168 let mut stack = self.stack.borrow_mut();
169 match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
172 let cycle = &stack[i..];
173 self.report_cycle(span, cycle);
174 return Err(ErrorReported);
182 self.stack.borrow_mut().pop();
186 fn report_cycle(&self,
188 cycle: &[AstConvRequest])
190 assert!(!cycle.is_empty());
193 let mut err = struct_span_err!(tcx.sess, span, E0391,
194 "unsupported cyclic reference between types/traits detected");
197 AstConvRequest::GetItemTypeScheme(def_id) |
198 AstConvRequest::GetTraitDef(def_id) => {
200 &format!("the cycle begins when processing `{}`...",
201 tcx.item_path_str(def_id)));
203 AstConvRequest::EnsureSuperPredicates(def_id) => {
205 &format!("the cycle begins when computing the supertraits of `{}`...",
206 tcx.item_path_str(def_id)));
208 AstConvRequest::GetTypeParameterBounds(id) => {
209 let def = tcx.type_parameter_def(id);
211 &format!("the cycle begins when computing the bounds \
212 for type parameter `{}`...",
217 for request in &cycle[1..] {
219 AstConvRequest::GetItemTypeScheme(def_id) |
220 AstConvRequest::GetTraitDef(def_id) => {
222 &format!("...which then requires processing `{}`...",
223 tcx.item_path_str(def_id)));
225 AstConvRequest::EnsureSuperPredicates(def_id) => {
227 &format!("...which then requires computing the supertraits of `{}`...",
228 tcx.item_path_str(def_id)));
230 AstConvRequest::GetTypeParameterBounds(id) => {
231 let def = tcx.type_parameter_def(id);
233 &format!("...which then requires computing the bounds \
234 for type parameter `{}`...",
241 AstConvRequest::GetItemTypeScheme(def_id) |
242 AstConvRequest::GetTraitDef(def_id) => {
244 &format!("...which then again requires processing `{}`, completing the cycle.",
245 tcx.item_path_str(def_id)));
247 AstConvRequest::EnsureSuperPredicates(def_id) => {
249 &format!("...which then again requires computing the supertraits of `{}`, \
250 completing the cycle.",
251 tcx.item_path_str(def_id)));
253 AstConvRequest::GetTypeParameterBounds(id) => {
254 let def = tcx.type_parameter_def(id);
256 &format!("...which then again requires computing the bounds \
257 for type parameter `{}`, completing the cycle.",
264 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
265 fn get_trait_def(&self, trait_id: DefId)
266 -> &'tcx ty::TraitDef<'tcx>
270 if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
271 let item = match tcx.map.get(trait_id) {
272 hir_map::NodeItem(item) => item,
273 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
276 trait_def_of_item(self, &item)
278 tcx.lookup_trait_def(trait_id)
282 /// Ensure that the (transitive) super predicates for
283 /// `trait_def_id` are available. This will report a cycle error
284 /// if a trait `X` (transitively) extends itself in some form.
285 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
286 -> Result<(), ErrorReported>
288 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
289 let def_ids = ensure_super_predicates_step(self, trait_def_id);
291 for def_id in def_ids {
292 try!(self.ensure_super_predicates(span, def_id));
300 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
301 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
302 ast_ty_to_ty(self, rs, ast_ty)
306 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
307 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
309 fn get_item_type_scheme(&self, span: Span, id: DefId)
310 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
312 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
313 Ok(type_scheme_of_def_id(self.ccx, id))
317 fn get_trait_def(&self, span: Span, id: DefId)
318 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
320 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
321 Ok(self.ccx.get_trait_def(id))
325 fn ensure_super_predicates(&self,
328 -> Result<(), ErrorReported>
330 debug!("ensure_super_predicates(trait_def_id={:?})",
333 self.ccx.ensure_super_predicates(span, trait_def_id)
337 fn get_type_parameter_bounds(&self,
339 node_id: ast::NodeId)
340 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
342 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
343 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
345 .filter_map(|p| p.to_opt_poly_trait_ref())
351 fn trait_defines_associated_type_named(&self,
353 assoc_name: ast::Name)
356 if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
357 trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
359 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
360 trait_def.associated_type_names.contains(&assoc_name)
365 _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
366 _substs: Option<&mut Substs<'tcx>>,
367 _space: Option<ParamSpace>,
368 span: Span) -> Ty<'tcx> {
369 span_err!(self.tcx().sess, span, E0121,
370 "the type placeholder `_` is not allowed within types on item signatures");
374 fn projected_ty(&self,
376 trait_ref: ty::TraitRef<'tcx>,
377 item_name: ast::Name)
380 self.tcx().mk_projection(trait_ref, item_name)
384 /// Interface used to find the bounds on a type parameter from within
385 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
386 trait GetTypeParameterBounds<'tcx> {
387 fn get_type_parameter_bounds(&self,
388 astconv: &AstConv<'tcx>,
390 node_id: ast::NodeId)
391 -> Vec<ty::Predicate<'tcx>>;
394 /// Find bounds from both elements of the tuple.
395 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
396 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
398 fn get_type_parameter_bounds(&self,
399 astconv: &AstConv<'tcx>,
401 node_id: ast::NodeId)
402 -> Vec<ty::Predicate<'tcx>>
404 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
405 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
410 /// Empty set of bounds.
411 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
412 fn get_type_parameter_bounds(&self,
413 _astconv: &AstConv<'tcx>,
415 _node_id: ast::NodeId)
416 -> Vec<ty::Predicate<'tcx>>
422 /// Find bounds from the parsed and converted predicates. This is
423 /// used when converting methods, because by that time the predicates
424 /// from the trait/impl have been fully converted.
425 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
426 fn get_type_parameter_bounds(&self,
427 astconv: &AstConv<'tcx>,
429 node_id: ast::NodeId)
430 -> Vec<ty::Predicate<'tcx>>
432 let def = astconv.tcx().type_parameter_def(node_id);
436 .filter(|predicate| {
438 ty::Predicate::Trait(ref data) => {
439 data.skip_binder().self_ty().is_param(def.space, def.index)
441 ty::Predicate::TypeOutlives(ref data) => {
442 data.skip_binder().0.is_param(def.space, def.index)
444 ty::Predicate::Equate(..) |
445 ty::Predicate::RegionOutlives(..) |
446 ty::Predicate::WellFormed(..) |
447 ty::Predicate::ObjectSafe(..) |
448 ty::Predicate::Projection(..) => {
458 /// Find bounds from hir::Generics. This requires scanning through the
459 /// AST. We do this to avoid having to convert *all* the bounds, which
460 /// would create artificial cycles. Instead we can only convert the
461 /// bounds for a type parameter `X` if `X::Foo` is used.
462 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
463 fn get_type_parameter_bounds(&self,
464 astconv: &AstConv<'tcx>,
466 node_id: ast::NodeId)
467 -> Vec<ty::Predicate<'tcx>>
469 // In the AST, bounds can derive from two places. Either
470 // written inline like `<T:Foo>` or in a where clause like
473 let def = astconv.tcx().type_parameter_def(node_id);
474 let ty = astconv.tcx().mk_param_from_def(&def);
479 .filter(|p| p.id == node_id)
480 .flat_map(|p| p.bounds.iter())
481 .flat_map(|b| predicates_from_bound(astconv, ty, b));
483 let from_where_clauses =
487 .filter_map(|wp| match *wp {
488 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
491 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
492 .flat_map(|bp| bp.bounds.iter())
493 .flat_map(|b| predicates_from_bound(astconv, ty, b));
495 from_ty_params.chain(from_where_clauses).collect()
499 /// Tests whether this is the AST for a reference to the type
500 /// parameter with id `param_id`. We use this so as to avoid running
501 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
502 /// conversion of the type to avoid inducing unnecessary cycles.
503 fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
505 param_id: ast::NodeId)
508 if let hir::TyPath(None, _) = ast_ty.node {
509 let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
510 match path_res.base_def {
511 Def::SelfTy(Some(def_id), None) => {
512 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
514 Def::TyParam(_, _, def_id, _) => {
515 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
527 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
528 container: ImplOrTraitItemContainer,
531 vis: hir::Visibility,
532 sig: &hir::MethodSig,
533 untransformed_rcvr_ty: Ty<'tcx>,
534 rcvr_ty_generics: &ty::Generics<'tcx>,
535 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
536 let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
538 let ty_generic_predicates =
539 ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
541 let (fty, explicit_self_category) =
542 astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
543 sig, untransformed_rcvr_ty);
545 let def_id = ccx.tcx.map.local_def_id(id);
546 let ty_method = ty::Method::new(name,
548 ty_generic_predicates,
550 explicit_self_category,
555 let fty = ccx.tcx.mk_fn(Some(def_id),
556 ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
557 debug!("method {} (id {}) has type {:?}",
559 ccx.tcx.register_item_type(def_id, TypeScheme {
560 generics: ty_method.generics.clone(),
563 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
565 write_ty_to_tcx(ccx.tcx, id, fty);
567 debug!("writing method type: def_id={:?} mty={:?}",
570 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
571 ty::MethodTraitItem(Rc::new(ty_method)));
574 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
575 struct_generics: &ty::Generics<'tcx>,
576 struct_predicates: &ty::GenericPredicates<'tcx>,
577 v: &hir::StructField,
578 ty_f: ty::FieldDefMaster<'tcx>)
580 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &v.node.ty);
582 write_ty_to_tcx(ccx.tcx, v.node.id, tt);
584 /* add the field to the tcache */
585 ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(v.node.id),
587 generics: struct_generics.clone(),
590 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(v.node.id),
591 struct_predicates.clone());
594 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
595 container: ImplOrTraitItemContainer,
598 vis: hir::Visibility,
602 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
603 ty::GenericPredicates::empty());
605 write_ty_to_tcx(ccx.tcx, id, ty);
607 let associated_const = Rc::new(ty::AssociatedConst {
610 def_id: ccx.tcx.map.local_def_id(id),
611 container: container,
615 ccx.tcx.impl_or_trait_items.borrow_mut()
616 .insert(ccx.tcx.map.local_def_id(id), ty::ConstTraitItem(associated_const));
619 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
620 container: ImplOrTraitItemContainer,
623 vis: hir::Visibility,
624 ty: Option<Ty<'tcx>>)
626 let associated_type = Rc::new(ty::AssociatedType {
630 def_id: ccx.tcx.map.local_def_id(id),
633 ccx.tcx.impl_or_trait_items.borrow_mut()
634 .insert(ccx.tcx.map.local_def_id(id), ty::TypeTraitItem(associated_type));
637 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
639 generics: &hir::Generics,
640 thing: &'static str) {
641 let mut warn = false;
643 for ty_param in generics.ty_params.iter() {
644 for bound in ty_param.bounds.iter() {
646 hir::TraitTyParamBound(..) => {
649 hir::RegionTyParamBound(..) => { }
655 // According to accepted RFC #XXX, we should
656 // eventually accept these, but it will not be
657 // part of this PR. Still, convert to warning to
658 // make bootstrapping easier.
659 span_warn!(ccx.tcx.sess, span, E0122,
660 "trait bounds are not (yet) enforced \
666 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
668 debug!("convert: item {} with id {}", it.name, it.id);
670 // These don't define types.
671 hir::ItemExternCrate(_) | hir::ItemUse(_) | hir::ItemMod(_) => {
673 hir::ItemForeignMod(ref foreign_mod) => {
674 for item in &foreign_mod.items {
675 convert_foreign_item(ccx, item);
678 hir::ItemEnum(ref enum_definition, _) => {
679 let (scheme, predicates) = convert_typed_item(ccx, it);
680 write_ty_to_tcx(tcx, it.id, scheme.ty);
681 convert_enum_variant_types(ccx,
682 tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
685 &enum_definition.variants);
687 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
689 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
694 tcx.record_trait_has_default_impl(trait_ref.def_id);
696 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
704 // Create generics from the generics specified in the impl head.
705 debug!("convert: ast_generics={:?}", generics);
706 let def_id = ccx.tcx.map.local_def_id(it.id);
707 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
708 let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
710 debug!("convert: impl_bounds={:?}", ty_predicates);
712 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &selfty);
713 write_ty_to_tcx(tcx, it.id, selfty);
715 tcx.register_item_type(def_id,
716 TypeScheme { generics: ty_generics.clone(),
718 if let &Some(ref ast_trait_ref) = opt_trait_ref {
719 tcx.impl_trait_refs.borrow_mut().insert(
721 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
727 tcx.impl_trait_refs.borrow_mut().insert(def_id, None);
730 enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id);
731 tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
734 // If there is a trait reference, treat the methods as always public.
735 // This is to work around some incorrect behavior in privacy checking:
736 // when the method belongs to a trait, it should acquire the privacy
737 // from the trait, not the impl. Forcing the visibility to be public
738 // makes things sorta work.
739 let parent_visibility = if opt_trait_ref.is_some() {
745 // Convert all the associated consts.
746 // Also, check if there are any duplicate associated items
747 let mut seen_type_items = FnvHashSet();
748 let mut seen_value_items = FnvHashSet();
750 for impl_item in impl_items {
751 let seen_items = match impl_item.node {
752 hir::ImplItemKind::Type(_) => &mut seen_type_items,
753 _ => &mut seen_value_items,
755 if !seen_items.insert(impl_item.name) {
756 let desc = match impl_item.node {
757 hir::ImplItemKind::Const(_, _) => "associated constant",
758 hir::ImplItemKind::Type(_) => "associated type",
759 hir::ImplItemKind::Method(ref sig, _) =>
760 match sig.explicit_self.node {
761 hir::SelfStatic => "associated function",
766 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
769 if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
770 let ty = ccx.icx(&ty_predicates)
771 .to_ty(&ExplicitRscope, &ty);
772 tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
774 generics: ty_generics.clone(),
777 convert_associated_const(ccx, ImplContainer(def_id),
778 impl_item.name, impl_item.id,
779 impl_item.vis.inherit_from(parent_visibility),
780 ty, true /* has_value */);
784 // Convert all the associated types.
785 for impl_item in impl_items {
786 if let hir::ImplItemKind::Type(ref ty) = impl_item.node {
787 if opt_trait_ref.is_none() {
788 span_err!(tcx.sess, impl_item.span, E0202,
789 "associated types are not allowed in inherent impls");
792 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
794 convert_associated_type(ccx, ImplContainer(def_id),
795 impl_item.name, impl_item.id, impl_item.vis,
800 for impl_item in impl_items {
801 if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
802 // if the method specifies a visibility, use that, otherwise
803 // inherit the visibility from the impl (so `foo` in `pub impl
804 // { fn foo(); }` is public, but private in `impl { fn
806 let method_vis = impl_item.vis.inherit_from(parent_visibility);
808 convert_method(ccx, ImplContainer(def_id),
809 impl_item.name, impl_item.id, method_vis,
810 sig, selfty, &ty_generics, &ty_predicates);
814 enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
816 hir::ItemTrait(_, _, _, ref trait_items) => {
817 let trait_def = trait_def_of_item(ccx, it);
818 let def_id = trait_def.trait_ref.def_id;
819 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
820 ccx.ensure_super_predicates(it.span, def_id);
821 convert_trait_predicates(ccx, it);
822 let trait_predicates = tcx.lookup_predicates(def_id);
824 debug!("convert: trait_bounds={:?}", trait_predicates);
826 // FIXME: is the ordering here important? I think it is.
827 let container = TraitContainer(def_id);
829 // Convert all the associated constants.
830 for trait_item in trait_items {
831 if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node {
832 let ty = ccx.icx(&trait_predicates)
833 .to_ty(&ExplicitRscope, ty);
834 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
836 generics: trait_def.generics.clone(),
839 convert_associated_const(ccx,
849 // Convert all the associated types.
850 for trait_item in trait_items {
851 if let hir::TypeTraitItem(_, ref opt_ty) = trait_item.node {
852 let typ = opt_ty.as_ref().map({
853 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
856 convert_associated_type(ccx,
865 // Convert all the methods
866 for trait_item in trait_items {
867 if let hir::MethodTraitItem(ref sig, _) = trait_item.node {
881 // Add an entry mapping
882 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
883 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
884 match trait_item.node {
885 hir::ConstTraitItem(..) => ty::ConstTraitItemId(def_id),
886 hir::MethodTraitItem(..) => ty::MethodTraitItemId(def_id),
887 hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id)
890 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
893 hir::ItemStruct(ref struct_def, _) => {
894 let (scheme, predicates) = convert_typed_item(ccx, it);
895 write_ty_to_tcx(tcx, it.id, scheme.ty);
897 let it_def_id = ccx.tcx.map.local_def_id(it.id);
898 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
900 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
901 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
904 if !struct_def.is_struct() {
905 convert_variant_ctor(tcx, struct_def.id(), variant, scheme, predicates);
908 hir::ItemTy(_, ref generics) => {
909 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
910 let (scheme, _) = convert_typed_item(ccx, it);
911 write_ty_to_tcx(tcx, it.id, scheme.ty);
914 // This call populates the type cache with the converted type
915 // of the item in passing. All we have to do here is to write
916 // it into the node type table.
917 let (scheme, _) = convert_typed_item(ccx, it);
918 write_ty_to_tcx(tcx, it.id, scheme.ty);
923 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
924 ctor_id: ast::NodeId,
925 variant: ty::VariantDef<'tcx>,
926 scheme: ty::TypeScheme<'tcx>,
927 predicates: ty::GenericPredicates<'tcx>) {
928 let ctor_ty = match variant.kind() {
929 VariantKind::Unit | VariantKind::Struct => scheme.ty,
930 VariantKind::Tuple => {
934 .map(|field| field.unsubst_ty())
936 tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
941 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
942 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
943 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
945 generics: scheme.generics,
950 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
951 def: ty::AdtDefMaster<'tcx>,
952 scheme: ty::TypeScheme<'tcx>,
953 predicates: ty::GenericPredicates<'tcx>,
954 variants: &[hir::Variant]) {
955 // fill the field types
956 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
957 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
958 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
961 // Convert the ctor, if any. This also registers the variant as
963 convert_variant_ctor(
965 variant.node.data.id(),
973 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
977 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
978 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
979 let fields = def.fields().iter().map(|f| {
980 let fid = tcx.map.local_def_id(f.node.id);
982 hir::NamedField(name, vis) => {
983 let dup_span = seen_fields.get(&name).cloned();
984 if let Some(prev_span) = dup_span {
985 let mut err = struct_span_err!(tcx.sess, f.span, E0124,
986 "field `{}` is already declared",
988 span_note!(&mut err, prev_span, "previously declared here");
991 seen_fields.insert(name, f.span);
994 ty::FieldDefData::new(fid, name, vis)
996 hir::UnnamedField(vis) => {
997 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1001 ty::VariantDefData {
1006 kind: VariantKind::from_variant_data(def),
1010 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1012 def: &hir::VariantData)
1013 -> ty::AdtDefMaster<'tcx>
1016 let did = tcx.map.local_def_id(it.id);
1017 let ctor_id = if !def.is_struct() {
1018 tcx.map.local_def_id(def.id())
1024 ty::AdtKind::Struct,
1025 vec![convert_struct_variant(tcx, ctor_id, it.name, 0, def)]
1029 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1032 -> ty::AdtDefMaster<'tcx>
1034 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1036 e: &hir::Expr) -> Option<ty::Disr> {
1037 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1039 let hint = UncheckedExprHint(repr_ty);
1040 match const_eval::eval_const_expr_partial(tcx, e, hint, None) {
1041 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1042 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1044 let sign_desc = if repr_ty.is_signed() {
1049 span_err!(tcx.sess, e.span, E0079,
1050 "expected {} integer constant",
1055 let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
1056 "constant evaluation error: {}",
1058 if !e.span.contains(err.span) {
1059 diag.span_note(e.span, "for enum discriminant here");
1067 fn report_discrim_overflow(tcx: &ty::ctxt,
1070 repr_type: attr::IntType,
1071 prev_val: ty::Disr) {
1072 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1073 let computed_value = repr_type.disr_string(computed_value);
1074 let prev_val = repr_type.disr_string(prev_val);
1075 let repr_type = repr_type.to_ty(tcx);
1076 span_err!(tcx.sess, variant_span, E0370,
1077 "enum discriminant overflowed on value after {}: {}; \
1078 set explicitly via {} = {} if that is desired outcome",
1079 prev_val, repr_type, variant_name, computed_value);
1082 fn next_disr(tcx: &ty::ctxt,
1084 repr_type: attr::IntType,
1085 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1086 if let Some(prev_disr_val) = prev_disr_val {
1087 let result = repr_type.disr_incr(prev_disr_val);
1088 if let None = result {
1089 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1090 repr_type, prev_disr_val);
1094 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1097 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1100 -> ty::VariantDefData<'tcx, 'tcx>
1102 let did = tcx.map.local_def_id(v.node.data.id());
1103 let name = v.node.name;
1104 convert_struct_variant(tcx, did, name, disr, &v.node.data)
1106 let did = tcx.map.local_def_id(it.id);
1107 let repr_hints = tcx.lookup_repr_hints(did);
1108 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1109 let mut prev_disr = None;
1110 let variants = def.variants.iter().map(|v| {
1111 let disr = match v.node.disr_expr {
1112 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1113 None => next_disr(tcx, v, repr_type, prev_disr)
1114 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1116 let v = convert_enum_variant(tcx, v, disr);
1117 prev_disr = Some(disr);
1120 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1123 /// Ensures that the super-predicates of the trait with def-id
1124 /// trait_def_id are converted and stored. This does NOT ensure that
1125 /// the transitive super-predicates are converted; that is the job of
1126 /// the `ensure_super_predicates()` method in the `AstConv` impl
1127 /// above. Returns a list of trait def-ids that must be ensured as
1128 /// well to guarantee that the transitive superpredicates are
1130 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1131 trait_def_id: DefId)
1136 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1138 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1141 // If this trait comes from an external crate, then all of the
1142 // supertraits it may depend on also must come from external
1143 // crates, and hence all of them already have their
1144 // super-predicates "converted" (and available from crate
1145 // meta-data), so there is no need to transitively test them.
1149 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1150 let superpredicates = superpredicates.unwrap_or_else(|| {
1151 let item = match ccx.tcx.map.get(trait_node_id) {
1152 hir_map::NodeItem(item) => item,
1153 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1156 let (generics, bounds) = match item.node {
1157 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1158 _ => tcx.sess.span_bug(item.span,
1159 "ensure_super_predicates_step invoked on non-trait"),
1162 // In-scope when converting the superbounds for `Trait` are
1163 // that `Self:Trait` as well as any bounds that appear on the
1165 let trait_def = trait_def_of_item(ccx, item);
1166 let self_predicate = ty::GenericPredicates {
1167 predicates: VecPerParamSpace::new(vec![],
1168 vec![trait_def.trait_ref.to_predicate()],
1171 let scope = &(generics, &self_predicate);
1173 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1174 let self_param_ty = tcx.mk_self_type();
1175 let superbounds1 = compute_bounds(&ccx.icx(scope),
1181 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1183 // Convert any explicit superbounds in the where clause,
1184 // e.g. `trait Foo where Self : Bar`:
1185 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1187 // Combine the two lists to form the complete set of superbounds:
1188 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1189 let superpredicates = ty::GenericPredicates {
1190 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1192 debug!("superpredicates for trait {:?} = {:?}",
1193 tcx.map.local_def_id(item.id),
1196 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1201 let def_ids: Vec<_> = superpredicates.predicates
1203 .filter_map(|p| p.to_opt_poly_trait_ref())
1204 .map(|tr| tr.def_id())
1207 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1212 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1214 -> &'tcx ty::TraitDef<'tcx>
1216 let def_id = ccx.tcx.map.local_def_id(it.id);
1219 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1223 let (unsafety, generics, items) = match it.node {
1224 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1225 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1228 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1229 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1230 let mut err = ccx.tcx.sess.struct_span_err(
1232 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1233 which traits can use parenthetical notation");
1234 fileline_help!(&mut err, it.span,
1235 "add `#![feature(unboxed_closures)]` to \
1236 the crate attributes to use it");
1240 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1242 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1244 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1245 match trait_item.node {
1246 hir::TypeTraitItem(..) => Some(trait_item.name),
1251 let trait_ref = ty::TraitRef {
1256 let trait_def = ty::TraitDef::new(unsafety,
1260 associated_type_names);
1262 return tcx.intern_trait_def(trait_def);
1264 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1265 generics: &hir::Generics)
1270 // Creates a no-op substitution for the trait's type parameters.
1275 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1278 name: def.lifetime.name
1282 // Start with the generics in the type parameters...
1287 .map(|(i, def)| tcx.mk_param(TypeSpace,
1288 i as u32, def.name))
1291 // ...and also create the `Self` parameter.
1292 let self_ty = tcx.mk_self_type();
1294 Substs::new_trait(types, regions, self_ty)
1298 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1299 trait_node_id: ast::NodeId,
1300 assoc_name: ast::Name)
1303 let item = match ccx.tcx.map.get(trait_node_id) {
1304 hir_map::NodeItem(item) => item,
1305 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1308 let trait_items = match item.node {
1309 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1310 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1313 trait_items.iter().any(|trait_item| {
1314 match trait_item.node {
1315 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1321 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1323 let trait_def = trait_def_of_item(ccx, it);
1325 let def_id = ccx.tcx.map.local_def_id(it.id);
1327 let (generics, items) = match it.node {
1328 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1332 &format!("trait_def_of_item invoked on {:?}", s));
1336 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1338 // `ty_generic_predicates` below will consider the bounds on the type
1339 // parameters (including `Self`) and the explicit where-clauses,
1340 // but to get the full set of predicates on a trait we need to add
1341 // in the supertrait bounds and anything declared on the
1342 // associated types.
1343 let mut base_predicates = super_predicates;
1345 // Add in a predicate that `Self:Trait` (where `Trait` is the
1346 // current trait). This is needed for builtin bounds.
1347 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1348 base_predicates.predicates.push(SelfSpace, self_predicate);
1350 // add in the explicit where-clauses
1351 let mut trait_predicates =
1352 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1354 let assoc_predicates = predicates_for_associated_types(ccx,
1357 trait_def.trait_ref,
1359 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1361 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1362 assert!(prev_predicates.is_none());
1366 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1367 ast_generics: &hir::Generics,
1368 trait_predicates: &ty::GenericPredicates<'tcx>,
1369 self_trait_ref: ty::TraitRef<'tcx>,
1370 trait_items: &[hir::TraitItem])
1371 -> Vec<ty::Predicate<'tcx>>
1373 trait_items.iter().flat_map(|trait_item| {
1374 let bounds = match trait_item.node {
1375 hir::TypeTraitItem(ref bounds, _) => bounds,
1377 return vec!().into_iter();
1381 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1384 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1387 SizedByDefault::Yes,
1390 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1395 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1397 -> ty::TypeScheme<'tcx>
1399 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1400 match ccx.tcx.map.find(node_id) {
1401 Some(hir_map::NodeItem(item)) => {
1402 type_scheme_of_item(ccx, &item)
1404 Some(hir_map::NodeForeignItem(foreign_item)) => {
1405 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1406 type_scheme_of_foreign_item(ccx, &foreign_item, abi)
1409 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1410 in get_item_type_scheme(): {:?}",
1415 ccx.tcx.lookup_item_type(def_id)
1419 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1421 -> ty::TypeScheme<'tcx>
1423 let item_def_id = ccx.tcx.map.local_def_id(item.id);
1424 ccx.tcx.tcache.memoize(item_def_id, || {
1425 // NB. Since the `memoized` function enters a new task, and we
1426 // are giving this task access to the item `item`, we must
1428 ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
1429 compute_type_scheme_of_item(ccx, item)
1433 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1435 -> ty::TypeScheme<'tcx>
1439 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1440 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &t);
1441 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1443 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1444 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1445 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl);
1446 let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1447 ty::TypeScheme { ty: ty, generics: ty_generics }
1449 hir::ItemTy(ref t, ref generics) => {
1450 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1451 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &t);
1452 ty::TypeScheme { ty: ty, generics: ty_generics }
1454 hir::ItemEnum(ref ei, ref generics) => {
1455 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1456 let substs = mk_item_substs(ccx, &ty_generics);
1457 let def = convert_enum_def(tcx, it, ei);
1458 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1459 ty::TypeScheme { ty: t, generics: ty_generics }
1461 hir::ItemStruct(ref si, ref generics) => {
1462 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1463 let substs = mk_item_substs(ccx, &ty_generics);
1464 let def = convert_struct_def(tcx, it, si);
1465 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1466 ty::TypeScheme { ty: t, generics: ty_generics }
1468 hir::ItemDefaultImpl(..) |
1469 hir::ItemTrait(..) |
1472 hir::ItemForeignMod(..) |
1473 hir::ItemExternCrate(..) |
1474 hir::ItemUse(..) => {
1477 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1483 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1485 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1489 let tag = type_scheme_of_item(ccx, it);
1490 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1491 let predicates = match it.node {
1492 hir::ItemStatic(..) | hir::ItemConst(..) => {
1493 ty::GenericPredicates::empty()
1495 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1496 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1498 hir::ItemTy(_, ref generics) => {
1499 ty_generic_predicates_for_type_or_impl(ccx, generics)
1501 hir::ItemEnum(_, ref generics) => {
1502 ty_generic_predicates_for_type_or_impl(ccx, generics)
1504 hir::ItemStruct(_, ref generics) => {
1505 ty_generic_predicates_for_type_or_impl(ccx, generics)
1507 hir::ItemDefaultImpl(..) |
1508 hir::ItemTrait(..) |
1509 hir::ItemExternCrate(..) |
1513 hir::ItemForeignMod(..) => {
1516 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1521 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1522 predicates.clone());
1523 assert!(prev_predicates.is_none());
1526 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1527 let object_lifetime_default_reprs: String =
1528 scheme.generics.types.iter()
1529 .map(|t| match t.object_lifetime_default {
1530 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1531 d => format!("{:?}", d),
1533 .collect::<Vec<String>>()
1536 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1539 return (scheme, predicates);
1542 fn type_scheme_of_foreign_item<'a, 'tcx>(
1543 ccx: &CrateCtxt<'a, 'tcx>,
1544 item: &hir::ForeignItem,
1546 -> ty::TypeScheme<'tcx>
1548 let item_def_id = ccx.tcx.map.local_def_id(item.id);
1549 ccx.tcx.tcache.memoize(item_def_id, || {
1550 // NB. Since the `memoized` function enters a new task, and we
1551 // are giving this task access to the item `item`, we must
1553 ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
1554 compute_type_scheme_of_foreign_item(ccx, item, abi)
1558 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1559 ccx: &CrateCtxt<'a, 'tcx>,
1560 it: &hir::ForeignItem,
1562 -> ty::TypeScheme<'tcx>
1565 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1566 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1568 hir::ForeignItemStatic(ref t, _) => {
1570 generics: ty::Generics::empty(),
1571 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1577 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1578 it: &hir::ForeignItem)
1580 // For reasons I cannot fully articulate, I do so hate the AST
1581 // map, and I regard each time that I use it as a personal and
1582 // moral failing, but at the moment it seems like the only
1583 // convenient way to extract the ABI. - ndm
1585 let abi = tcx.map.get_foreign_abi(it.id);
1587 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1588 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1590 let predicates = match it.node {
1591 hir::ForeignItemFn(_, ref generics) => {
1592 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1594 hir::ForeignItemStatic(..) => {
1595 ty::GenericPredicates::empty()
1599 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1601 assert!(prev_predicates.is_none());
1604 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1605 generics: &hir::Generics)
1606 -> ty::Generics<'tcx> {
1607 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1610 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1611 generics: &hir::Generics)
1612 -> ty::GenericPredicates<'tcx>
1614 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1617 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1618 trait_id: ast::NodeId,
1619 substs: &'tcx Substs<'tcx>,
1620 ast_generics: &hir::Generics)
1621 -> ty::Generics<'tcx>
1623 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1624 ccx.tcx.map.local_def_id(trait_id), substs);
1626 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1628 // Add in the self type parameter.
1630 // Something of a hack: use the node id for the trait, also as
1631 // the node id for the Self type parameter.
1632 let param_id = trait_id;
1634 let parent = ccx.tcx.map.get_parent(param_id);
1636 let def = ty::TypeParameterDef {
1639 name: special_idents::type_self.name,
1640 def_id: ccx.tcx.map.local_def_id(param_id),
1641 default_def_id: ccx.tcx.map.local_def_id(parent),
1643 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1646 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1648 generics.types.push(SelfSpace, def);
1653 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1654 generics: &hir::Generics,
1655 base_generics: &ty::Generics<'tcx>)
1656 -> ty::Generics<'tcx>
1658 ty_generics(ccx, FnSpace, generics, base_generics)
1661 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1662 generics: &hir::Generics,
1663 base_predicates: &ty::GenericPredicates<'tcx>)
1664 -> ty::GenericPredicates<'tcx>
1666 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1669 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1670 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1671 bounds: &mut ty::BuiltinBounds,
1672 ast_bounds: &[hir::TyParamBound],
1675 let tcx = astconv.tcx();
1677 // Try to find an unbound in bounds.
1678 let mut unbound = None;
1679 for ab in ast_bounds {
1680 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1681 if unbound.is_none() {
1682 assert!(ptr.bound_lifetimes.is_empty());
1683 unbound = Some(ptr.trait_ref.clone());
1685 span_err!(tcx.sess, span, E0203,
1686 "type parameter has more than one relaxed default \
1687 bound, only one is supported");
1692 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1695 // FIXME(#8559) currently requires the unbound to be built-in.
1696 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1698 Ok(kind_id) if trait_def_id != kind_id => {
1699 tcx.sess.span_warn(span,
1700 "default bound relaxed for a type parameter, but \
1701 this does nothing because the given bound is not \
1702 a default. Only `?Sized` is supported");
1703 tcx.try_add_builtin_trait(kind_id, bounds);
1708 _ if kind_id.is_ok() => {
1709 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1711 // No lang item for Sized, so we can't add it as a bound.
1716 /// Returns the early-bound lifetimes declared in this generics
1717 /// listing. For anything other than fns/methods, this is just all
1718 /// the lifetimes that are declared. For fns or methods, we have to
1719 /// screen out those that do not appear in any where-clauses etc using
1720 /// `resolve_lifetime::early_bound_lifetimes`.
1721 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1722 ast_generics: &hir::Generics)
1723 -> Vec<hir::LifetimeDef>
1726 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1727 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1731 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1733 ast_generics: &hir::Generics,
1734 base_predicates: &ty::GenericPredicates<'tcx>)
1735 -> ty::GenericPredicates<'tcx>
1738 let mut result = base_predicates.clone();
1740 // Collect the predicates that were written inline by the user on each
1741 // type parameter (e.g., `<T:Foo>`).
1742 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1743 let index = index as u32;
1744 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1745 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1748 SizedByDefault::Yes,
1750 let predicates = bounds.predicates(ccx.tcx, param_ty);
1751 result.predicates.extend(space, predicates.into_iter());
1754 // Collect the region predicates that were declared inline as
1755 // well. In the case of parameters declared on a fn or method, we
1756 // have to be careful to only iterate over early-bound regions.
1757 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1758 for (index, param) in early_lifetimes.iter().enumerate() {
1759 let index = index as u32;
1761 ty::ReEarlyBound(ty::EarlyBoundRegion {
1764 name: param.lifetime.name
1766 for bound in ¶m.bounds {
1767 let bound_region = ast_region_to_region(ccx.tcx, bound);
1768 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1769 result.predicates.push(space, outlives.to_predicate());
1773 // Add in the bounds that appear in the where-clause
1774 let where_clause = &ast_generics.where_clause;
1775 for predicate in &where_clause.predicates {
1777 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1778 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1780 &bound_pred.bounded_ty);
1782 for bound in bound_pred.bounds.iter() {
1784 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1785 let mut projections = Vec::new();
1788 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1793 result.predicates.push(space, trait_ref.to_predicate());
1795 for projection in &projections {
1796 result.predicates.push(space, projection.to_predicate());
1800 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1801 let region = ast_region_to_region(tcx, lifetime);
1802 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1803 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1809 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1810 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1811 for bound in ®ion_pred.bounds {
1812 let r2 = ast_region_to_region(tcx, bound);
1813 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1814 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1818 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1820 tcx.sess.span_bug(eq_pred.span,
1821 "Equality constraints are not yet \
1822 implemented (#20041)")
1830 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1832 ast_generics: &hir::Generics,
1833 base_generics: &ty::Generics<'tcx>)
1834 -> ty::Generics<'tcx>
1837 let mut result = base_generics.clone();
1839 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1840 for (i, l) in early_lifetimes.iter().enumerate() {
1841 let bounds = l.bounds.iter()
1842 .map(|l| ast_region_to_region(tcx, l))
1844 let def = ty::RegionParameterDef { name: l.lifetime.name,
1847 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1849 result.regions.push(space, def);
1852 assert!(result.types.is_empty_in(space));
1854 // Now create the real type parameters.
1855 for i in 0..ast_generics.ty_params.len() {
1856 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1857 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1858 result.types.push(space, def);
1864 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1870 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1872 for leaf_ty in ty.walk() {
1873 if let ty::TyParam(p) = leaf_ty.sty {
1874 if p.space == space && p.idx >= index {
1875 span_err!(ccx.tcx.sess, path.span, E0128,
1876 "type parameters with a default cannot use \
1877 forward declared identifiers");
1879 return ccx.tcx.types.err
1887 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1888 ast_generics: &hir::Generics,
1891 -> ty::TypeParameterDef<'tcx>
1893 let param = &ast_generics.ty_params[index as usize];
1896 match tcx.ty_param_defs.borrow().get(¶m.id) {
1897 Some(d) => { return d.clone(); }
1901 let default = param.default.as_ref().map(
1902 |def| convert_default_type_parameter(ccx, def, space, index)
1905 let object_lifetime_default =
1906 compute_object_lifetime_default(ccx, param.id,
1907 ¶m.bounds, &ast_generics.where_clause);
1909 let parent = tcx.map.get_parent(param.id);
1911 if space != TypeSpace && default.is_some() {
1912 if !tcx.sess.features.borrow().default_type_parameter_fallback {
1914 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1917 format!("defaults for type parameters are only allowed in `struct`, \
1918 `enum`, `type`, or `trait` definitions."));
1922 let def = ty::TypeParameterDef {
1926 def_id: ccx.tcx.map.local_def_id(param.id),
1927 default_def_id: ccx.tcx.map.local_def_id(parent),
1929 object_lifetime_default: object_lifetime_default,
1932 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
1937 /// Scan the bounds and where-clauses on a parameter to extract bounds
1938 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
1939 /// This runs as part of computing the minimal type scheme, so we
1940 /// intentionally avoid just asking astconv to convert all the where
1941 /// clauses into a `ty::Predicate`. This is because that could induce
1942 /// artificial cycles.
1943 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1944 param_id: ast::NodeId,
1945 param_bounds: &[hir::TyParamBound],
1946 where_clause: &hir::WhereClause)
1947 -> ty::ObjectLifetimeDefault
1949 let inline_bounds = from_bounds(ccx, param_bounds);
1950 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
1951 let all_bounds: HashSet<_> = inline_bounds.into_iter()
1952 .chain(where_bounds)
1954 return if all_bounds.len() > 1 {
1955 ty::ObjectLifetimeDefault::Ambiguous
1956 } else if all_bounds.len() == 0 {
1957 ty::ObjectLifetimeDefault::BaseDefault
1959 ty::ObjectLifetimeDefault::Specific(
1960 all_bounds.into_iter().next().unwrap())
1963 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1964 bounds: &[hir::TyParamBound])
1968 .filter_map(|bound| {
1970 hir::TraitTyParamBound(..) =>
1972 hir::RegionTyParamBound(ref lifetime) =>
1973 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
1979 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1980 param_id: ast::NodeId,
1981 predicates: &[hir::WherePredicate])
1985 .flat_map(|predicate| {
1987 hir::WherePredicate::BoundPredicate(ref data) => {
1988 if data.bound_lifetimes.is_empty() &&
1989 is_param(ccx.tcx, &data.bounded_ty, param_id)
1991 from_bounds(ccx, &data.bounds).into_iter()
1993 Vec::new().into_iter()
1996 hir::WherePredicate::RegionPredicate(..) |
1997 hir::WherePredicate::EqPredicate(..) => {
1998 Vec::new().into_iter()
2006 enum SizedByDefault { Yes, No, }
2008 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2009 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2010 /// built-in trait (formerly known as kind): Send.
2011 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2012 param_ty: ty::Ty<'tcx>,
2013 ast_bounds: &[hir::TyParamBound],
2014 sized_by_default: SizedByDefault,
2016 -> astconv::Bounds<'tcx>
2019 conv_param_bounds(astconv,
2024 if let SizedByDefault::Yes = sized_by_default {
2025 add_unsized_bound(astconv,
2026 &mut bounds.builtin_bounds,
2031 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2036 /// Converts a specific TyParamBound from the AST into a set of
2037 /// predicates that apply to the self-type. A vector is returned
2038 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2039 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2040 /// and `<T as Bar>::X == i32`).
2041 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2043 bound: &hir::TyParamBound)
2044 -> Vec<ty::Predicate<'tcx>>
2047 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2048 let mut projections = Vec::new();
2049 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2050 projections.into_iter()
2051 .map(|p| p.to_predicate())
2052 .chain(Some(pred.to_predicate()))
2055 hir::RegionTyParamBound(ref lifetime) => {
2056 let region = ast_region_to_region(astconv.tcx(), lifetime);
2057 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2058 vec![ty::Predicate::TypeOutlives(pred)]
2060 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2066 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2068 trait_ref: &hir::PolyTraitRef,
2069 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2070 -> ty::PolyTraitRef<'tcx>
2072 astconv::instantiate_poly_trait_ref(astconv,
2079 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2081 param_ty: ty::Ty<'tcx>,
2082 ast_bounds: &[hir::TyParamBound])
2083 -> astconv::Bounds<'tcx>
2085 let tcx = astconv.tcx();
2086 let astconv::PartitionedBounds {
2090 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2092 let mut projection_bounds = Vec::new();
2094 let trait_bounds: Vec<ty::PolyTraitRef> =
2096 .map(|bound| conv_poly_trait_ref(astconv,
2099 &mut projection_bounds))
2102 let region_bounds: Vec<ty::Region> =
2103 region_bounds.into_iter()
2104 .map(|r| ast_region_to_region(tcx, r))
2108 region_bounds: region_bounds,
2109 builtin_bounds: builtin_bounds,
2110 trait_bounds: trait_bounds,
2111 projection_bounds: projection_bounds,
2115 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2116 ccx: &CrateCtxt<'a, 'tcx>,
2118 ast_generics: &hir::Generics,
2120 -> ty::TypeScheme<'tcx>
2122 for i in &decl.inputs {
2124 PatKind::Ident(_, _, _) => (),
2125 PatKind::Wild => (),
2127 span_err!(ccx.tcx.sess, i.pat.span, E0130,
2128 "patterns aren't allowed in foreign function declarations");
2133 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2135 let rb = BindingRscope::new();
2136 let input_tys = decl.inputs
2138 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2141 let output = match decl.output {
2142 hir::Return(ref ty) =>
2143 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &ty)),
2144 hir::DefaultReturn(..) =>
2145 ty::FnConverging(ccx.tcx.mk_nil()),
2146 hir::NoReturn(..) =>
2150 let t_fn = ccx.tcx.mk_fn(None,
2151 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2153 unsafety: hir::Unsafety::Unsafe,
2154 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2156 variadic: decl.variadic}),
2160 generics: ty_generics,
2165 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2166 ty_generics: &ty::Generics<'tcx>)
2170 ty_generics.types.map(
2171 |def| ccx.tcx.mk_param_from_def(def));
2174 ty_generics.regions.map(
2175 |def| def.to_early_bound_region());
2177 Substs::new(types, regions)
2180 /// Checks that all the type parameters on an impl
2181 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2182 ast_generics: &hir::Generics,
2183 impl_predicates: &mut ty::GenericPredicates<'tcx>,
2186 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2187 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2189 assert!(impl_predicates.predicates.is_empty_in(FnSpace));
2190 assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
2192 // The trait reference is an input, so find all type parameters
2193 // reachable from there, to start (if this is an inherent impl,
2194 // then just examine the self type).
2195 let mut input_parameters: HashSet<_> =
2196 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2197 if let Some(ref trait_ref) = impl_trait_ref {
2198 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2201 ctp::setup_constraining_predicates(tcx,
2202 impl_predicates.predicates.get_mut_slice(TypeSpace),
2204 &mut input_parameters);
2206 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2207 let param_ty = ty::ParamTy { space: TypeSpace,
2209 name: ty_param.name };
2210 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2211 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2216 fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2217 ast_generics: &hir::Generics,
2219 impl_items: &[hir::ImplItem])
2221 // Every lifetime used in an associated type must be constrained.
2222 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2223 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2224 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2226 let mut input_parameters: HashSet<_> =
2227 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2228 if let Some(ref trait_ref) = impl_trait_ref {
2229 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2231 ctp::identify_constrained_type_params(tcx,
2232 &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
2234 let lifetimes_in_associated_types: HashSet<_> =
2236 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2237 .filter_map(|item| match item {
2238 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2239 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2241 .flat_map(|ty| ctp::parameters_for_type(ty, true))
2242 .filter_map(|p| match p {
2243 ctp::Parameter::Type(_) => None,
2244 ctp::Parameter::Region(r) => Some(r),
2248 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2249 let region = ty::EarlyBoundRegion { space: TypeSpace,
2250 index: index as u32,
2251 name: lifetime_def.lifetime.name };
2253 lifetimes_in_associated_types.contains(®ion) && // (*)
2254 !input_parameters.contains(&ctp::Parameter::Region(region))
2256 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2257 "lifetime", ®ion.name.to_string());
2261 // (*) This is a horrible concession to reality. I think it'd be
2262 // better to just ban unconstrianed lifetimes outright, but in
2263 // practice people do non-hygenic macros like:
2266 // macro_rules! __impl_slice_eq1 {
2267 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2268 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2275 // In a concession to backwards compatbility, we continue to
2276 // permit those, so long as the lifetimes aren't used in
2277 // associated types. I believe this is sound, because lifetimes
2278 // used elsewhere are not projected back out.
2281 fn report_unused_parameter(tcx: &ty::ctxt,
2286 span_err!(tcx.sess, span, E0207,
2287 "the {} parameter `{}` is not constrained by the \
2288 impl trait, self type, or predicates",