1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 The collect phase of type check has the job of visiting all items,
16 determining their type, and writing that type into the `tcx.tcache`
17 table. Despite its name, this table does not really operate as a
18 *cache*, at least not for the types of items defined within the
19 current crate: we assume that after the collect phase, the types of
20 all local items will be present in the table.
22 Unlike most of the types that are present in Rust, the types computed
23 for each item are in fact type schemes. This means that they are
24 generic types that may have type parameters. TypeSchemes are
25 represented by an instance of `ty::TypeScheme`. This combines the
26 core type along with a list of the bounds for each parameter. Type
27 parameters themselves are represented as `ty_param()` instances.
29 The phasing of type conversion is somewhat complicated. There is no
30 clear set of phases we can enforce (e.g., converting traits first,
31 then types, or something like that) because the user can introduce
32 arbitrary interdependencies. So instead we generally convert things
33 lazilly and on demand, and include logic that checks for cycles.
34 Demand is driven by calls to `AstConv::get_item_type_scheme` or
35 `AstConv::lookup_trait_def`.
37 Currently, we "convert" types and traits in three phases (note that
38 conversion only affects the types of items / enum variants / methods;
39 it does not e.g. compute the types of individual expressions):
45 Conversion itself is done by simply walking each of the items in turn
46 and invoking an appropriate function (e.g., `trait_def_of_item` or
47 `convert_item`). However, it is possible that while converting an
48 item, we may need to compute the *type scheme* or *trait definition*
51 There are some shortcomings in this design:
53 - Before walking the set of supertraits for a given trait, you must
54 call `ensure_super_predicates` on that trait def-id. Otherwise,
55 `lookup_super_predicates` will result in ICEs.
56 - Because the type scheme includes defaults, cycles through type
57 parameter defaults are illegal even if those defaults are never
58 employed. This is not necessarily a bug.
59 - The phasing of trait definitions before type definitions does not
60 seem to be necessary, sufficient, or particularly helpful, given that
61 processing a trait definition can trigger processing a type def and
62 vice versa. However, if I remove it, I get ICEs, so some more work is
63 needed in that area. -nmatsakis
67 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
68 use metadata::cstore::LOCAL_CRATE;
70 use middle::def_id::DefId;
71 use constrained_type_params as ctp;
72 use middle::lang_items::SizedTraitLangItem;
73 use middle::free_region::FreeRegionMap;
75 use middle::resolve_lifetime;
76 use middle::const_eval::{self, ConstVal};
77 use middle::const_eval::EvalHint::UncheckedExprHint;
78 use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
79 use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
80 use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme};
81 use middle::ty::{VariantKind};
82 use middle::ty::fold::{TypeFolder, TypeFoldable};
83 use middle::ty::util::IntTypeExt;
86 use rustc::front::map as hir_map;
87 use util::common::{ErrorReported, memoized};
88 use util::nodemap::{FnvHashMap, FnvHashSet};
91 use std::cell::{Cell, RefCell};
92 use std::collections::HashSet;
98 use syntax::codemap::Span;
99 use syntax::parse::token::special_idents;
101 use rustc_front::hir;
102 use rustc_front::visit;
103 use rustc_front::print::pprust;
105 ///////////////////////////////////////////////////////////////////////////
108 pub fn collect_item_types(tcx: &ty::ctxt) {
109 let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) };
111 let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
112 visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
114 let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
115 visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
118 ///////////////////////////////////////////////////////////////////////////
120 struct CrateCtxt<'a,'tcx:'a> {
121 tcx: &'a ty::ctxt<'tcx>,
123 // This stack is used to identify cycles in the user's source.
124 // Note that these cycles can cross multiple items.
125 stack: RefCell<Vec<AstConvRequest>>,
128 /// Context specific to some particular item. This is what implements
129 /// AstConv. It has information about the predicates that are defined
130 /// on the trait. Unfortunately, this predicate information is
131 /// available in various different forms at various points in the
132 /// process. So we can't just store a pointer to e.g. the AST or the
133 /// parsed ty form, we have to be more flexible. To this end, the
134 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
135 /// that it uses to satisfy `get_type_parameter_bounds` requests.
136 /// This object might draw the information from the AST
137 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
138 /// or both (a tuple).
139 struct ItemCtxt<'a,'tcx:'a> {
140 ccx: &'a CrateCtxt<'a,'tcx>,
141 param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
144 #[derive(Copy, Clone, PartialEq, Eq)]
145 enum AstConvRequest {
146 GetItemTypeScheme(DefId),
148 EnsureSuperPredicates(DefId),
149 GetTypeParameterBounds(ast::NodeId),
152 ///////////////////////////////////////////////////////////////////////////
153 // First phase: just collect *trait definitions* -- basically, the set
154 // of type parameters and supertraits. This is information we need to
155 // know later when parsing field defs.
157 struct CollectTraitDefVisitor<'a, 'tcx: 'a> {
158 ccx: &'a CrateCtxt<'a, 'tcx>
161 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> {
162 fn visit_item(&mut self, i: &hir::Item) {
164 hir::ItemTrait(..) => {
165 // computing the trait def also fills in the table
166 let _ = trait_def_of_item(self.ccx, i);
171 visit::walk_item(self, i);
175 ///////////////////////////////////////////////////////////////////////////
176 // Second phase: collection proper.
178 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
179 ccx: &'a CrateCtxt<'a, 'tcx>
182 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
183 fn visit_item(&mut self, i: &hir::Item) {
184 convert_item(self.ccx, i);
185 visit::walk_item(self, i);
187 fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
188 convert_foreign_item(self.ccx, i);
189 visit::walk_foreign_item(self, i);
193 ///////////////////////////////////////////////////////////////////////////
194 // Utility types and common code for the above passes.
196 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
197 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
198 ItemCtxt { ccx: self, param_bounds: param_bounds }
201 fn method_ty(&self, method_id: ast::NodeId) -> Rc<ty::Method<'tcx>> {
202 let def_id = DefId::local(method_id);
203 match *self.tcx.impl_or_trait_items.borrow().get(&def_id).unwrap() {
204 ty::MethodTraitItem(ref mty) => mty.clone(),
206 self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id));
211 fn cycle_check<F,R>(&self,
213 request: AstConvRequest,
215 -> Result<R,ErrorReported>
216 where F: FnOnce() -> Result<R,ErrorReported>
219 let mut stack = self.stack.borrow_mut();
220 match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
223 let cycle = &stack[i..];
224 self.report_cycle(span, cycle);
225 return Err(ErrorReported);
233 self.stack.borrow_mut().pop();
237 fn report_cycle(&self,
239 cycle: &[AstConvRequest])
241 assert!(!cycle.is_empty());
244 span_err!(tcx.sess, span, E0391,
245 "unsupported cyclic reference between types/traits detected");
248 AstConvRequest::GetItemTypeScheme(def_id) |
249 AstConvRequest::GetTraitDef(def_id) => {
251 &format!("the cycle begins when processing `{}`...",
252 tcx.item_path_str(def_id)));
254 AstConvRequest::EnsureSuperPredicates(def_id) => {
256 &format!("the cycle begins when computing the supertraits of `{}`...",
257 tcx.item_path_str(def_id)));
259 AstConvRequest::GetTypeParameterBounds(id) => {
260 let def = tcx.type_parameter_def(id);
262 &format!("the cycle begins when computing the bounds \
263 for type parameter `{}`...",
268 for request in &cycle[1..] {
270 AstConvRequest::GetItemTypeScheme(def_id) |
271 AstConvRequest::GetTraitDef(def_id) => {
273 &format!("...which then requires processing `{}`...",
274 tcx.item_path_str(def_id)));
276 AstConvRequest::EnsureSuperPredicates(def_id) => {
278 &format!("...which then requires computing the supertraits of `{}`...",
279 tcx.item_path_str(def_id)));
281 AstConvRequest::GetTypeParameterBounds(id) => {
282 let def = tcx.type_parameter_def(id);
284 &format!("...which then requires computing the bounds \
285 for type parameter `{}`...",
292 AstConvRequest::GetItemTypeScheme(def_id) |
293 AstConvRequest::GetTraitDef(def_id) => {
295 &format!("...which then again requires processing `{}`, completing the cycle.",
296 tcx.item_path_str(def_id)));
298 AstConvRequest::EnsureSuperPredicates(def_id) => {
300 &format!("...which then again requires computing the supertraits of `{}`, \
301 completing the cycle.",
302 tcx.item_path_str(def_id)));
304 AstConvRequest::GetTypeParameterBounds(id) => {
305 let def = tcx.type_parameter_def(id);
307 &format!("...which then again requires computing the bounds \
308 for type parameter `{}`, completing the cycle.",
314 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
315 fn get_trait_def(&self, trait_id: DefId)
316 -> &'tcx ty::TraitDef<'tcx>
320 if trait_id.krate != LOCAL_CRATE {
321 return tcx.lookup_trait_def(trait_id)
324 let item = match tcx.map.get(trait_id.node) {
325 hir_map::NodeItem(item) => item,
326 _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
329 trait_def_of_item(self, &*item)
332 /// Ensure that the (transitive) super predicates for
333 /// `trait_def_id` are available. This will report a cycle error
334 /// if a trait `X` (transitively) extends itself in some form.
335 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
336 -> Result<(), ErrorReported>
338 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
339 let def_ids = ensure_super_predicates_step(self, trait_def_id);
341 for def_id in def_ids {
342 try!(self.ensure_super_predicates(span, def_id));
350 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
351 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
352 ast_ty_to_ty(self, rs, ast_ty)
356 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
357 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
359 fn get_item_type_scheme(&self, span: Span, id: DefId)
360 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
362 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
363 Ok(type_scheme_of_def_id(self.ccx, id))
367 fn get_trait_def(&self, span: Span, id: DefId)
368 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
370 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
371 Ok(self.ccx.get_trait_def(id))
375 fn ensure_super_predicates(&self,
378 -> Result<(), ErrorReported>
380 debug!("ensure_super_predicates(trait_def_id={:?})",
383 self.ccx.ensure_super_predicates(span, trait_def_id)
387 fn get_type_parameter_bounds(&self,
389 node_id: ast::NodeId)
390 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
392 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
393 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
395 .filter_map(|p| p.to_opt_poly_trait_ref())
401 fn trait_defines_associated_type_named(&self,
403 assoc_name: ast::Name)
406 if trait_def_id.is_local() {
407 trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
409 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
410 trait_def.associated_type_names.contains(&assoc_name)
415 _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
416 _substs: Option<&mut Substs<'tcx>>,
417 _space: Option<ParamSpace>,
418 span: Span) -> Ty<'tcx> {
419 span_err!(self.tcx().sess, span, E0121,
420 "the type placeholder `_` is not allowed within types on item signatures");
424 fn projected_ty(&self,
426 trait_ref: ty::TraitRef<'tcx>,
427 item_name: ast::Name)
430 self.tcx().mk_projection(trait_ref, item_name)
434 /// Interface used to find the bounds on a type parameter from within
435 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
436 trait GetTypeParameterBounds<'tcx> {
437 fn get_type_parameter_bounds(&self,
438 astconv: &AstConv<'tcx>,
440 node_id: ast::NodeId)
441 -> Vec<ty::Predicate<'tcx>>;
444 /// Find bounds from both elements of the tuple.
445 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
446 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
448 fn get_type_parameter_bounds(&self,
449 astconv: &AstConv<'tcx>,
451 node_id: ast::NodeId)
452 -> Vec<ty::Predicate<'tcx>>
454 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
455 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
460 /// Empty set of bounds.
461 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
462 fn get_type_parameter_bounds(&self,
463 _astconv: &AstConv<'tcx>,
465 _node_id: ast::NodeId)
466 -> Vec<ty::Predicate<'tcx>>
472 /// Find bounds from the parsed and converted predicates. This is
473 /// used when converting methods, because by that time the predicates
474 /// from the trait/impl have been fully converted.
475 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
476 fn get_type_parameter_bounds(&self,
477 astconv: &AstConv<'tcx>,
479 node_id: ast::NodeId)
480 -> Vec<ty::Predicate<'tcx>>
482 let def = astconv.tcx().type_parameter_def(node_id);
486 .filter(|predicate| {
488 ty::Predicate::Trait(ref data) => {
489 data.skip_binder().self_ty().is_param(def.space, def.index)
491 ty::Predicate::TypeOutlives(ref data) => {
492 data.skip_binder().0.is_param(def.space, def.index)
494 ty::Predicate::Equate(..) |
495 ty::Predicate::RegionOutlives(..) |
496 ty::Predicate::WellFormed(..) |
497 ty::Predicate::ObjectSafe(..) |
498 ty::Predicate::Projection(..) => {
508 /// Find bounds from hir::Generics. This requires scanning through the
509 /// AST. We do this to avoid having to convert *all* the bounds, which
510 /// would create artificial cycles. Instead we can only convert the
511 /// bounds for those a type parameter `X` if `X::Foo` is used.
512 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
513 fn get_type_parameter_bounds(&self,
514 astconv: &AstConv<'tcx>,
516 node_id: ast::NodeId)
517 -> Vec<ty::Predicate<'tcx>>
519 // In the AST, bounds can derive from two places. Either
520 // written inline like `<T:Foo>` or in a where clause like
523 let def = astconv.tcx().type_parameter_def(node_id);
524 let ty = astconv.tcx().mk_param_from_def(&def);
529 .filter(|p| p.id == node_id)
530 .flat_map(|p| p.bounds.iter())
531 .flat_map(|b| predicates_from_bound(astconv, ty, b));
533 let from_where_clauses =
537 .filter_map(|wp| match *wp {
538 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
541 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
542 .flat_map(|bp| bp.bounds.iter())
543 .flat_map(|b| predicates_from_bound(astconv, ty, b));
545 from_ty_params.chain(from_where_clauses).collect()
549 /// Tests whether this is the AST for a reference to the type
550 /// parameter with id `param_id`. We use this so as to avoid running
551 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
552 /// conversion of the type to avoid inducing unnecessary cycles.
553 fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
555 param_id: ast::NodeId)
558 if let hir::TyPath(None, _) = ast_ty.node {
559 let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
560 match path_res.base_def {
561 def::DefSelfTy(Some(def_id), None) => {
562 path_res.depth == 0 && def_id.node == param_id
564 def::DefTyParam(_, _, def_id, _) => {
565 path_res.depth == 0 && def_id == DefId::local(param_id)
577 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
578 container: ImplOrTraitItemContainer,
579 sig: &hir::MethodSig,
582 vis: hir::Visibility,
583 untransformed_rcvr_ty: Ty<'tcx>,
584 rcvr_ty_generics: &ty::Generics<'tcx>,
585 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
586 let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
588 let ty_generic_predicates =
589 ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
591 let (fty, explicit_self_category) =
592 astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
593 sig, untransformed_rcvr_ty);
595 let def_id = DefId::local(id);
596 let ty_method = ty::Method::new(name,
598 ty_generic_predicates,
600 explicit_self_category,
605 let fty = ccx.tcx.mk_fn(Some(def_id),
606 ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
607 debug!("method {} (id {}) has type {:?}",
609 ccx.tcx.register_item_type(def_id, TypeScheme {
610 generics: ty_method.generics.clone(),
613 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
615 write_ty_to_tcx(ccx.tcx, id, fty);
617 debug!("writing method type: def_id={:?} mty={:?}",
620 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
621 ty::MethodTraitItem(Rc::new(ty_method)));
624 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
625 struct_generics: &ty::Generics<'tcx>,
626 struct_predicates: &ty::GenericPredicates<'tcx>,
627 v: &hir::StructField,
628 ty_f: ty::FieldDefMaster<'tcx>)
630 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
632 write_ty_to_tcx(ccx.tcx, v.node.id, tt);
634 /* add the field to the tcache */
635 ccx.tcx.register_item_type(DefId::local(v.node.id),
637 generics: struct_generics.clone(),
640 ccx.tcx.predicates.borrow_mut().insert(DefId::local(v.node.id),
641 struct_predicates.clone());
644 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
645 container: ImplOrTraitItemContainer,
648 vis: hir::Visibility,
652 ccx.tcx.predicates.borrow_mut().insert(DefId::local(id),
653 ty::GenericPredicates::empty());
655 write_ty_to_tcx(ccx.tcx, id, ty);
657 let associated_const = Rc::new(ty::AssociatedConst {
660 def_id: DefId::local(id),
661 container: container,
665 ccx.tcx.impl_or_trait_items.borrow_mut()
666 .insert(DefId::local(id), ty::ConstTraitItem(associated_const));
669 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
670 container: ImplOrTraitItemContainer,
673 vis: hir::Visibility,
674 ty: Option<Ty<'tcx>>)
676 let associated_type = Rc::new(ty::AssociatedType {
680 def_id: DefId::local(id),
683 ccx.tcx.impl_or_trait_items.borrow_mut()
684 .insert(DefId::local(id), ty::TypeTraitItem(associated_type));
687 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
688 container: ImplOrTraitItemContainer,
690 untransformed_rcvr_ty: Ty<'tcx>,
691 rcvr_ty_generics: &ty::Generics<'tcx>,
692 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
693 where I: Iterator<Item=(&'i hir::MethodSig, ast::NodeId, ast::Name, hir::Visibility, Span)>
695 debug!("convert_methods(untransformed_rcvr_ty={:?}, rcvr_ty_generics={:?}, \
696 rcvr_ty_predicates={:?})",
697 untransformed_rcvr_ty,
701 for (sig, id, name, vis, _span) in methods {
708 untransformed_rcvr_ty,
714 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
716 generics: &hir::Generics,
717 thing: &'static str) {
718 let mut warn = false;
720 for ty_param in generics.ty_params.iter() {
721 for bound in ty_param.bounds.iter() {
723 hir::TraitTyParamBound(..) => {
726 hir::RegionTyParamBound(..) => { }
732 // According to accepted RFC #XXX, we should
733 // eventually accept these, but it will not be
734 // part of this PR. Still, convert to warning to
735 // make bootstrapping easier.
736 span_warn!(ccx.tcx.sess, span, E0122,
737 "trait bounds are not (yet) enforced \
743 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
745 debug!("convert: item {} with id {}", it.name, it.id);
747 // These don't define types.
748 hir::ItemExternCrate(_) | hir::ItemUse(_) |
749 hir::ItemForeignMod(_) | hir::ItemMod(_) => {
751 hir::ItemEnum(ref enum_definition, _) => {
752 let (scheme, predicates) = convert_typed_item(ccx, it);
753 write_ty_to_tcx(tcx, it.id, scheme.ty);
754 convert_enum_variant_types(ccx,
755 tcx.lookup_adt_def_master(DefId::local(it.id)),
758 &enum_definition.variants);
760 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
762 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
767 tcx.record_trait_has_default_impl(trait_ref.def_id);
769 tcx.impl_trait_refs.borrow_mut().insert(DefId::local(it.id), Some(trait_ref));
776 // Create generics from the generics specified in the impl head.
777 debug!("convert: ast_generics={:?}", generics);
778 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
779 let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
781 debug!("convert: impl_bounds={:?}", ty_predicates);
783 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
784 write_ty_to_tcx(tcx, it.id, selfty);
786 tcx.register_item_type(DefId::local(it.id),
787 TypeScheme { generics: ty_generics.clone(),
789 tcx.predicates.borrow_mut().insert(DefId::local(it.id),
790 ty_predicates.clone());
791 if let &Some(ref ast_trait_ref) = opt_trait_ref {
792 tcx.impl_trait_refs.borrow_mut().insert(
794 Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
800 tcx.impl_trait_refs.borrow_mut().insert(DefId::local(it.id), None);
804 // If there is a trait reference, treat the methods as always public.
805 // This is to work around some incorrect behavior in privacy checking:
806 // when the method belongs to a trait, it should acquire the privacy
807 // from the trait, not the impl. Forcing the visibility to be public
808 // makes things sorta work.
809 let parent_visibility = if opt_trait_ref.is_some() {
815 // Convert all the associated consts.
816 // Also, check if there are any duplicate associated items
817 let mut seen_type_items = FnvHashSet();
818 let mut seen_value_items = FnvHashSet();
820 for impl_item in impl_items {
821 let seen_items = match impl_item.node {
822 hir::TypeImplItem(_) => &mut seen_type_items,
823 _ => &mut seen_value_items,
825 if !seen_items.insert(impl_item.name) {
826 let desc = match impl_item.node {
827 hir::ConstImplItem(_, _) => "associated constant",
828 hir::TypeImplItem(_) => "associated type",
829 hir::MethodImplItem(ref sig, _) =>
830 match sig.explicit_self.node {
831 hir::SelfStatic => "associated function",
836 span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
839 if let hir::ConstImplItem(ref ty, _) = impl_item.node {
840 let ty = ccx.icx(&ty_predicates)
841 .to_ty(&ExplicitRscope, &*ty);
842 tcx.register_item_type(DefId::local(impl_item.id),
844 generics: ty_generics.clone(),
847 convert_associated_const(ccx, ImplContainer(DefId::local(it.id)),
848 impl_item.name, impl_item.id,
849 impl_item.vis.inherit_from(parent_visibility),
850 ty, true /* has_value */);
854 // Convert all the associated types.
855 for impl_item in impl_items {
856 if let hir::TypeImplItem(ref ty) = impl_item.node {
857 if opt_trait_ref.is_none() {
858 span_err!(tcx.sess, impl_item.span, E0202,
859 "associated types are not allowed in inherent impls");
862 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
864 convert_associated_type(ccx, ImplContainer(DefId::local(it.id)),
865 impl_item.name, impl_item.id, impl_item.vis,
870 let methods = impl_items.iter().filter_map(|ii| {
871 if let hir::MethodImplItem(ref sig, _) = ii.node {
872 // if the method specifies a visibility, use that, otherwise
873 // inherit the visibility from the impl (so `foo` in `pub impl
874 // { fn foo(); }` is public, but private in `impl { fn
876 let method_vis = ii.vis.inherit_from(parent_visibility);
877 Some((sig, ii.id, ii.name, method_vis, ii.span))
883 ImplContainer(DefId::local(it.id)),
889 for impl_item in impl_items {
890 if let hir::MethodImplItem(ref sig, ref body) = impl_item.node {
891 let body_id = body.id;
892 check_method_self_type(ccx,
893 &BindingRscope::new(),
894 ccx.method_ty(impl_item.id),
901 enforce_impl_params_are_constrained(tcx,
906 hir::ItemTrait(_, _, _, ref trait_items) => {
907 let trait_def = trait_def_of_item(ccx, it);
908 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
909 ccx.ensure_super_predicates(it.span, DefId::local(it.id));
910 convert_trait_predicates(ccx, it);
911 let trait_predicates = tcx.lookup_predicates(DefId::local(it.id));
913 debug!("convert: trait_bounds={:?}", trait_predicates);
915 // Convert all the associated types.
916 for trait_item in trait_items {
917 match trait_item.node {
918 hir::ConstTraitItem(ref ty, ref default) => {
919 let ty = ccx.icx(&trait_predicates)
920 .to_ty(&ExplicitRscope, ty);
921 tcx.register_item_type(DefId::local(trait_item.id),
923 generics: trait_def.generics.clone(),
926 convert_associated_const(ccx, TraitContainer(DefId::local(it.id)),
927 trait_item.name, trait_item.id,
928 hir::Public, ty, default.is_some());
934 // Convert all the associated types.
935 for trait_item in trait_items {
936 match trait_item.node {
937 hir::TypeTraitItem(_, ref opt_ty) => {
938 let typ = opt_ty.as_ref().map({
939 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
942 convert_associated_type(ccx, TraitContainer(DefId::local(it.id)),
943 trait_item.name, trait_item.id, hir::Public,
950 let methods = trait_items.iter().filter_map(|ti| {
951 let sig = match ti.node {
952 hir::MethodTraitItem(ref sig, _) => sig,
955 Some((sig, ti.id, ti.name, hir::Inherited, ti.span))
958 // Run convert_methods on the trait methods.
960 TraitContainer(DefId::local(it.id)),
966 // Add an entry mapping
967 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
968 let def_id = DefId::local(trait_item.id);
969 match trait_item.node {
970 hir::ConstTraitItem(..) => {
971 ty::ConstTraitItemId(def_id)
973 hir::MethodTraitItem(..) => {
974 ty::MethodTraitItemId(def_id)
976 hir::TypeTraitItem(..) => {
977 ty::TypeTraitItemId(def_id)
981 tcx.trait_item_def_ids.borrow_mut().insert(DefId::local(it.id), trait_item_def_ids);
983 // This must be done after `collect_trait_methods` so that
984 // we have a method type stored for every method.
985 for trait_item in trait_items {
986 let sig = match trait_item.node {
987 hir::MethodTraitItem(ref sig, _) => sig,
990 check_method_self_type(ccx,
991 &BindingRscope::new(),
992 ccx.method_ty(trait_item.id),
998 hir::ItemStruct(ref struct_def, _) => {
999 let (scheme, predicates) = convert_typed_item(ccx, it);
1000 write_ty_to_tcx(tcx, it.id, scheme.ty);
1002 let variant = tcx.lookup_adt_def_master(DefId::local(it.id)).struct_variant();
1004 for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
1005 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1008 if let Some(ctor_id) = struct_def.ctor_id {
1009 convert_variant_ctor(tcx, ctor_id, variant, scheme, predicates);
1012 hir::ItemTy(_, ref generics) => {
1013 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
1014 let (scheme, _) = convert_typed_item(ccx, it);
1015 write_ty_to_tcx(tcx, it.id, scheme.ty);
1018 // This call populates the type cache with the converted type
1019 // of the item in passing. All we have to do here is to write
1020 // it into the node type table.
1021 let (scheme, _) = convert_typed_item(ccx, it);
1022 write_ty_to_tcx(tcx, it.id, scheme.ty);
1027 fn convert_variant_ctor<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
1028 ctor_id: ast::NodeId,
1029 variant: ty::VariantDef<'tcx>,
1030 scheme: ty::TypeScheme<'tcx>,
1031 predicates: ty::GenericPredicates<'tcx>) {
1032 let ctor_ty = match variant.kind() {
1033 VariantKind::Unit | VariantKind::Dict => scheme.ty,
1034 VariantKind::Tuple => {
1035 let inputs: Vec<_> =
1038 .map(|field| field.unsubst_ty())
1040 tcx.mk_ctor_fn(DefId::local(ctor_id),
1045 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
1046 tcx.predicates.borrow_mut().insert(DefId::local(ctor_id), predicates);
1047 tcx.register_item_type(DefId::local(ctor_id),
1049 generics: scheme.generics,
1054 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1055 def: ty::AdtDefMaster<'tcx>,
1056 scheme: ty::TypeScheme<'tcx>,
1057 predicates: ty::GenericPredicates<'tcx>,
1058 variants: &[P<hir::Variant>]) {
1060 let icx = ccx.icx(&predicates);
1062 // fill the field types
1063 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
1064 match variant.node.kind {
1065 hir::TupleVariantKind(ref args) => {
1066 let rs = ExplicitRscope;
1067 let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
1068 for (field, &ty) in ty_variant.fields.iter().zip(input_tys.iter()) {
1069 field.fulfill_ty(ty);
1073 hir::StructVariantKind(ref struct_def) => {
1074 for (f, ty_f) in struct_def.fields.iter().zip(ty_variant.fields.iter()) {
1075 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
1080 // Convert the ctor, if any. This also registers the variant as
1082 convert_variant_ctor(
1092 fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1096 def: &hir::StructDef) -> ty::VariantDefData<'tcx, 'tcx> {
1097 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
1098 let fields = def.fields.iter().map(|f| {
1099 let fid = DefId::local(f.node.id);
1101 hir::NamedField(name, vis) => {
1102 let dup_span = seen_fields.get(&name).cloned();
1103 if let Some(prev_span) = dup_span {
1104 span_err!(tcx.sess, f.span, E0124,
1105 "field `{}` is already declared",
1107 span_note!(tcx.sess, prev_span, "previously declared here");
1109 seen_fields.insert(name, f.span);
1112 ty::FieldDefData::new(fid, name, vis)
1114 hir::UnnamedField(vis) => {
1115 ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
1119 ty::VariantDefData {
1127 fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1129 def: &hir::StructDef)
1130 -> ty::AdtDefMaster<'tcx>
1133 let did = DefId::local(it.id);
1136 ty::AdtKind::Struct,
1137 vec![convert_struct_variant(tcx, did, it.name, 0, def)]
1141 fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>,
1144 -> ty::AdtDefMaster<'tcx>
1146 fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
1148 e: &hir::Expr) -> Option<ty::Disr> {
1149 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1151 let hint = UncheckedExprHint(repr_ty);
1152 match const_eval::eval_const_expr_partial(tcx, e, hint) {
1153 Ok(ConstVal::Int(val)) => Some(val as ty::Disr),
1154 Ok(ConstVal::Uint(val)) => Some(val as ty::Disr),
1156 let sign_desc = if repr_ty.is_signed() {
1161 span_err!(tcx.sess, e.span, E0079,
1162 "expected {} integer constant",
1167 span_err!(tcx.sess, err.span, E0080,
1168 "constant evaluation error: {}",
1175 fn report_discrim_overflow(tcx: &ty::ctxt,
1178 repr_type: attr::IntType,
1179 prev_val: ty::Disr) {
1180 let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
1181 let computed_value = repr_type.disr_string(computed_value);
1182 let prev_val = repr_type.disr_string(prev_val);
1183 let repr_type = repr_type.to_ty(tcx);
1184 span_err!(tcx.sess, variant_span, E0370,
1185 "enum discriminant overflowed on value after {}: {}; \
1186 set explicitly via {} = {} if that is desired outcome",
1187 prev_val, repr_type, variant_name, computed_value);
1190 fn next_disr(tcx: &ty::ctxt,
1192 repr_type: attr::IntType,
1193 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1194 if let Some(prev_disr_val) = prev_disr_val {
1195 let result = repr_type.disr_incr(prev_disr_val);
1196 if let None = result {
1197 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(),
1198 repr_type, prev_disr_val);
1202 Some(ty::INITIAL_DISCRIMINANT_VALUE)
1205 fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
1208 -> ty::VariantDefData<'tcx, 'tcx>
1210 let did = DefId::local(v.node.id);
1211 let name = v.node.name;
1213 hir::TupleVariantKind(ref va) => {
1214 ty::VariantDefData {
1218 fields: va.iter().map(|&hir::VariantArg { id, .. }| {
1219 ty::FieldDefData::new(
1221 special_idents::unnamed_field.name,
1222 hir::Visibility::Public
1227 hir::StructVariantKind(ref def) => {
1228 convert_struct_variant(tcx, did, name, disr, &def)
1232 let did = DefId::local(it.id);
1233 let repr_hints = tcx.lookup_repr_hints(did);
1234 let (repr_type, repr_type_ty) = tcx.enum_repr_type(repr_hints.get(0));
1235 let mut prev_disr = None;
1236 let variants = def.variants.iter().map(|v| {
1237 let disr = match v.node.disr_expr {
1238 Some(ref e) => evaluate_disr_expr(tcx, repr_type_ty, e),
1239 None => next_disr(tcx, v, repr_type, prev_disr)
1240 }.unwrap_or(repr_type.disr_wrap_incr(prev_disr));
1242 let v = convert_enum_variant(tcx, v, disr);
1243 prev_disr = Some(disr);
1246 tcx.intern_adt_def(DefId::local(it.id), ty::AdtKind::Enum, variants)
1249 /// Ensures that the super-predicates of the trait with def-id
1250 /// trait_def_id are converted and stored. This does NOT ensure that
1251 /// the transitive super-predicates are converted; that is the job of
1252 /// the `ensure_super_predicates()` method in the `AstConv` impl
1253 /// above. Returns a list of trait def-ids that must be ensured as
1254 /// well to guarantee that the transitive superpredicates are
1256 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1257 trait_def_id: DefId)
1262 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1264 if trait_def_id.krate != LOCAL_CRATE {
1265 // If this trait comes from an external crate, then all of the
1266 // supertraits it may depend on also must come from external
1267 // crates, and hence all of them already have their
1268 // super-predicates "converted" (and available from crate
1269 // meta-data), so there is no need to transitively test them.
1273 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1274 let superpredicates = superpredicates.unwrap_or_else(|| {
1275 let trait_node_id = trait_def_id.node;
1277 let item = match ccx.tcx.map.get(trait_node_id) {
1278 hir_map::NodeItem(item) => item,
1279 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1282 let (generics, bounds) = match item.node {
1283 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1284 _ => tcx.sess.span_bug(item.span,
1285 "ensure_super_predicates_step invoked on non-trait"),
1288 // In-scope when converting the superbounds for `Trait` are
1289 // that `Self:Trait` as well as any bounds that appear on the
1291 let trait_def = trait_def_of_item(ccx, item);
1292 let self_predicate = ty::GenericPredicates {
1293 predicates: VecPerParamSpace::new(vec![],
1294 vec![trait_def.trait_ref.to_predicate()],
1297 let scope = &(generics, &self_predicate);
1299 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1300 let self_param_ty = tcx.mk_self_type();
1301 let superbounds1 = compute_bounds(&ccx.icx(scope),
1307 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1309 // Convert any explicit superbounds in the where clause,
1310 // e.g. `trait Foo where Self : Bar`:
1311 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1313 // Combine the two lists to form the complete set of superbounds:
1314 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1315 let superpredicates = ty::GenericPredicates {
1316 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1318 debug!("superpredicates for trait {:?} = {:?}",
1319 DefId::local(item.id),
1322 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1327 let def_ids: Vec<_> = superpredicates.predicates
1329 .filter_map(|p| p.to_opt_poly_trait_ref())
1330 .map(|tr| tr.def_id())
1333 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1338 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1340 -> &'tcx ty::TraitDef<'tcx>
1342 let def_id = DefId::local(it.id);
1345 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1349 let (unsafety, generics, items) = match it.node {
1350 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1351 _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
1354 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1355 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1356 ccx.tcx.sess.span_err(
1358 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1359 which traits can use parenthetical notation");
1360 fileline_help!(ccx.tcx.sess, it.span,
1361 "add `#![feature(unboxed_closures)]` to \
1362 the crate attributes to use it");
1365 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1367 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1369 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1370 match trait_item.node {
1371 hir::TypeTraitItem(..) => Some(trait_item.name),
1376 let trait_ref = ty::TraitRef {
1381 let trait_def = ty::TraitDef {
1382 paren_sugar: paren_sugar,
1384 generics: ty_generics,
1385 trait_ref: trait_ref,
1386 associated_type_names: associated_type_names,
1387 nonblanket_impls: RefCell::new(FnvHashMap()),
1388 blanket_impls: RefCell::new(vec![]),
1389 flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS)
1392 return tcx.intern_trait_def(trait_def);
1394 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1395 generics: &hir::Generics)
1400 // Creates a no-op substitution for the trait's type parameters.
1405 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1406 param_id: def.lifetime.id,
1409 name: def.lifetime.name
1413 // Start with the generics in the type parameters...
1418 .map(|(i, def)| tcx.mk_param(TypeSpace,
1419 i as u32, def.name))
1422 // ...and also create the `Self` parameter.
1423 let self_ty = tcx.mk_self_type();
1425 Substs::new_trait(types, regions, self_ty)
1429 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1430 trait_node_id: ast::NodeId,
1431 assoc_name: ast::Name)
1434 let item = match ccx.tcx.map.get(trait_node_id) {
1435 hir_map::NodeItem(item) => item,
1436 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1439 let trait_items = match item.node {
1440 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1441 _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1444 trait_items.iter().any(|trait_item| {
1445 match trait_item.node {
1446 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1452 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1454 let trait_def = trait_def_of_item(ccx, it);
1456 let def_id = DefId::local(it.id);
1458 let (generics, items) = match it.node {
1459 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1463 &format!("trait_def_of_item invoked on {:?}", s));
1467 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1469 // `ty_generic_predicates` below will consider the bounds on the type
1470 // parameters (including `Self`) and the explicit where-clauses,
1471 // but to get the full set of predicates on a trait we need to add
1472 // in the supertrait bounds and anything declared on the
1473 // associated types.
1474 let mut base_predicates = super_predicates;
1476 // Add in a predicate that `Self:Trait` (where `Trait` is the
1477 // current trait). This is needed for builtin bounds.
1478 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1479 base_predicates.predicates.push(SelfSpace, self_predicate);
1481 // add in the explicit where-clauses
1482 let mut trait_predicates =
1483 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1485 let assoc_predicates = predicates_for_associated_types(ccx,
1488 trait_def.trait_ref,
1490 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1492 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1493 assert!(prev_predicates.is_none());
1497 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1498 ast_generics: &hir::Generics,
1499 trait_predicates: &ty::GenericPredicates<'tcx>,
1500 self_trait_ref: ty::TraitRef<'tcx>,
1501 trait_items: &[P<hir::TraitItem>])
1502 -> Vec<ty::Predicate<'tcx>>
1504 trait_items.iter().flat_map(|trait_item| {
1505 let bounds = match trait_item.node {
1506 hir::TypeTraitItem(ref bounds, _) => bounds,
1508 return vec!().into_iter();
1512 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1515 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1518 SizedByDefault::Yes,
1521 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1526 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1528 -> ty::TypeScheme<'tcx>
1530 if def_id.krate != LOCAL_CRATE {
1531 return ccx.tcx.lookup_item_type(def_id);
1534 match ccx.tcx.map.find(def_id.node) {
1535 Some(hir_map::NodeItem(item)) => {
1536 type_scheme_of_item(ccx, &*item)
1538 Some(hir_map::NodeForeignItem(foreign_item)) => {
1539 let abi = ccx.tcx.map.get_foreign_abi(def_id.node);
1540 type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
1543 ccx.tcx.sess.bug(&format!("unexpected sort of node \
1544 in get_item_type_scheme(): {:?}",
1550 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1552 -> ty::TypeScheme<'tcx>
1554 memoized(&ccx.tcx.tcache,
1555 DefId::local(it.id),
1556 |_| compute_type_scheme_of_item(ccx, it))
1559 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1561 -> ty::TypeScheme<'tcx>
1565 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1566 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
1567 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1569 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1570 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1571 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
1572 let ty = tcx.mk_fn(Some(DefId::local(it.id)), tcx.mk_bare_fn(tofd));
1573 ty::TypeScheme { ty: ty, generics: ty_generics }
1575 hir::ItemTy(ref t, ref generics) => {
1576 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1577 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
1578 ty::TypeScheme { ty: ty, generics: ty_generics }
1580 hir::ItemEnum(ref ei, ref generics) => {
1581 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1582 let substs = mk_item_substs(ccx, &ty_generics);
1583 let def = convert_enum_def(tcx, it, ei);
1584 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1585 ty::TypeScheme { ty: t, generics: ty_generics }
1587 hir::ItemStruct(ref si, ref generics) => {
1588 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1589 let substs = mk_item_substs(ccx, &ty_generics);
1590 let def = convert_struct_def(tcx, it, si);
1591 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1592 ty::TypeScheme { ty: t, generics: ty_generics }
1594 hir::ItemDefaultImpl(..) |
1595 hir::ItemTrait(..) |
1598 hir::ItemForeignMod(..) |
1599 hir::ItemExternCrate(..) |
1600 hir::ItemUse(..) => {
1603 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1609 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1611 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1615 let tag = type_scheme_of_item(ccx, it);
1616 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1617 let predicates = match it.node {
1618 hir::ItemStatic(..) | hir::ItemConst(..) => {
1619 ty::GenericPredicates::empty()
1621 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1622 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1624 hir::ItemTy(_, ref generics) => {
1625 ty_generic_predicates_for_type_or_impl(ccx, generics)
1627 hir::ItemEnum(_, ref generics) => {
1628 ty_generic_predicates_for_type_or_impl(ccx, generics)
1630 hir::ItemStruct(_, ref generics) => {
1631 ty_generic_predicates_for_type_or_impl(ccx, generics)
1633 hir::ItemDefaultImpl(..) |
1634 hir::ItemTrait(..) |
1635 hir::ItemExternCrate(..) |
1639 hir::ItemForeignMod(..) => {
1642 &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
1647 let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id),
1648 predicates.clone());
1649 assert!(prev_predicates.is_none());
1652 if tcx.has_attr(DefId::local(it.id), "rustc_object_lifetime_default") {
1653 let object_lifetime_default_reprs: String =
1654 scheme.generics.types.iter()
1655 .map(|t| match t.object_lifetime_default {
1656 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1657 d => format!("{:?}", d),
1659 .collect::<Vec<String>>()
1662 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1665 return (scheme, predicates);
1668 fn type_scheme_of_foreign_item<'a, 'tcx>(
1669 ccx: &CrateCtxt<'a, 'tcx>,
1670 it: &hir::ForeignItem,
1672 -> ty::TypeScheme<'tcx>
1674 memoized(&ccx.tcx.tcache,
1675 DefId::local(it.id),
1676 |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
1679 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1680 ccx: &CrateCtxt<'a, 'tcx>,
1681 it: &hir::ForeignItem,
1683 -> ty::TypeScheme<'tcx>
1686 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1687 compute_type_scheme_of_foreign_fn_decl(ccx, fn_decl, generics, abi)
1689 hir::ForeignItemStatic(ref t, _) => {
1691 generics: ty::Generics::empty(),
1692 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1698 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1699 it: &hir::ForeignItem)
1701 // For reasons I cannot fully articulate, I do so hate the AST
1702 // map, and I regard each time that I use it as a personal and
1703 // moral failing, but at the moment it seems like the only
1704 // convenient way to extract the ABI. - ndm
1706 let abi = tcx.map.get_foreign_abi(it.id);
1708 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1709 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1711 let predicates = match it.node {
1712 hir::ForeignItemFn(_, ref generics) => {
1713 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1715 hir::ForeignItemStatic(..) => {
1716 ty::GenericPredicates::empty()
1720 let prev_predicates = tcx.predicates.borrow_mut().insert(DefId::local(it.id), predicates);
1721 assert!(prev_predicates.is_none());
1724 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1725 generics: &hir::Generics)
1726 -> ty::Generics<'tcx> {
1727 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1730 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1731 generics: &hir::Generics)
1732 -> ty::GenericPredicates<'tcx>
1734 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1737 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1738 trait_id: ast::NodeId,
1739 substs: &'tcx Substs<'tcx>,
1740 ast_generics: &hir::Generics)
1741 -> ty::Generics<'tcx>
1743 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1744 DefId::local(trait_id), substs);
1746 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1748 // Add in the self type parameter.
1750 // Something of a hack: use the node id for the trait, also as
1751 // the node id for the Self type parameter.
1752 let param_id = trait_id;
1754 let parent = ccx.tcx.map.get_parent(param_id);
1756 let def = ty::TypeParameterDef {
1759 name: special_idents::type_self.name,
1760 def_id: DefId::local(param_id),
1761 default_def_id: DefId::local(parent),
1763 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1766 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1768 generics.types.push(SelfSpace, def);
1773 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1774 generics: &hir::Generics,
1775 base_generics: &ty::Generics<'tcx>)
1776 -> ty::Generics<'tcx>
1778 ty_generics(ccx, FnSpace, generics, base_generics)
1781 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1782 generics: &hir::Generics,
1783 base_predicates: &ty::GenericPredicates<'tcx>)
1784 -> ty::GenericPredicates<'tcx>
1786 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1789 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1790 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1791 bounds: &mut ty::BuiltinBounds,
1792 ast_bounds: &[hir::TyParamBound],
1795 let tcx = astconv.tcx();
1797 // Try to find an unbound in bounds.
1798 let mut unbound = None;
1799 for ab in ast_bounds {
1800 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1801 if unbound.is_none() {
1802 assert!(ptr.bound_lifetimes.is_empty());
1803 unbound = Some(ptr.trait_ref.clone());
1805 span_err!(tcx.sess, span, E0203,
1806 "type parameter has more than one relaxed default \
1807 bound, only one is supported");
1812 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1815 // FIXME(#8559) currently requires the unbound to be built-in.
1816 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1818 Ok(kind_id) if trait_def_id != kind_id => {
1819 tcx.sess.span_warn(span,
1820 "default bound relaxed for a type parameter, but \
1821 this does nothing because the given bound is not \
1822 a default. Only `?Sized` is supported");
1823 tcx.try_add_builtin_trait(kind_id, bounds);
1828 _ if kind_id.is_ok() => {
1829 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1831 // No lang item for Sized, so we can't add it as a bound.
1836 /// Returns the early-bound lifetimes declared in this generics
1837 /// listing. For anything other than fns/methods, this is just all
1838 /// the lifetimes that are declared. For fns or methods, we have to
1839 /// screen out those that do not appear in any where-clauses etc using
1840 /// `resolve_lifetime::early_bound_lifetimes`.
1841 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1842 ast_generics: &hir::Generics)
1843 -> Vec<hir::LifetimeDef>
1846 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1847 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1851 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1853 ast_generics: &hir::Generics,
1854 base_predicates: &ty::GenericPredicates<'tcx>)
1855 -> ty::GenericPredicates<'tcx>
1858 let mut result = base_predicates.clone();
1860 // Collect the predicates that were written inline by the user on each
1861 // type parameter (e.g., `<T:Foo>`).
1862 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1863 let index = index as u32;
1864 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1865 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1868 SizedByDefault::Yes,
1870 let predicates = bounds.predicates(ccx.tcx, param_ty);
1871 result.predicates.extend(space, predicates.into_iter());
1874 // Collect the region predicates that were declared inline as
1875 // well. In the case of parameters declared on a fn or method, we
1876 // have to be careful to only iterate over early-bound regions.
1877 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1878 for (index, param) in early_lifetimes.iter().enumerate() {
1879 let index = index as u32;
1881 ty::ReEarlyBound(ty::EarlyBoundRegion {
1882 param_id: param.lifetime.id,
1885 name: param.lifetime.name
1887 for bound in ¶m.bounds {
1888 let bound_region = ast_region_to_region(ccx.tcx, bound);
1889 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1890 result.predicates.push(space, outlives.to_predicate());
1894 // Add in the bounds that appear in the where-clause
1895 let where_clause = &ast_generics.where_clause;
1896 for predicate in &where_clause.predicates {
1898 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1899 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1901 &*bound_pred.bounded_ty);
1903 for bound in bound_pred.bounds.iter() {
1905 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1906 let mut projections = Vec::new();
1909 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1914 result.predicates.push(space, trait_ref.to_predicate());
1916 for projection in &projections {
1917 result.predicates.push(space, projection.to_predicate());
1921 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1922 let region = ast_region_to_region(tcx, lifetime);
1923 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1924 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1930 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1931 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1932 for bound in ®ion_pred.bounds {
1933 let r2 = ast_region_to_region(tcx, bound);
1934 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1935 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1939 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1941 tcx.sess.span_bug(eq_pred.span,
1942 "Equality constraints are not yet \
1943 implemented (#20041)")
1951 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1953 ast_generics: &hir::Generics,
1954 base_generics: &ty::Generics<'tcx>)
1955 -> ty::Generics<'tcx>
1958 let mut result = base_generics.clone();
1960 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1961 for (i, l) in early_lifetimes.iter().enumerate() {
1962 let bounds = l.bounds.iter()
1963 .map(|l| ast_region_to_region(tcx, l))
1965 let def = ty::RegionParameterDef { name: l.lifetime.name,
1968 def_id: DefId::local(l.lifetime.id),
1970 result.regions.push(space, def);
1973 assert!(result.types.is_empty_in(space));
1975 // Now create the real type parameters.
1976 for i in 0..ast_generics.ty_params.len() {
1977 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1978 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1979 result.types.push(space, def);
1985 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1991 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1993 for leaf_ty in ty.walk() {
1994 if let ty::TyParam(p) = leaf_ty.sty {
1995 if p.space == space && p.idx >= index {
1996 span_err!(ccx.tcx.sess, path.span, E0128,
1997 "type parameters with a default cannot use \
1998 forward declared identifiers");
2000 return ccx.tcx.types.err
2008 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2009 ast_generics: &hir::Generics,
2012 -> ty::TypeParameterDef<'tcx>
2014 let param = &ast_generics.ty_params[index as usize];
2017 match tcx.ty_param_defs.borrow().get(¶m.id) {
2018 Some(d) => { return d.clone(); }
2022 let default = param.default.as_ref().map(
2023 |def| convert_default_type_parameter(ccx, def, space, index)
2026 let object_lifetime_default =
2027 compute_object_lifetime_default(ccx, param.id,
2028 ¶m.bounds, &ast_generics.where_clause);
2030 let parent = tcx.map.get_parent(param.id);
2032 let def = ty::TypeParameterDef {
2036 def_id: DefId::local(param.id),
2037 default_def_id: DefId::local(parent),
2039 object_lifetime_default: object_lifetime_default,
2042 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
2047 /// Scan the bounds and where-clauses on a parameter to extract bounds
2048 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
2049 /// This runs as part of computing the minimal type scheme, so we
2050 /// intentionally avoid just asking astconv to convert all the where
2051 /// clauses into a `ty::Predicate`. This is because that could induce
2052 /// artificial cycles.
2053 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2054 param_id: ast::NodeId,
2055 param_bounds: &[hir::TyParamBound],
2056 where_clause: &hir::WhereClause)
2057 -> ty::ObjectLifetimeDefault
2059 let inline_bounds = from_bounds(ccx, param_bounds);
2060 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
2061 let all_bounds: HashSet<_> = inline_bounds.into_iter()
2062 .chain(where_bounds)
2064 return if all_bounds.len() > 1 {
2065 ty::ObjectLifetimeDefault::Ambiguous
2066 } else if all_bounds.len() == 0 {
2067 ty::ObjectLifetimeDefault::BaseDefault
2069 ty::ObjectLifetimeDefault::Specific(
2070 all_bounds.into_iter().next().unwrap())
2073 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2074 bounds: &[hir::TyParamBound])
2078 .filter_map(|bound| {
2080 hir::TraitTyParamBound(..) =>
2082 hir::RegionTyParamBound(ref lifetime) =>
2083 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
2089 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
2090 param_id: ast::NodeId,
2091 predicates: &[hir::WherePredicate])
2095 .flat_map(|predicate| {
2097 hir::WherePredicate::BoundPredicate(ref data) => {
2098 if data.bound_lifetimes.is_empty() &&
2099 is_param(ccx.tcx, &data.bounded_ty, param_id)
2101 from_bounds(ccx, &data.bounds).into_iter()
2103 Vec::new().into_iter()
2106 hir::WherePredicate::RegionPredicate(..) |
2107 hir::WherePredicate::EqPredicate(..) => {
2108 Vec::new().into_iter()
2116 enum SizedByDefault { Yes, No, }
2118 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2119 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2120 /// built-in trait (formerly known as kind): Send.
2121 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2122 param_ty: ty::Ty<'tcx>,
2123 ast_bounds: &[hir::TyParamBound],
2124 sized_by_default: SizedByDefault,
2126 -> astconv::Bounds<'tcx>
2129 conv_param_bounds(astconv,
2134 if let SizedByDefault::Yes = sized_by_default {
2135 add_unsized_bound(astconv,
2136 &mut bounds.builtin_bounds,
2141 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2146 /// Converts a specific TyParamBound from the AST into a set of
2147 /// predicates that apply to the self-type. A vector is returned
2148 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2149 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2150 /// and `<T as Bar>::X == i32`).
2151 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2153 bound: &hir::TyParamBound)
2154 -> Vec<ty::Predicate<'tcx>>
2157 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2158 let mut projections = Vec::new();
2159 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2160 projections.into_iter()
2161 .map(|p| p.to_predicate())
2162 .chain(Some(pred.to_predicate()))
2165 hir::RegionTyParamBound(ref lifetime) => {
2166 let region = ast_region_to_region(astconv.tcx(), lifetime);
2167 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2168 vec![ty::Predicate::TypeOutlives(pred)]
2170 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2176 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2178 trait_ref: &hir::PolyTraitRef,
2179 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2180 -> ty::PolyTraitRef<'tcx>
2182 astconv::instantiate_poly_trait_ref(astconv,
2189 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2191 param_ty: ty::Ty<'tcx>,
2192 ast_bounds: &[hir::TyParamBound])
2193 -> astconv::Bounds<'tcx>
2195 let tcx = astconv.tcx();
2196 let astconv::PartitionedBounds {
2200 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2202 let mut projection_bounds = Vec::new();
2204 let trait_bounds: Vec<ty::PolyTraitRef> =
2206 .map(|bound| conv_poly_trait_ref(astconv,
2209 &mut projection_bounds))
2212 let region_bounds: Vec<ty::Region> =
2213 region_bounds.into_iter()
2214 .map(|r| ast_region_to_region(tcx, r))
2218 region_bounds: region_bounds,
2219 builtin_bounds: builtin_bounds,
2220 trait_bounds: trait_bounds,
2221 projection_bounds: projection_bounds,
2225 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2226 ccx: &CrateCtxt<'a, 'tcx>,
2228 ast_generics: &hir::Generics,
2230 -> ty::TypeScheme<'tcx>
2232 for i in &decl.inputs {
2233 match (*i).pat.node {
2234 hir::PatIdent(_, _, _) => (),
2235 hir::PatWild(hir::PatWildSingle) => (),
2237 span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
2238 "patterns aren't allowed in foreign function declarations");
2243 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2245 let rb = BindingRscope::new();
2246 let input_tys = decl.inputs
2248 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2251 let output = match decl.output {
2252 hir::Return(ref ty) =>
2253 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
2254 hir::DefaultReturn(..) =>
2255 ty::FnConverging(ccx.tcx.mk_nil()),
2256 hir::NoReturn(..) =>
2260 let t_fn = ccx.tcx.mk_fn(None,
2261 ccx.tcx.mk_bare_fn(ty::BareFnTy {
2263 unsafety: hir::Unsafety::Unsafe,
2264 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2266 variadic: decl.variadic}),
2270 generics: ty_generics,
2275 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2276 ty_generics: &ty::Generics<'tcx>)
2280 ty_generics.types.map(
2281 |def| ccx.tcx.mk_param_from_def(def));
2284 ty_generics.regions.map(
2285 |def| def.to_early_bound_region());
2287 Substs::new(types, regions)
2290 /// Verifies that the explicit self type of a method matches the impl
2291 /// or trait. This is a bit weird but basically because right now we
2292 /// don't handle the general case, but instead map it to one of
2293 /// several pre-defined options using various heuristics, this method
2294 /// comes back to check after the fact that explicit type the user
2295 /// wrote actually matches what the pre-defined option said.
2296 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
2297 ccx: &CrateCtxt<'a, 'tcx>,
2299 method_type: Rc<ty::Method<'tcx>>,
2300 required_type: Ty<'tcx>,
2301 explicit_self: &hir::ExplicitSelf,
2302 body_id: ast::NodeId)
2305 if let hir::SelfExplicit(ref ast_type, _) = explicit_self.node {
2306 let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
2307 let base_type = match typ.sty {
2308 ty::TyRef(_, tm) => tm.ty,
2309 ty::TyBox(typ) => typ,
2313 let body_scope = tcx.region_maps.item_extent(body_id);
2315 // "Required type" comes from the trait definition. It may
2316 // contain late-bound regions from the method, but not the
2317 // trait (since traits only have early-bound region
2319 assert!(!base_type.has_regions_escaping_depth(1));
2320 let required_type_free =
2321 liberate_early_bound_regions(
2323 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
2325 // The "base type" comes from the impl. It too may have late-bound
2326 // regions from the method.
2327 assert!(!base_type.has_regions_escaping_depth(1));
2328 let base_type_free =
2329 liberate_early_bound_regions(
2331 &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
2333 debug!("required_type={:?} required_type_free={:?} \
2334 base_type={:?} base_type_free={:?}",
2340 let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
2341 drop(::require_same_types(tcx,
2348 format!("mismatched self type: expected `{}`",
2352 // We could conceviably add more free-region relations here,
2353 // but since this code is just concerned with checking that
2354 // the `&Self` types etc match up, it's not really necessary.
2355 // It would just allow people to be more approximate in some
2356 // cases. In any case, we can do it later as we feel the need;
2357 // I'd like this function to go away eventually.
2358 let free_regions = FreeRegionMap::new();
2360 infcx.resolve_regions_and_report_errors(&free_regions, body_id);
2363 fn liberate_early_bound_regions<'tcx,T>(
2364 tcx: &ty::ctxt<'tcx>,
2365 scope: region::CodeExtent,
2368 where T : TypeFoldable<'tcx>
2371 * Convert early-bound regions into free regions; normally this is done by
2372 * applying the `free_substs` from the `ParameterEnvironment`, but this particular
2373 * method-self-type check is kind of hacky and done very early in the process,
2374 * before we really have a `ParameterEnvironment` to check.
2377 tcx.fold_regions(value, &mut false, |region, _| {
2379 ty::ReEarlyBound(data) => {
2380 let def_id = DefId::local(data.param_id);
2381 ty::ReFree(ty::FreeRegion { scope: scope,
2382 bound_region: ty::BrNamed(def_id, data.name) })
2390 /// Checks that all the type parameters on an impl
2391 fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
2392 ast_generics: &hir::Generics,
2394 impl_items: &[P<hir::ImplItem>])
2396 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2397 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2398 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2400 // The trait reference is an input, so find all type parameters
2401 // reachable from there, to start (if this is an inherent impl,
2402 // then just examine the self type).
2403 let mut input_parameters: HashSet<_> =
2404 ctp::parameters_for_type(impl_scheme.ty).into_iter().collect();
2405 if let Some(ref trait_ref) = impl_trait_ref {
2406 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref));
2409 ctp::identify_constrained_type_params(tcx,
2410 impl_predicates.predicates.as_slice(),
2412 &mut input_parameters);
2414 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2415 let param_ty = ty::ParamTy { space: TypeSpace,
2417 name: ty_param.name };
2418 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2419 report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
2423 // Every lifetime used in an associated type must be constrained.
2425 let lifetimes_in_associated_types: HashSet<_> =
2427 .map(|item| tcx.impl_or_trait_item(DefId::local(item.id)))
2428 .filter_map(|item| match item {
2429 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2430 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2432 .flat_map(|ty| ctp::parameters_for_type(ty))
2433 .filter_map(|p| match p {
2434 ctp::Parameter::Type(_) => None,
2435 ctp::Parameter::Region(r) => Some(r),
2439 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2440 let region = ty::EarlyBoundRegion { param_id: lifetime_def.lifetime.id,
2442 index: index as u32,
2443 name: lifetime_def.lifetime.name };
2445 lifetimes_in_associated_types.contains(®ion) && // (*)
2446 !input_parameters.contains(&ctp::Parameter::Region(region))
2448 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2449 "lifetime", ®ion.name.to_string());
2453 // (*) This is a horrible concession to reality. I think it'd be
2454 // better to just ban unconstrianed lifetimes outright, but in
2455 // practice people do non-hygenic macros like:
2458 // macro_rules! __impl_slice_eq1 {
2459 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2460 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2467 // In a concession to backwards compatbility, we continue to
2468 // permit those, so long as the lifetimes aren't used in
2469 // associated types. I believe this is sound, because lifetimes
2470 // used elsewhere are not projected back out.
2473 fn report_unused_parameter(tcx: &ty::ctxt,
2478 span_err!(tcx.sess, span, E0207,
2479 "the {} parameter `{}` is not constrained by the \
2480 impl trait, self type, or predicates",