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;
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()) };
103 let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
104 ccx.tcx.map.krate().visit_all_items(&mut visitor);
107 ///////////////////////////////////////////////////////////////////////////
109 struct CrateCtxt<'a,'tcx:'a> {
110 tcx: &'a ty::ctxt<'tcx>,
112 // This stack is used to identify cycles in the user's source.
113 // Note that these cycles can cross multiple items.
114 stack: RefCell<Vec<AstConvRequest>>,
117 /// Context specific to some particular item. This is what implements
118 /// AstConv. It has information about the predicates that are defined
119 /// on the trait. Unfortunately, this predicate information is
120 /// available in various different forms at various points in the
121 /// process. So we can't just store a pointer to e.g. the AST or the
122 /// parsed ty form, we have to be more flexible. To this end, the
123 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
124 /// that it uses to satisfy `get_type_parameter_bounds` requests.
125 /// This object might draw the information from the AST
126 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
127 /// or both (a tuple).
128 struct ItemCtxt<'a,'tcx:'a> {
129 ccx: &'a CrateCtxt<'a,'tcx>,
130 param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
133 #[derive(Copy, Clone, PartialEq, Eq)]
134 enum AstConvRequest {
135 GetItemTypeScheme(DefId),
137 EnsureSuperPredicates(DefId),
138 GetTypeParameterBounds(ast::NodeId),
141 ///////////////////////////////////////////////////////////////////////////
143 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
144 ccx: &'a CrateCtxt<'a, 'tcx>
147 impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
148 fn visit_item(&mut self, item: &hir::Item) {
149 let tcx = self.ccx.tcx;
150 let item_def_id = tcx.map.local_def_id(item.id);
151 let _task = tcx.dep_graph.in_task(DepNode::CollectItem(item_def_id));
152 convert_item(self.ccx, item);
156 ///////////////////////////////////////////////////////////////////////////
157 // Utility types and common code for the above passes.
159 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
160 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
161 ItemCtxt { ccx: self, param_bounds: param_bounds }
164 fn cycle_check<F,R>(&self,
166 request: AstConvRequest,
168 -> Result<R,ErrorReported>
169 where F: FnOnce() -> Result<R,ErrorReported>
172 let mut stack = self.stack.borrow_mut();
173 match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
176 let cycle = &stack[i..];
177 self.report_cycle(span, cycle);
178 return Err(ErrorReported);
186 self.stack.borrow_mut().pop();
190 fn report_cycle(&self,
192 cycle: &[AstConvRequest])
194 assert!(!cycle.is_empty());
197 let mut err = struct_span_err!(tcx.sess, span, E0391,
198 "unsupported cyclic reference between types/traits detected");
201 AstConvRequest::GetItemTypeScheme(def_id) |
202 AstConvRequest::GetTraitDef(def_id) => {
204 &format!("the cycle begins when processing `{}`...",
205 tcx.item_path_str(def_id)));
207 AstConvRequest::EnsureSuperPredicates(def_id) => {
209 &format!("the cycle begins when computing the supertraits of `{}`...",
210 tcx.item_path_str(def_id)));
212 AstConvRequest::GetTypeParameterBounds(id) => {
213 let def = tcx.type_parameter_def(id);
215 &format!("the cycle begins when computing the bounds \
216 for type parameter `{}`...",
221 for request in &cycle[1..] {
223 AstConvRequest::GetItemTypeScheme(def_id) |
224 AstConvRequest::GetTraitDef(def_id) => {
226 &format!("...which then requires processing `{}`...",
227 tcx.item_path_str(def_id)));
229 AstConvRequest::EnsureSuperPredicates(def_id) => {
231 &format!("...which then requires computing the supertraits of `{}`...",
232 tcx.item_path_str(def_id)));
234 AstConvRequest::GetTypeParameterBounds(id) => {
235 let def = tcx.type_parameter_def(id);
237 &format!("...which then requires computing the bounds \
238 for type parameter `{}`...",
245 AstConvRequest::GetItemTypeScheme(def_id) |
246 AstConvRequest::GetTraitDef(def_id) => {
248 &format!("...which then again requires processing `{}`, completing the cycle.",
249 tcx.item_path_str(def_id)));
251 AstConvRequest::EnsureSuperPredicates(def_id) => {
253 &format!("...which then again requires computing the supertraits of `{}`, \
254 completing the cycle.",
255 tcx.item_path_str(def_id)));
257 AstConvRequest::GetTypeParameterBounds(id) => {
258 let def = tcx.type_parameter_def(id);
260 &format!("...which then again requires computing the bounds \
261 for type parameter `{}`, completing the cycle.",
268 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
269 fn get_trait_def(&self, trait_id: DefId)
270 -> &'tcx ty::TraitDef<'tcx>
274 if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
275 let item = match tcx.map.get(trait_id) {
276 hir_map::NodeItem(item) => item,
277 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
280 trait_def_of_item(self, &*item)
282 tcx.lookup_trait_def(trait_id)
286 /// Ensure that the (transitive) super predicates for
287 /// `trait_def_id` are available. This will report a cycle error
288 /// if a trait `X` (transitively) extends itself in some form.
289 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
290 -> Result<(), ErrorReported>
292 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
293 let def_ids = ensure_super_predicates_step(self, trait_def_id);
295 for def_id in def_ids {
296 try!(self.ensure_super_predicates(span, def_id));
304 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
305 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
306 ast_ty_to_ty(self, rs, ast_ty)
310 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
311 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
313 fn get_item_type_scheme(&self, span: Span, id: DefId)
314 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
316 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
317 Ok(type_scheme_of_def_id(self.ccx, id))
321 fn get_trait_def(&self, span: Span, id: DefId)
322 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
324 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
325 Ok(self.ccx.get_trait_def(id))
329 fn ensure_super_predicates(&self,
332 -> Result<(), ErrorReported>
334 debug!("ensure_super_predicates(trait_def_id={:?})",
337 self.ccx.ensure_super_predicates(span, trait_def_id)
341 fn get_type_parameter_bounds(&self,
343 node_id: ast::NodeId)
344 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
346 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
347 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
349 .filter_map(|p| p.to_opt_poly_trait_ref())
355 fn trait_defines_associated_type_named(&self,
357 assoc_name: ast::Name)
360 if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
361 trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
363 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
364 trait_def.associated_type_names.contains(&assoc_name)
369 _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
370 _substs: Option<&mut Substs<'tcx>>,
371 _space: Option<ParamSpace>,
372 span: Span) -> Ty<'tcx> {
373 span_err!(self.tcx().sess, span, E0121,
374 "the type placeholder `_` is not allowed within types on item signatures");
378 fn projected_ty(&self,
380 trait_ref: ty::TraitRef<'tcx>,
381 item_name: ast::Name)
384 self.tcx().mk_projection(trait_ref, item_name)
388 /// Interface used to find the bounds on a type parameter from within
389 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
390 trait GetTypeParameterBounds<'tcx> {
391 fn get_type_parameter_bounds(&self,
392 astconv: &AstConv<'tcx>,
394 node_id: ast::NodeId)
395 -> Vec<ty::Predicate<'tcx>>;
398 /// Find bounds from both elements of the tuple.
399 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
400 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
402 fn get_type_parameter_bounds(&self,
403 astconv: &AstConv<'tcx>,
405 node_id: ast::NodeId)
406 -> Vec<ty::Predicate<'tcx>>
408 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
409 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
414 /// Empty set of bounds.
415 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
416 fn get_type_parameter_bounds(&self,
417 _astconv: &AstConv<'tcx>,
419 _node_id: ast::NodeId)
420 -> Vec<ty::Predicate<'tcx>>
426 /// Find bounds from the parsed and converted predicates. This is
427 /// used when converting methods, because by that time the predicates
428 /// from the trait/impl have been fully converted.
429 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
430 fn get_type_parameter_bounds(&self,
431 astconv: &AstConv<'tcx>,
433 node_id: ast::NodeId)
434 -> Vec<ty::Predicate<'tcx>>
436 let def = astconv.tcx().type_parameter_def(node_id);
440 .filter(|predicate| {
442 ty::Predicate::Trait(ref data) => {
443 data.skip_binder().self_ty().is_param(def.space, def.index)
445 ty::Predicate::TypeOutlives(ref data) => {
446 data.skip_binder().0.is_param(def.space, def.index)
448 ty::Predicate::Equate(..) |
449 ty::Predicate::RegionOutlives(..) |
450 ty::Predicate::WellFormed(..) |
451 ty::Predicate::ObjectSafe(..) |
452 ty::Predicate::Projection(..) => {
462 /// Find bounds from hir::Generics. This requires scanning through the
463 /// AST. We do this to avoid having to convert *all* the bounds, which
464 /// would create artificial cycles. Instead we can only convert the
465 /// bounds for a type parameter `X` if `X::Foo` is used.
466 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
467 fn get_type_parameter_bounds(&self,
468 astconv: &AstConv<'tcx>,
470 node_id: ast::NodeId)
471 -> Vec<ty::Predicate<'tcx>>
473 // In the AST, bounds can derive from two places. Either
474 // written inline like `<T:Foo>` or in a where clause like
477 let def = astconv.tcx().type_parameter_def(node_id);
478 let ty = astconv.tcx().mk_param_from_def(&def);
483 .filter(|p| p.id == node_id)
484 .flat_map(|p| p.bounds.iter())
485 .flat_map(|b| predicates_from_bound(astconv, ty, b));
487 let from_where_clauses =
491 .filter_map(|wp| match *wp {
492 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
495 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
496 .flat_map(|bp| bp.bounds.iter())
497 .flat_map(|b| predicates_from_bound(astconv, ty, b));
499 from_ty_params.chain(from_where_clauses).collect()
503 /// Tests whether this is the AST for a reference to the type
504 /// parameter with id `param_id`. We use this so as to avoid running
505 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
506 /// conversion of the type to avoid inducing unnecessary cycles.
507 fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
509 param_id: ast::NodeId)
512 if let hir::TyPath(None, _) = ast_ty.node {
513 let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
514 match path_res.base_def {
515 def::DefSelfTy(Some(def_id), None) => {
516 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
518 def::DefTyParam(_, _, def_id, _) => {
519 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
531 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
532 container: ImplOrTraitItemContainer,
535 vis: hir::Visibility,
536 sig: &hir::MethodSig,
537 untransformed_rcvr_ty: Ty<'tcx>,
538 rcvr_ty_generics: &ty::Generics<'tcx>,
539 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
540 let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
542 let ty_generic_predicates =
543 ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
545 let (fty, explicit_self_category) =
546 astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
547 sig, untransformed_rcvr_ty);
549 let def_id = ccx.tcx.map.local_def_id(id);
550 let ty_method = ty::Method::new(name,
552 ty_generic_predicates,
554 explicit_self_category,
559 let fty = ccx.tcx.mk_fn(Some(def_id),
560 ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
561 debug!("method {} (id {}) has type {:?}",
563 ccx.tcx.register_item_type(def_id, TypeScheme {
564 generics: ty_method.generics.clone(),
567 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
569 write_ty_to_tcx(ccx.tcx, id, fty);
571 debug!("writing method type: def_id={:?} mty={:?}",
574 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
575 ty::MethodTraitItem(Rc::new(ty_method)));
578 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
579 struct_generics: &ty::Generics<'tcx>,
580 struct_predicates: &ty::GenericPredicates<'tcx>,
581 v: &hir::StructField,
582 ty_f: ty::FieldDefMaster<'tcx>)
584 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
586 write_ty_to_tcx(ccx.tcx, v.node.id, tt);
588 /* add the field to the tcache */
589 ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(v.node.id),
591 generics: struct_generics.clone(),
594 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(v.node.id),
595 struct_predicates.clone());
598 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
599 container: ImplOrTraitItemContainer,
602 vis: hir::Visibility,
606 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
607 ty::GenericPredicates::empty());
609 write_ty_to_tcx(ccx.tcx, id, ty);
611 let associated_const = Rc::new(ty::AssociatedConst {
614 def_id: ccx.tcx.map.local_def_id(id),
615 container: container,
619 ccx.tcx.impl_or_trait_items.borrow_mut()
620 .insert(ccx.tcx.map.local_def_id(id), ty::ConstTraitItem(associated_const));
623 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
624 container: ImplOrTraitItemContainer,
627 vis: hir::Visibility,
628 ty: Option<Ty<'tcx>>)
630 let associated_type = Rc::new(ty::AssociatedType {
634 def_id: ccx.tcx.map.local_def_id(id),
637 ccx.tcx.impl_or_trait_items.borrow_mut()
638 .insert(ccx.tcx.map.local_def_id(id), ty::TypeTraitItem(associated_type));
641 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
643 generics: &hir::Generics,
644 thing: &'static str) {
645 let mut warn = false;
647 for ty_param in generics.ty_params.iter() {
648 for bound in ty_param.bounds.iter() {
650 hir::TraitTyParamBound(..) => {
653 hir::RegionTyParamBound(..) => { }
659 // According to accepted RFC #XXX, we should
660 // eventually accept these, but it will not be
661 // part of this PR. Still, convert to warning to
662 // make bootstrapping easier.
663 span_warn!(ccx.tcx.sess, span, E0122,
664 "trait bounds are not (yet) enforced \
670 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
672 debug!("convert: item {} with id {}", it.name, it.id);
674 // These don't define types.
675 hir::ItemExternCrate(_) | hir::ItemUse(_) | hir::ItemMod(_) => {
677 hir::ItemForeignMod(ref foreign_mod) => {
678 for item in &foreign_mod.items {
679 convert_foreign_item(ccx, item);
682 hir::ItemEnum(ref enum_definition, _) => {
683 let (scheme, predicates) = convert_typed_item(ccx, it);
684 write_ty_to_tcx(tcx, it.id, scheme.ty);
685 convert_enum_variant_types(ccx,
686 tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
689 &enum_definition.variants);
691 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
693 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
698 tcx.record_trait_has_default_impl(trait_ref.def_id);
700 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
708 // Create generics from the generics specified in the impl head.
709 debug!("convert: ast_generics={:?}", generics);
710 let def_id = ccx.tcx.map.local_def_id(it.id);
711 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
712 let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
714 debug!("convert: impl_bounds={:?}", ty_predicates);
716 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
717 write_ty_to_tcx(tcx, it.id, selfty);
719 tcx.register_item_type(def_id,
720 TypeScheme { generics: ty_generics.clone(),
722 if let &Some(ref ast_trait_ref) = opt_trait_ref {
723 tcx.impl_trait_refs.borrow_mut().insert(
725 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
731 tcx.impl_trait_refs.borrow_mut().insert(def_id, None);
734 enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id);
735 tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
738 // If there is a trait reference, treat the methods as always public.
739 // This is to work around some incorrect behavior in privacy checking:
740 // when the method belongs to a trait, it should acquire the privacy
741 // from the trait, not the impl. Forcing the visibility to be public
742 // makes things sorta work.
743 let parent_visibility = if opt_trait_ref.is_some() {
749 // Convert all the associated consts.
750 // Also, check if there are any duplicate associated items
751 let mut seen_type_items = FnvHashSet();
752 let mut seen_value_items = FnvHashSet();
754 for impl_item in impl_items {
755 let seen_items = match impl_item.node {
756 hir::ImplItemKind::Type(_) => &mut seen_type_items,
757 _ => &mut seen_value_items,
759 if !seen_items.insert(impl_item.name) {
760 let desc = match impl_item.node {
761 hir::ImplItemKind::Const(_, _) => "associated constant",
762 hir::ImplItemKind::Type(_) => "associated type",
763 hir::ImplItemKind::Method(ref sig, _) =>
764 match sig.explicit_self.node {
765 hir::SelfStatic => "associated function",
770 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
773 if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
774 let ty = ccx.icx(&ty_predicates)
775 .to_ty(&ExplicitRscope, &*ty);
776 tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
778 generics: ty_generics.clone(),
781 convert_associated_const(ccx, ImplContainer(def_id),
782 impl_item.name, impl_item.id,
783 impl_item.vis.inherit_from(parent_visibility),
784 ty, true /* has_value */);
788 // Convert all the associated types.
789 for impl_item in impl_items {
790 if let hir::ImplItemKind::Type(ref ty) = impl_item.node {
791 if opt_trait_ref.is_none() {
792 span_err!(tcx.sess, impl_item.span, E0202,
793 "associated types are not allowed in inherent impls");
796 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
798 convert_associated_type(ccx, ImplContainer(def_id),
799 impl_item.name, impl_item.id, impl_item.vis,
804 for impl_item in impl_items {
805 if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
806 // if the method specifies a visibility, use that, otherwise
807 // inherit the visibility from the impl (so `foo` in `pub impl
808 // { fn foo(); }` is public, but private in `impl { fn
810 let method_vis = impl_item.vis.inherit_from(parent_visibility);
812 convert_method(ccx, ImplContainer(def_id),
813 impl_item.name, impl_item.id, method_vis,
814 sig, selfty, &ty_generics, &ty_predicates);
818 enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
820 hir::ItemTrait(_, _, _, ref trait_items) => {
821 let trait_def = trait_def_of_item(ccx, it);
822 let def_id = trait_def.trait_ref.def_id;
823 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
824 ccx.ensure_super_predicates(it.span, def_id);
825 convert_trait_predicates(ccx, it);
826 let trait_predicates = tcx.lookup_predicates(def_id);
828 debug!("convert: trait_bounds={:?}", trait_predicates);
830 // FIXME: is the ordering here important? I think it is.
831 let container = TraitContainer(def_id);
833 // Convert all the associated constants.
834 for trait_item in trait_items {
835 if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node {
836 let ty = ccx.icx(&trait_predicates)
837 .to_ty(&ExplicitRscope, ty);
838 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
840 generics: trait_def.generics.clone(),
843 convert_associated_const(ccx,
853 // Convert all the associated types.
854 for trait_item in trait_items {
855 if let hir::TypeTraitItem(_, ref opt_ty) = trait_item.node {
856 let typ = opt_ty.as_ref().map({
857 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
860 convert_associated_type(ccx,
869 // Convert all the methods
870 for trait_item in trait_items {
871 if let hir::MethodTraitItem(ref sig, _) = trait_item.node {
885 // Add an entry mapping
886 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
887 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
888 match trait_item.node {
889 hir::ConstTraitItem(..) => ty::ConstTraitItemId(def_id),
890 hir::MethodTraitItem(..) => ty::MethodTraitItemId(def_id),
891 hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id)
894 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
897 hir::ItemStruct(ref struct_def, _) => {
898 let (scheme, predicates) = convert_typed_item(ccx, it);
899 write_ty_to_tcx(tcx, it.id, scheme.ty);
901 let it_def_id = ccx.tcx.map.local_def_id(it.id);
902 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
904 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
905 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
908 if !struct_def.is_struct() {
909 convert_variant_ctor(tcx, struct_def.id(), variant, scheme, predicates);
912 hir::ItemTy(_, ref generics) => {
913 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
914 let (scheme, _) = convert_typed_item(ccx, it);
915 write_ty_to_tcx(tcx, it.id, scheme.ty);
918 // This call populates the type cache with the converted type
919 // of the item in passing. All we have to do here is to write
920 // it into the node type table.
921 let (scheme, _) = convert_typed_item(ccx, it);
922 write_ty_to_tcx(tcx, it.id, scheme.ty);
927 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
928 ctor_id: ast::NodeId,
929 variant: ty::VariantDef<'tcx>,
930 scheme: ty::TypeScheme<'tcx>,
931 predicates: ty::GenericPredicates<'tcx>) {
932 let ctor_ty = match variant.kind() {
933 VariantKind::Unit | VariantKind::Struct => scheme.ty,
934 VariantKind::Tuple => {
938 .map(|field| field.unsubst_ty())
940 tcx.mk_ctor_fn(tcx.map.local_def_id(ctor_id),
945 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
946 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
947 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
949 generics: scheme.generics,
954 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
955 def: ty::AdtDefMaster<'tcx>,
956 scheme: ty::TypeScheme<'tcx>,
957 predicates: ty::GenericPredicates<'tcx>,
958 variants: &[hir::Variant]) {
959 // fill the field types
960 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
961 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
962 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
965 // Convert the ctor, if any. This also registers the variant as
967 convert_variant_ctor(
969 variant.node.data.id(),
977 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
981 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
982 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
983 let fields = def.fields().iter().map(|f| {
984 let fid = tcx.map.local_def_id(f.node.id);
986 hir::NamedField(name, vis) => {
987 let dup_span = seen_fields.get(&name).cloned();
988 if let Some(prev_span) = dup_span {
989 let mut err = struct_span_err!(tcx.sess, f.span, E0124,
990 "field `{}` is already declared",
992 span_note!(&mut err, prev_span, "previously declared here");
995 seen_fields.insert(name, f.span);
998 ty::FieldDefData::new(fid, name, vis)
1000 hir::UnnamedField(vis) => {
1001 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1005 ty::VariantDefData {
1011 hir::VariantData::Struct(..) => ty::VariantKind::Struct,
1012 hir::VariantData::Tuple(..) => ty::VariantKind::Tuple,
1013 hir::VariantData::Unit(..) => ty::VariantKind::Unit,
1018 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1020 def: &hir::VariantData)
1021 -> ty::AdtDefMaster<'tcx>
1024 let did = tcx.map.local_def_id(it.id);
1025 let ctor_id = if !def.is_struct() {
1026 tcx.map.local_def_id(def.id())
1032 ty::AdtKind::Struct,
1033 vec![convert_struct_variant(tcx, ctor_id, it.name, 0, def)]
1037 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1040 -> ty::AdtDefMaster<'tcx>
1042 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1044 e: &hir::Expr) -> Option<ty::Disr> {
1045 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1047 let hint = UncheckedExprHint(repr_ty);
1048 match const_eval::eval_const_expr_partial(tcx, e, hint, None) {
1049 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1050 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1052 let sign_desc = if repr_ty.is_signed() {
1057 span_err!(tcx.sess, e.span, E0079,
1058 "expected {} integer constant",
1063 let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
1064 "constant evaluation error: {}",
1066 if !e.span.contains(err.span) {
1067 diag.span_note(e.span, "for enum discriminant here");
1075 fn report_discrim_overflow(tcx: &ty::ctxt,
1078 repr_type: attr::IntType,
1079 prev_val: ty::Disr) {
1080 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1081 let computed_value = repr_type.disr_string(computed_value);
1082 let prev_val = repr_type.disr_string(prev_val);
1083 let repr_type = repr_type.to_ty(tcx);
1084 span_err!(tcx.sess, variant_span, E0370,
1085 "enum discriminant overflowed on value after {}: {}; \
1086 set explicitly via {} = {} if that is desired outcome",
1087 prev_val, repr_type, variant_name, computed_value);
1090 fn next_disr(tcx: &ty::ctxt,
1092 repr_type: attr::IntType,
1093 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1094 if let Some(prev_disr_val) = prev_disr_val {
1095 let result = repr_type.disr_incr(prev_disr_val);
1096 if let None = result {
1097 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1098 repr_type, prev_disr_val);
1102 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1105 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1108 -> ty::VariantDefData<'tcx, 'tcx>
1110 let did = tcx.map.local_def_id(v.node.data.id());
1111 let name = v.node.name;
1112 convert_struct_variant(tcx, did, name, disr, &v.node.data)
1114 let did = tcx.map.local_def_id(it.id);
1115 let repr_hints = tcx.lookup_repr_hints(did);
1116 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1117 let mut prev_disr = None;
1118 let variants = def.variants.iter().map(|v| {
1119 let disr = match v.node.disr_expr {
1120 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1121 None => next_disr(tcx, v, repr_type, prev_disr)
1122 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1124 let v = convert_enum_variant(tcx, v, disr);
1125 prev_disr = Some(disr);
1128 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1131 /// Ensures that the super-predicates of the trait with def-id
1132 /// trait_def_id are converted and stored. This does NOT ensure that
1133 /// the transitive super-predicates are converted; that is the job of
1134 /// the `ensure_super_predicates()` method in the `AstConv` impl
1135 /// above. Returns a list of trait def-ids that must be ensured as
1136 /// well to guarantee that the transitive superpredicates are
1138 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1139 trait_def_id: DefId)
1144 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1146 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1149 // If this trait comes from an external crate, then all of the
1150 // supertraits it may depend on also must come from external
1151 // crates, and hence all of them already have their
1152 // super-predicates "converted" (and available from crate
1153 // meta-data), so there is no need to transitively test them.
1157 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1158 let superpredicates = superpredicates.unwrap_or_else(|| {
1159 let item = match ccx.tcx.map.get(trait_node_id) {
1160 hir_map::NodeItem(item) => item,
1161 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1164 let (generics, bounds) = match item.node {
1165 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1166 _ => tcx.sess.span_bug(item.span,
1167 "ensure_super_predicates_step invoked on non-trait"),
1170 // In-scope when converting the superbounds for `Trait` are
1171 // that `Self:Trait` as well as any bounds that appear on the
1173 let trait_def = trait_def_of_item(ccx, item);
1174 let self_predicate = ty::GenericPredicates {
1175 predicates: VecPerParamSpace::new(vec![],
1176 vec![trait_def.trait_ref.to_predicate()],
1179 let scope = &(generics, &self_predicate);
1181 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1182 let self_param_ty = tcx.mk_self_type();
1183 let superbounds1 = compute_bounds(&ccx.icx(scope),
1189 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1191 // Convert any explicit superbounds in the where clause,
1192 // e.g. `trait Foo where Self : Bar`:
1193 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1195 // Combine the two lists to form the complete set of superbounds:
1196 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1197 let superpredicates = ty::GenericPredicates {
1198 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1200 debug!("superpredicates for trait {:?} = {:?}",
1201 tcx.map.local_def_id(item.id),
1204 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1209 let def_ids: Vec<_> = superpredicates.predicates
1211 .filter_map(|p| p.to_opt_poly_trait_ref())
1212 .map(|tr| tr.def_id())
1215 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1220 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1222 -> &'tcx ty::TraitDef<'tcx>
1224 let def_id = ccx.tcx.map.local_def_id(it.id);
1227 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1231 let (unsafety, generics, items) = match it.node {
1232 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1233 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1236 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1237 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1238 let mut err = ccx.tcx.sess.struct_span_err(
1240 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1241 which traits can use parenthetical notation");
1242 fileline_help!(&mut err, it.span,
1243 "add `#![feature(unboxed_closures)]` to \
1244 the crate attributes to use it");
1248 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1250 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1252 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1253 match trait_item.node {
1254 hir::TypeTraitItem(..) => Some(trait_item.name),
1259 let trait_ref = ty::TraitRef {
1264 let trait_def = ty::TraitDef::new(unsafety,
1268 associated_type_names);
1270 return tcx.intern_trait_def(trait_def);
1272 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1273 generics: &hir::Generics)
1278 // Creates a no-op substitution for the trait's type parameters.
1283 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1286 name: def.lifetime.name
1290 // Start with the generics in the type parameters...
1295 .map(|(i, def)| tcx.mk_param(TypeSpace,
1296 i as u32, def.name))
1299 // ...and also create the `Self` parameter.
1300 let self_ty = tcx.mk_self_type();
1302 Substs::new_trait(types, regions, self_ty)
1306 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1307 trait_node_id: ast::NodeId,
1308 assoc_name: ast::Name)
1311 let item = match ccx.tcx.map.get(trait_node_id) {
1312 hir_map::NodeItem(item) => item,
1313 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1316 let trait_items = match item.node {
1317 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1318 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1321 trait_items.iter().any(|trait_item| {
1322 match trait_item.node {
1323 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1329 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1331 let trait_def = trait_def_of_item(ccx, it);
1333 let def_id = ccx.tcx.map.local_def_id(it.id);
1335 let (generics, items) = match it.node {
1336 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1340 &format!("trait_def_of_item invoked on {:?}", s));
1344 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1346 // `ty_generic_predicates` below will consider the bounds on the type
1347 // parameters (including `Self`) and the explicit where-clauses,
1348 // but to get the full set of predicates on a trait we need to add
1349 // in the supertrait bounds and anything declared on the
1350 // associated types.
1351 let mut base_predicates = super_predicates;
1353 // Add in a predicate that `Self:Trait` (where `Trait` is the
1354 // current trait). This is needed for builtin bounds.
1355 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1356 base_predicates.predicates.push(SelfSpace, self_predicate);
1358 // add in the explicit where-clauses
1359 let mut trait_predicates =
1360 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1362 let assoc_predicates = predicates_for_associated_types(ccx,
1365 trait_def.trait_ref,
1367 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1369 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1370 assert!(prev_predicates.is_none());
1374 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1375 ast_generics: &hir::Generics,
1376 trait_predicates: &ty::GenericPredicates<'tcx>,
1377 self_trait_ref: ty::TraitRef<'tcx>,
1378 trait_items: &[hir::TraitItem])
1379 -> Vec<ty::Predicate<'tcx>>
1381 trait_items.iter().flat_map(|trait_item| {
1382 let bounds = match trait_item.node {
1383 hir::TypeTraitItem(ref bounds, _) => bounds,
1385 return vec!().into_iter();
1389 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1392 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1395 SizedByDefault::Yes,
1398 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1403 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1405 -> ty::TypeScheme<'tcx>
1407 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1408 match ccx.tcx.map.find(node_id) {
1409 Some(hir_map::NodeItem(item)) => {
1410 type_scheme_of_item(ccx, &*item)
1412 Some(hir_map::NodeForeignItem(foreign_item)) => {
1413 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1414 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1417 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1418 in get_item_type_scheme(): {:?}",
1423 ccx.tcx.lookup_item_type(def_id)
1427 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1429 -> ty::TypeScheme<'tcx>
1431 let item_def_id = ccx.tcx.map.local_def_id(item.id);
1432 ccx.tcx.tcache.memoize(item_def_id, || {
1433 // NB. Since the `memoized` function enters a new task, and we
1434 // are giving this task access to the item `item`, we must
1436 ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
1437 compute_type_scheme_of_item(ccx, item)
1441 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1443 -> ty::TypeScheme<'tcx>
1447 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1448 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1449 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1451 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1452 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1453 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1454 let ty = tcx.mk_fn(Some(ccx.tcx.map.local_def_id(it.id)), tcx.mk_bare_fn(tofd));
1455 ty::TypeScheme { ty: ty, generics: ty_generics }
1457 hir::ItemTy(ref t, ref generics) => {
1458 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1459 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1460 ty::TypeScheme { ty: ty, generics: ty_generics }
1462 hir::ItemEnum(ref ei, ref generics) => {
1463 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1464 let substs = mk_item_substs(ccx, &ty_generics);
1465 let def = convert_enum_def(tcx, it, ei);
1466 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1467 ty::TypeScheme { ty: t, generics: ty_generics }
1469 hir::ItemStruct(ref si, ref generics) => {
1470 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1471 let substs = mk_item_substs(ccx, &ty_generics);
1472 let def = convert_struct_def(tcx, it, si);
1473 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1474 ty::TypeScheme { ty: t, generics: ty_generics }
1476 hir::ItemDefaultImpl(..) |
1477 hir::ItemTrait(..) |
1480 hir::ItemForeignMod(..) |
1481 hir::ItemExternCrate(..) |
1482 hir::ItemUse(..) => {
1485 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1491 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1493 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1497 let tag = type_scheme_of_item(ccx, it);
1498 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1499 let predicates = match it.node {
1500 hir::ItemStatic(..) | hir::ItemConst(..) => {
1501 ty::GenericPredicates::empty()
1503 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1504 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1506 hir::ItemTy(_, ref generics) => {
1507 ty_generic_predicates_for_type_or_impl(ccx, generics)
1509 hir::ItemEnum(_, ref generics) => {
1510 ty_generic_predicates_for_type_or_impl(ccx, generics)
1512 hir::ItemStruct(_, ref generics) => {
1513 ty_generic_predicates_for_type_or_impl(ccx, generics)
1515 hir::ItemDefaultImpl(..) |
1516 hir::ItemTrait(..) |
1517 hir::ItemExternCrate(..) |
1521 hir::ItemForeignMod(..) => {
1524 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1529 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1530 predicates.clone());
1531 assert!(prev_predicates.is_none());
1534 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1535 let object_lifetime_default_reprs: String =
1536 scheme.generics.types.iter()
1537 .map(|t| match t.object_lifetime_default {
1538 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1539 d => format!("{:?}", d),
1541 .collect::<Vec<String>>()
1544 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1547 return (scheme, predicates);
1550 fn type_scheme_of_foreign_item<'a, 'tcx>(
1551 ccx: &CrateCtxt<'a, 'tcx>,
1552 item: &hir::ForeignItem,
1554 -> ty::TypeScheme<'tcx>
1556 let item_def_id = ccx.tcx.map.local_def_id(item.id);
1557 ccx.tcx.tcache.memoize(item_def_id, || {
1558 // NB. Since the `memoized` function enters a new task, and we
1559 // are giving this task access to the item `item`, we must
1561 ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
1562 compute_type_scheme_of_foreign_item(ccx, item, abi)
1566 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1567 ccx: &CrateCtxt<'a, 'tcx>,
1568 it: &hir::ForeignItem,
1570 -> ty::TypeScheme<'tcx>
1573 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1574 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1576 hir::ForeignItemStatic(ref t, _) => {
1578 generics: ty::Generics::empty(),
1579 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1585 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1586 it: &hir::ForeignItem)
1588 // For reasons I cannot fully articulate, I do so hate the AST
1589 // map, and I regard each time that I use it as a personal and
1590 // moral failing, but at the moment it seems like the only
1591 // convenient way to extract the ABI. - ndm
1593 let abi = tcx.map.get_foreign_abi(it.id);
1595 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1596 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1598 let predicates = match it.node {
1599 hir::ForeignItemFn(_, ref generics) => {
1600 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1602 hir::ForeignItemStatic(..) => {
1603 ty::GenericPredicates::empty()
1607 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1609 assert!(prev_predicates.is_none());
1612 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1613 generics: &hir::Generics)
1614 -> ty::Generics<'tcx> {
1615 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1618 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1619 generics: &hir::Generics)
1620 -> ty::GenericPredicates<'tcx>
1622 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1625 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1626 trait_id: ast::NodeId,
1627 substs: &'tcx Substs<'tcx>,
1628 ast_generics: &hir::Generics)
1629 -> ty::Generics<'tcx>
1631 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1632 ccx.tcx.map.local_def_id(trait_id), substs);
1634 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1636 // Add in the self type parameter.
1638 // Something of a hack: use the node id for the trait, also as
1639 // the node id for the Self type parameter.
1640 let param_id = trait_id;
1642 let parent = ccx.tcx.map.get_parent(param_id);
1644 let def = ty::TypeParameterDef {
1647 name: special_idents::type_self.name,
1648 def_id: ccx.tcx.map.local_def_id(param_id),
1649 default_def_id: ccx.tcx.map.local_def_id(parent),
1651 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1654 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1656 generics.types.push(SelfSpace, def);
1661 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1662 generics: &hir::Generics,
1663 base_generics: &ty::Generics<'tcx>)
1664 -> ty::Generics<'tcx>
1666 ty_generics(ccx, FnSpace, generics, base_generics)
1669 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1670 generics: &hir::Generics,
1671 base_predicates: &ty::GenericPredicates<'tcx>)
1672 -> ty::GenericPredicates<'tcx>
1674 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1677 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1678 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1679 bounds: &mut ty::BuiltinBounds,
1680 ast_bounds: &[hir::TyParamBound],
1683 let tcx = astconv.tcx();
1685 // Try to find an unbound in bounds.
1686 let mut unbound = None;
1687 for ab in ast_bounds {
1688 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1689 if unbound.is_none() {
1690 assert!(ptr.bound_lifetimes.is_empty());
1691 unbound = Some(ptr.trait_ref.clone());
1693 span_err!(tcx.sess, span, E0203,
1694 "type parameter has more than one relaxed default \
1695 bound, only one is supported");
1700 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1703 // FIXME(#8559) currently requires the unbound to be built-in.
1704 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1706 Ok(kind_id) if trait_def_id != kind_id => {
1707 tcx.sess.span_warn(span,
1708 "default bound relaxed for a type parameter, but \
1709 this does nothing because the given bound is not \
1710 a default. Only `?Sized` is supported");
1711 tcx.try_add_builtin_trait(kind_id, bounds);
1716 _ if kind_id.is_ok() => {
1717 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1719 // No lang item for Sized, so we can't add it as a bound.
1724 /// Returns the early-bound lifetimes declared in this generics
1725 /// listing. For anything other than fns/methods, this is just all
1726 /// the lifetimes that are declared. For fns or methods, we have to
1727 /// screen out those that do not appear in any where-clauses etc using
1728 /// `resolve_lifetime::early_bound_lifetimes`.
1729 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1730 ast_generics: &hir::Generics)
1731 -> Vec<hir::LifetimeDef>
1734 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1735 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1739 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1741 ast_generics: &hir::Generics,
1742 base_predicates: &ty::GenericPredicates<'tcx>)
1743 -> ty::GenericPredicates<'tcx>
1746 let mut result = base_predicates.clone();
1748 // Collect the predicates that were written inline by the user on each
1749 // type parameter (e.g., `<T:Foo>`).
1750 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1751 let index = index as u32;
1752 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1753 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1756 SizedByDefault::Yes,
1758 let predicates = bounds.predicates(ccx.tcx, param_ty);
1759 result.predicates.extend(space, predicates.into_iter());
1762 // Collect the region predicates that were declared inline as
1763 // well. In the case of parameters declared on a fn or method, we
1764 // have to be careful to only iterate over early-bound regions.
1765 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1766 for (index, param) in early_lifetimes.iter().enumerate() {
1767 let index = index as u32;
1769 ty::ReEarlyBound(ty::EarlyBoundRegion {
1772 name: param.lifetime.name
1774 for bound in ¶m.bounds {
1775 let bound_region = ast_region_to_region(ccx.tcx, bound);
1776 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1777 result.predicates.push(space, outlives.to_predicate());
1781 // Add in the bounds that appear in the where-clause
1782 let where_clause = &ast_generics.where_clause;
1783 for predicate in &where_clause.predicates {
1785 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1786 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1788 &*bound_pred.bounded_ty);
1790 for bound in bound_pred.bounds.iter() {
1792 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1793 let mut projections = Vec::new();
1796 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1801 result.predicates.push(space, trait_ref.to_predicate());
1803 for projection in &projections {
1804 result.predicates.push(space, projection.to_predicate());
1808 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1809 let region = ast_region_to_region(tcx, lifetime);
1810 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1811 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1817 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1818 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1819 for bound in ®ion_pred.bounds {
1820 let r2 = ast_region_to_region(tcx, bound);
1821 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1822 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1826 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1828 tcx.sess.span_bug(eq_pred.span,
1829 "Equality constraints are not yet \
1830 implemented (#20041)")
1838 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1840 ast_generics: &hir::Generics,
1841 base_generics: &ty::Generics<'tcx>)
1842 -> ty::Generics<'tcx>
1845 let mut result = base_generics.clone();
1847 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1848 for (i, l) in early_lifetimes.iter().enumerate() {
1849 let bounds = l.bounds.iter()
1850 .map(|l| ast_region_to_region(tcx, l))
1852 let def = ty::RegionParameterDef { name: l.lifetime.name,
1855 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1857 result.regions.push(space, def);
1860 assert!(result.types.is_empty_in(space));
1862 // Now create the real type parameters.
1863 for i in 0..ast_generics.ty_params.len() {
1864 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1865 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1866 result.types.push(space, def);
1872 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1878 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1880 for leaf_ty in ty.walk() {
1881 if let ty::TyParam(p) = leaf_ty.sty {
1882 if p.space == space && p.idx >= index {
1883 span_err!(ccx.tcx.sess, path.span, E0128,
1884 "type parameters with a default cannot use \
1885 forward declared identifiers");
1887 return ccx.tcx.types.err
1895 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1896 ast_generics: &hir::Generics,
1899 -> ty::TypeParameterDef<'tcx>
1901 let param = &ast_generics.ty_params[index as usize];
1904 match tcx.ty_param_defs.borrow().get(¶m.id) {
1905 Some(d) => { return d.clone(); }
1909 let default = param.default.as_ref().map(
1910 |def| convert_default_type_parameter(ccx, def, space, index)
1913 let object_lifetime_default =
1914 compute_object_lifetime_default(ccx, param.id,
1915 ¶m.bounds, &ast_generics.where_clause);
1917 let parent = tcx.map.get_parent(param.id);
1919 if space != TypeSpace && default.is_some() {
1920 if !tcx.sess.features.borrow().default_type_parameter_fallback {
1922 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1925 format!("defaults for type parameters are only allowed on type definitions, \
1926 like `struct` or `enum`"));
1930 let def = ty::TypeParameterDef {
1934 def_id: ccx.tcx.map.local_def_id(param.id),
1935 default_def_id: ccx.tcx.map.local_def_id(parent),
1937 object_lifetime_default: object_lifetime_default,
1940 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
1945 /// Scan the bounds and where-clauses on a parameter to extract bounds
1946 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
1947 /// This runs as part of computing the minimal type scheme, so we
1948 /// intentionally avoid just asking astconv to convert all the where
1949 /// clauses into a `ty::Predicate`. This is because that could induce
1950 /// artificial cycles.
1951 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1952 param_id: ast::NodeId,
1953 param_bounds: &[hir::TyParamBound],
1954 where_clause: &hir::WhereClause)
1955 -> ty::ObjectLifetimeDefault
1957 let inline_bounds = from_bounds(ccx, param_bounds);
1958 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
1959 let all_bounds: HashSet<_> = inline_bounds.into_iter()
1960 .chain(where_bounds)
1962 return if all_bounds.len() > 1 {
1963 ty::ObjectLifetimeDefault::Ambiguous
1964 } else if all_bounds.len() == 0 {
1965 ty::ObjectLifetimeDefault::BaseDefault
1967 ty::ObjectLifetimeDefault::Specific(
1968 all_bounds.into_iter().next().unwrap())
1971 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1972 bounds: &[hir::TyParamBound])
1976 .filter_map(|bound| {
1978 hir::TraitTyParamBound(..) =>
1980 hir::RegionTyParamBound(ref lifetime) =>
1981 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
1987 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1988 param_id: ast::NodeId,
1989 predicates: &[hir::WherePredicate])
1993 .flat_map(|predicate| {
1995 hir::WherePredicate::BoundPredicate(ref data) => {
1996 if data.bound_lifetimes.is_empty() &&
1997 is_param(ccx.tcx, &data.bounded_ty, param_id)
1999 from_bounds(ccx, &data.bounds).into_iter()
2001 Vec::new().into_iter()
2004 hir::WherePredicate::RegionPredicate(..) |
2005 hir::WherePredicate::EqPredicate(..) => {
2006 Vec::new().into_iter()
2014 enum SizedByDefault { Yes, No, }
2016 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2017 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2018 /// built-in trait (formerly known as kind): Send.
2019 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2020 param_ty: ty::Ty<'tcx>,
2021 ast_bounds: &[hir::TyParamBound],
2022 sized_by_default: SizedByDefault,
2024 -> astconv::Bounds<'tcx>
2027 conv_param_bounds(astconv,
2032 if let SizedByDefault::Yes = sized_by_default {
2033 add_unsized_bound(astconv,
2034 &mut bounds.builtin_bounds,
2039 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2044 /// Converts a specific TyParamBound from the AST into a set of
2045 /// predicates that apply to the self-type. A vector is returned
2046 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2047 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2048 /// and `<T as Bar>::X == i32`).
2049 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2051 bound: &hir::TyParamBound)
2052 -> Vec<ty::Predicate<'tcx>>
2055 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2056 let mut projections = Vec::new();
2057 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2058 projections.into_iter()
2059 .map(|p| p.to_predicate())
2060 .chain(Some(pred.to_predicate()))
2063 hir::RegionTyParamBound(ref lifetime) => {
2064 let region = ast_region_to_region(astconv.tcx(), lifetime);
2065 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2066 vec![ty::Predicate::TypeOutlives(pred)]
2068 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2074 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2076 trait_ref: &hir::PolyTraitRef,
2077 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2078 -> ty::PolyTraitRef<'tcx>
2080 astconv::instantiate_poly_trait_ref(astconv,
2087 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2089 param_ty: ty::Ty<'tcx>,
2090 ast_bounds: &[hir::TyParamBound])
2091 -> astconv::Bounds<'tcx>
2093 let tcx = astconv.tcx();
2094 let astconv::PartitionedBounds {
2098 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2100 let mut projection_bounds = Vec::new();
2102 let trait_bounds: Vec<ty::PolyTraitRef> =
2104 .map(|bound| conv_poly_trait_ref(astconv,
2107 &mut projection_bounds))
2110 let region_bounds: Vec<ty::Region> =
2111 region_bounds.into_iter()
2112 .map(|r| ast_region_to_region(tcx, r))
2116 region_bounds: region_bounds,
2117 builtin_bounds: builtin_bounds,
2118 trait_bounds: trait_bounds,
2119 projection_bounds: projection_bounds,
2123 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2124 ccx: &CrateCtxt<'a, 'tcx>,
2126 ast_generics: &hir::Generics,
2128 -> ty::TypeScheme<'tcx>
2130 for i in &decl.inputs {
2131 match (*i).pat.node {
2132 hir::PatIdent(_, _, _) => (),
2135 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2136 "patterns aren't allowed in foreign function declarations");
2141 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2143 let rb = BindingRscope::new();
2144 let input_tys = decl.inputs
2146 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2149 let output = match decl.output {
2150 hir::Return(ref ty) =>
2151 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2152 hir::DefaultReturn(..) =>
2153 ty::FnConverging(ccx.tcx.mk_nil()),
2154 hir::NoReturn(..) =>
2158 let t_fn = ccx.tcx.mk_fn(None,
2159 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2161 unsafety: hir::Unsafety::Unsafe,
2162 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2164 variadic: decl.variadic}),
2168 generics: ty_generics,
2173 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2174 ty_generics: &ty::Generics<'tcx>)
2178 ty_generics.types.map(
2179 |def| ccx.tcx.mk_param_from_def(def));
2182 ty_generics.regions.map(
2183 |def| def.to_early_bound_region());
2185 Substs::new(types, regions)
2188 /// Checks that all the type parameters on an impl
2189 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2190 ast_generics: &hir::Generics,
2191 impl_predicates: &mut ty::GenericPredicates<'tcx>,
2194 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2195 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2197 assert!(impl_predicates.predicates.is_empty_in(FnSpace));
2198 assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
2200 // The trait reference is an input, so find all type parameters
2201 // reachable from there, to start (if this is an inherent impl,
2202 // then just examine the self type).
2203 let mut input_parameters: HashSet<_> =
2204 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2205 if let Some(ref trait_ref) = impl_trait_ref {
2206 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2209 ctp::setup_constraining_predicates(tcx,
2210 impl_predicates.predicates.get_mut_slice(TypeSpace),
2212 &mut input_parameters);
2214 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2215 let param_ty = ty::ParamTy { space: TypeSpace,
2217 name: ty_param.name };
2218 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2219 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2224 fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2225 ast_generics: &hir::Generics,
2227 impl_items: &[hir::ImplItem])
2229 // Every lifetime used in an associated type must be constrained.
2230 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2231 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2232 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2234 let mut input_parameters: HashSet<_> =
2235 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2236 if let Some(ref trait_ref) = impl_trait_ref {
2237 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2239 ctp::identify_constrained_type_params(tcx,
2240 &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
2242 let lifetimes_in_associated_types: HashSet<_> =
2244 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2245 .filter_map(|item| match item {
2246 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2247 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2249 .flat_map(|ty| ctp::parameters_for_type(ty, true))
2250 .filter_map(|p| match p {
2251 ctp::Parameter::Type(_) => None,
2252 ctp::Parameter::Region(r) => Some(r),
2256 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2257 let region = ty::EarlyBoundRegion { space: TypeSpace,
2258 index: index as u32,
2259 name: lifetime_def.lifetime.name };
2261 lifetimes_in_associated_types.contains(®ion) && // (*)
2262 !input_parameters.contains(&ctp::Parameter::Region(region))
2264 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2265 "lifetime", ®ion.name.to_string());
2269 // (*) This is a horrible concession to reality. I think it'd be
2270 // better to just ban unconstrianed lifetimes outright, but in
2271 // practice people do non-hygenic macros like:
2274 // macro_rules! __impl_slice_eq1 {
2275 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2276 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2283 // In a concession to backwards compatbility, we continue to
2284 // permit those, so long as the lifetimes aren't used in
2285 // associated types. I believe this is sound, because lifetimes
2286 // used elsewhere are not projected back out.
2289 fn report_unused_parameter(tcx: &ty::ctxt,
2294 span_err!(tcx.sess, span, E0207,
2295 "the {} parameter `{}` is not constrained by the \
2296 impl trait, self type, or predicates",