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.types`
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 a pair of `Generics` and `Ty`. Type
26 parameters themselves are represented as `ty_param()` instances.
28 The phasing of type conversion is somewhat complicated. There is no
29 clear set of phases we can enforce (e.g., converting traits first,
30 then types, or something like that) because the user can introduce
31 arbitrary interdependencies. So instead we generally convert things
32 lazilly and on demand, and include logic that checks for cycles.
33 Demand is driven by calls to `AstConv::get_item_type_scheme` or
34 `AstConv::lookup_trait_def`.
36 Currently, we "convert" types and traits in two phases (note that
37 conversion only affects the types of items / enum variants / methods;
38 it does not e.g. compute the types of individual expressions):
41 1. Trait/Type definitions
43 Conversion itself is done by simply walking each of the items in turn
44 and invoking an appropriate function (e.g., `trait_def_of_item` or
45 `convert_item`). However, it is possible that while converting an
46 item, we may need to compute the *type scheme* or *trait definition*
49 There are some shortcomings in this design:
51 - Before walking the set of supertraits for a given trait, you must
52 call `ensure_super_predicates` on that trait def-id. Otherwise,
53 `item_super_predicates` will result in ICEs.
54 - Because the item generics include defaults, cycles through type
55 parameter defaults are illegal even if those defaults are never
56 employed. This is not necessarily a bug.
60 use astconv::{AstConv, ast_region_to_region, Bounds, PartitionedBounds, partition_bounds};
62 use constrained_type_params as ctp;
63 use middle::lang_items::SizedTraitLangItem;
64 use middle::const_val::ConstVal;
65 use rustc_const_eval::EvalHint::UncheckedExprHint;
66 use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
67 use rustc::ty::subst::Substs;
68 use rustc::ty::{ToPredicate, ImplContainer, AssociatedItemContainer, TraitContainer};
69 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
70 use rustc::ty::util::IntTypeExt;
72 use rustc::dep_graph::DepNode;
73 use util::common::{ErrorReported, MemoizationMap};
74 use util::nodemap::{NodeMap, FxHashMap, FxHashSet};
77 use rustc_const_math::ConstInt;
79 use std::cell::RefCell;
81 use syntax::{abi, ast, attr};
82 use syntax::symbol::{Symbol, keywords};
85 use rustc::hir::{self, map as hir_map, print as pprust};
86 use rustc::hir::intravisit::{self, Visitor};
87 use rustc::hir::def::{Def, CtorKind};
88 use rustc::hir::def_id::DefId;
90 ///////////////////////////////////////////////////////////////////////////
93 pub fn collect_item_types(ccx: &CrateCtxt) {
94 let mut visitor = CollectItemTypesVisitor { ccx: ccx };
95 ccx.tcx.visit_all_item_likes_in_krate(DepNode::CollectItem, &mut visitor.as_deep_visitor());
98 ///////////////////////////////////////////////////////////////////////////
100 /// Context specific to some particular item. This is what implements
101 /// AstConv. It has information about the predicates that are defined
102 /// on the trait. Unfortunately, this predicate information is
103 /// available in various different forms at various points in the
104 /// process. So we can't just store a pointer to e.g. the AST or the
105 /// parsed ty form, we have to be more flexible. To this end, the
106 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
107 /// that it uses to satisfy `get_type_parameter_bounds` requests.
108 /// This object might draw the information from the AST
109 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
110 /// or both (a tuple).
111 struct ItemCtxt<'a,'tcx:'a> {
112 ccx: &'a CrateCtxt<'a,'tcx>,
113 param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
116 #[derive(Copy, Clone, PartialEq, Eq)]
117 pub enum AstConvRequest {
119 GetItemTypeScheme(DefId),
121 EnsureSuperPredicates(DefId),
122 GetTypeParameterBounds(ast::NodeId),
125 ///////////////////////////////////////////////////////////////////////////
127 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
128 ccx: &'a CrateCtxt<'a, 'tcx>
131 impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
132 fn visit_item(&mut self, item: &hir::Item) {
133 convert_item(self.ccx, item);
134 intravisit::walk_item(self, item);
137 fn visit_expr(&mut self, expr: &hir::Expr) {
138 if let hir::ExprClosure(..) = expr.node {
139 convert_closure(self.ccx, expr.id);
141 intravisit::walk_expr(self, expr);
144 fn visit_ty(&mut self, ty: &hir::Ty) {
145 if let hir::TyImplTrait(..) = ty.node {
146 let def_id = self.ccx.tcx.map.local_def_id(ty.id);
147 generics_of_def_id(self.ccx, def_id);
149 intravisit::walk_ty(self, ty);
152 fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
153 convert_impl_item(self.ccx, impl_item);
154 intravisit::walk_impl_item(self, impl_item);
158 ///////////////////////////////////////////////////////////////////////////
159 // Utility types and common code for the above passes.
161 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
162 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
165 param_bounds: param_bounds,
169 fn cycle_check<F,R>(&self,
171 request: AstConvRequest,
173 -> Result<R,ErrorReported>
174 where F: FnOnce() -> Result<R,ErrorReported>
177 let mut stack = self.stack.borrow_mut();
178 if let Some((i, _)) = stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
179 let cycle = &stack[i..];
180 self.report_cycle(span, cycle);
181 return Err(ErrorReported);
188 self.stack.borrow_mut().pop();
192 fn report_cycle(&self,
194 cycle: &[AstConvRequest])
196 assert!(!cycle.is_empty());
199 let mut err = struct_span_err!(tcx.sess, span, E0391,
200 "unsupported cyclic reference between types/traits detected");
201 err.span_label(span, &format!("cyclic reference"));
204 AstConvRequest::GetGenerics(def_id) |
205 AstConvRequest::GetItemTypeScheme(def_id) |
206 AstConvRequest::GetTraitDef(def_id) => {
208 &format!("the cycle begins when processing `{}`...",
209 tcx.item_path_str(def_id)));
211 AstConvRequest::EnsureSuperPredicates(def_id) => {
213 &format!("the cycle begins when computing the supertraits of `{}`...",
214 tcx.item_path_str(def_id)));
216 AstConvRequest::GetTypeParameterBounds(id) => {
217 let def = tcx.type_parameter_def(id);
219 &format!("the cycle begins when computing the bounds \
220 for type parameter `{}`...",
225 for request in &cycle[1..] {
227 AstConvRequest::GetGenerics(def_id) |
228 AstConvRequest::GetItemTypeScheme(def_id) |
229 AstConvRequest::GetTraitDef(def_id) => {
231 &format!("...which then requires processing `{}`...",
232 tcx.item_path_str(def_id)));
234 AstConvRequest::EnsureSuperPredicates(def_id) => {
236 &format!("...which then requires computing the supertraits of `{}`...",
237 tcx.item_path_str(def_id)));
239 AstConvRequest::GetTypeParameterBounds(id) => {
240 let def = tcx.type_parameter_def(id);
242 &format!("...which then requires computing the bounds \
243 for type parameter `{}`...",
250 AstConvRequest::GetGenerics(def_id) |
251 AstConvRequest::GetItemTypeScheme(def_id) |
252 AstConvRequest::GetTraitDef(def_id) => {
254 &format!("...which then again requires processing `{}`, completing the cycle.",
255 tcx.item_path_str(def_id)));
257 AstConvRequest::EnsureSuperPredicates(def_id) => {
259 &format!("...which then again requires computing the supertraits of `{}`, \
260 completing the cycle.",
261 tcx.item_path_str(def_id)));
263 AstConvRequest::GetTypeParameterBounds(id) => {
264 let def = tcx.type_parameter_def(id);
266 &format!("...which then again requires computing the bounds \
267 for type parameter `{}`, completing the cycle.",
274 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
275 fn get_trait_def(&self, trait_id: DefId)
276 -> &'tcx ty::TraitDef<'tcx>
280 if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
281 let item = match tcx.map.get(trait_id) {
282 hir_map::NodeItem(item) => item,
283 _ => bug!("get_trait_def({:?}): not an item", trait_id)
286 trait_def_of_item(self, &item)
288 tcx.lookup_trait_def(trait_id)
292 /// Ensure that the (transitive) super predicates for
293 /// `trait_def_id` are available. This will report a cycle error
294 /// if a trait `X` (transitively) extends itself in some form.
295 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
296 -> Result<(), ErrorReported>
298 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
299 let def_ids = ensure_super_predicates_step(self, trait_def_id);
301 for def_id in def_ids {
302 self.ensure_super_predicates(span, def_id)?;
310 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
311 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
312 AstConv::ast_ty_to_ty(self, rs, ast_ty)
316 impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
317 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.ccx.tcx }
319 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
320 &self.ccx.ast_ty_to_ty_cache
323 fn get_generics(&self, span: Span, id: DefId)
324 -> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
326 self.ccx.cycle_check(span, AstConvRequest::GetGenerics(id), || {
327 Ok(generics_of_def_id(self.ccx, id))
331 fn get_item_type(&self, span: Span, id: DefId) -> Result<Ty<'tcx>, ErrorReported> {
332 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
333 Ok(type_of_def_id(self.ccx, id))
337 fn get_trait_def(&self, span: Span, id: DefId)
338 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
340 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
341 Ok(self.ccx.get_trait_def(id))
345 fn ensure_super_predicates(&self,
348 -> Result<(), ErrorReported>
350 debug!("ensure_super_predicates(trait_def_id={:?})",
353 self.ccx.ensure_super_predicates(span, trait_def_id)
357 fn get_type_parameter_bounds(&self,
359 node_id: ast::NodeId)
360 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
362 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
363 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
365 .filter_map(|p| p.to_opt_poly_trait_ref())
371 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
375 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
380 "the type placeholder `_` is not allowed within types on item signatures"
381 ).span_label(span, &format!("not allowed in type signatures"))
386 fn projected_ty_from_poly_trait_ref(&self,
388 poly_trait_ref: ty::PolyTraitRef<'tcx>,
389 item_name: ast::Name)
392 if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
393 self.projected_ty(span, trait_ref, item_name)
395 // no late-bound regions, we can just ignore the binder
396 span_err!(self.tcx().sess, span, E0212,
397 "cannot extract an associated type from a higher-ranked trait bound \
403 fn projected_ty(&self,
405 trait_ref: ty::TraitRef<'tcx>,
406 item_name: ast::Name)
409 self.tcx().mk_projection(trait_ref, item_name)
412 fn set_tainted_by_errors(&self) {
413 // no obvious place to track this, just let it go
417 /// Interface used to find the bounds on a type parameter from within
418 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
419 trait GetTypeParameterBounds<'tcx> {
420 fn get_type_parameter_bounds(&self,
421 astconv: &AstConv<'tcx, 'tcx>,
423 node_id: ast::NodeId)
424 -> Vec<ty::Predicate<'tcx>>;
427 /// Find bounds from both elements of the tuple.
428 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
429 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
431 fn get_type_parameter_bounds(&self,
432 astconv: &AstConv<'tcx, 'tcx>,
434 node_id: ast::NodeId)
435 -> Vec<ty::Predicate<'tcx>>
437 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
438 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
443 /// Empty set of bounds.
444 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
445 fn get_type_parameter_bounds(&self,
446 _astconv: &AstConv<'tcx, 'tcx>,
448 _node_id: ast::NodeId)
449 -> Vec<ty::Predicate<'tcx>>
455 /// Find bounds from the parsed and converted predicates. This is
456 /// used when converting methods, because by that time the predicates
457 /// from the trait/impl have been fully converted.
458 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
459 fn get_type_parameter_bounds(&self,
460 astconv: &AstConv<'tcx, 'tcx>,
462 node_id: ast::NodeId)
463 -> Vec<ty::Predicate<'tcx>>
465 let def = astconv.tcx().type_parameter_def(node_id);
467 let mut results = self.parent.map_or(vec![], |def_id| {
468 let parent = astconv.tcx().item_predicates(def_id);
469 parent.get_type_parameter_bounds(astconv, span, node_id)
472 results.extend(self.predicates.iter().filter(|predicate| {
474 ty::Predicate::Trait(ref data) => {
475 data.skip_binder().self_ty().is_param(def.index)
477 ty::Predicate::TypeOutlives(ref data) => {
478 data.skip_binder().0.is_param(def.index)
480 ty::Predicate::Equate(..) |
481 ty::Predicate::RegionOutlives(..) |
482 ty::Predicate::WellFormed(..) |
483 ty::Predicate::ObjectSafe(..) |
484 ty::Predicate::ClosureKind(..) |
485 ty::Predicate::Projection(..) => {
495 /// Find bounds from hir::Generics. This requires scanning through the
496 /// AST. We do this to avoid having to convert *all* the bounds, which
497 /// would create artificial cycles. Instead we can only convert the
498 /// bounds for a type parameter `X` if `X::Foo` is used.
499 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
500 fn get_type_parameter_bounds(&self,
501 astconv: &AstConv<'tcx, 'tcx>,
503 node_id: ast::NodeId)
504 -> Vec<ty::Predicate<'tcx>>
506 // In the AST, bounds can derive from two places. Either
507 // written inline like `<T:Foo>` or in a where clause like
510 let def = astconv.tcx().type_parameter_def(node_id);
511 let ty = astconv.tcx().mk_param_from_def(&def);
516 .filter(|p| p.id == node_id)
517 .flat_map(|p| p.bounds.iter())
518 .flat_map(|b| predicates_from_bound(astconv, ty, b));
520 let from_where_clauses =
524 .filter_map(|wp| match *wp {
525 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
528 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
529 .flat_map(|bp| bp.bounds.iter())
530 .flat_map(|b| predicates_from_bound(astconv, ty, b));
532 from_ty_params.chain(from_where_clauses).collect()
536 /// Tests whether this is the AST for a reference to the type
537 /// parameter with id `param_id`. We use this so as to avoid running
538 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
539 /// conversion of the type to avoid inducing unnecessary cycles.
540 fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
542 param_id: ast::NodeId)
545 if let hir::TyPath(hir::QPath::Resolved(None, _)) = ast_ty.node {
546 let path_res = tcx.expect_resolution(ast_ty.id);
547 match path_res.base_def {
548 Def::SelfTy(Some(def_id), None) |
549 Def::TyParam(def_id) if path_res.depth == 0 => {
550 def_id == tcx.map.local_def_id(param_id)
559 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
560 struct_generics: &'tcx ty::Generics<'tcx>,
561 struct_predicates: &ty::GenericPredicates<'tcx>,
562 field: &hir::StructField,
563 ty_f: ty::FieldDefMaster<'tcx>)
565 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty);
568 let def_id = ccx.tcx.map.local_def_id(field.id);
569 ccx.tcx.item_types.borrow_mut().insert(def_id, tt);
570 ccx.tcx.generics.borrow_mut().insert(def_id, struct_generics);
571 ccx.tcx.predicates.borrow_mut().insert(def_id, struct_predicates.clone());
574 fn convert_closure<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
575 node_id: ast::NodeId)
578 let def_id = tcx.map.local_def_id(node_id);
579 let base_def_id = tcx.closure_base_def_id(def_id);
580 let base_generics = generics_of_def_id(ccx, base_def_id);
582 // provide junk type parameter defs - the only place that
583 // cares about anything but the length is instantiation,
584 // and we don't do that for closures.
585 let upvar_decls : Vec<_> = tcx.with_freevars(node_id, |fv| {
586 fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
587 index: (base_generics.count() as u32) + (i as u32),
588 name: Symbol::intern("<upvar>"),
590 default_def_id: base_def_id,
592 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
593 pure_wrt_drop: false,
596 tcx.generics.borrow_mut().insert(def_id, tcx.alloc_generics(ty::Generics {
597 parent: Some(base_def_id),
598 parent_regions: base_generics.parent_regions + (base_generics.regions.len() as u32),
599 parent_types: base_generics.parent_types + (base_generics.types.len() as u32),
602 has_self: base_generics.has_self,
605 type_of_def_id(ccx, def_id);
608 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
609 container: AssociatedItemContainer,
611 sig: &hir::MethodSig,
612 untransformed_rcvr_ty: Ty<'tcx>,
613 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
614 let def_id = ccx.tcx.map.local_def_id(id);
615 let ty_generics = generics_of_def_id(ccx, def_id);
617 let ty_generic_predicates =
618 ty_generic_predicates(ccx, &sig.generics, ty_generics.parent, vec![], false);
620 let anon_scope = match container {
621 ImplContainer(_) => Some(AnonTypeScope::new(def_id)),
622 TraitContainer(_) => None
624 let fty = AstConv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
625 sig, untransformed_rcvr_ty, anon_scope);
627 let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
628 ccx.tcx.map.span(id), def_id);
629 let fty = ccx.tcx.mk_fn_def(def_id, substs, fty);
630 ccx.tcx.item_types.borrow_mut().insert(def_id, fty);
631 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_generic_predicates);
634 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
635 container: AssociatedItemContainer,
639 let predicates = ty::GenericPredicates {
640 parent: Some(container.id()),
643 let def_id = ccx.tcx.map.local_def_id(id);
644 ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
645 ccx.tcx.item_types.borrow_mut().insert(def_id, ty);
648 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
649 container: AssociatedItemContainer,
651 ty: Option<Ty<'tcx>>)
653 let predicates = ty::GenericPredicates {
654 parent: Some(container.id()),
657 let def_id = ccx.tcx.map.local_def_id(id);
658 ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
660 if let Some(ty) = ty {
661 ccx.tcx.item_types.borrow_mut().insert(def_id, ty);
665 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
667 generics: &hir::Generics,
668 thing: &'static str) {
669 let mut warn = false;
671 for ty_param in generics.ty_params.iter() {
672 for bound in ty_param.bounds.iter() {
674 hir::TraitTyParamBound(..) => {
677 hir::RegionTyParamBound(..) => { }
683 // According to accepted RFC #XXX, we should
684 // eventually accept these, but it will not be
685 // part of this PR. Still, convert to warning to
686 // make bootstrapping easier.
687 span_warn!(ccx.tcx.sess, span, E0122,
688 "trait bounds are not (yet) enforced \
694 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
696 debug!("convert: item {} with id {}", it.name, it.id);
698 // These don't define types.
699 hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
701 hir::ItemForeignMod(ref foreign_mod) => {
702 for item in &foreign_mod.items {
703 convert_foreign_item(ccx, item);
706 hir::ItemEnum(ref enum_definition, _) => {
707 let def_id = ccx.tcx.map.local_def_id(it.id);
708 let ty = type_of_def_id(ccx, def_id);
709 let generics = generics_of_def_id(ccx, def_id);
710 let predicates = predicates_of_item(ccx, it);
711 convert_enum_variant_types(ccx,
712 tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
716 &enum_definition.variants);
718 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
720 AstConv::instantiate_mono_trait_ref(&ccx.icx(&()),
725 tcx.record_trait_has_default_impl(trait_ref.def_id);
727 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
735 // Create generics from the generics specified in the impl head.
736 debug!("convert: ast_generics={:?}", generics);
737 let def_id = ccx.tcx.map.local_def_id(it.id);
738 generics_of_def_id(ccx, def_id);
739 let mut ty_predicates =
740 ty_generic_predicates(ccx, generics, None, vec![], false);
742 debug!("convert: impl_bounds={:?}", ty_predicates);
744 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &selfty);
745 tcx.item_types.borrow_mut().insert(def_id, selfty);
747 let trait_ref = opt_trait_ref.as_ref().map(|ast_trait_ref| {
748 AstConv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
753 tcx.impl_trait_refs.borrow_mut().insert(def_id, trait_ref);
755 // Subtle: before we store the predicates into the tcx, we
756 // sort them so that predicates like `T: Foo<Item=U>` come
757 // before uses of `U`. This avoids false ambiguity errors
758 // in trait checking. See `setup_constraining_predicates`
760 ctp::setup_constraining_predicates(&mut ty_predicates.predicates,
762 &mut ctp::parameters_for_impl(selfty, trait_ref));
764 tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
766 hir::ItemTrait(.., ref trait_items) => {
767 let trait_def = trait_def_of_item(ccx, it);
768 let def_id = trait_def.trait_ref.def_id;
769 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
770 ccx.ensure_super_predicates(it.span, def_id);
771 convert_trait_predicates(ccx, it);
772 let trait_predicates = tcx.item_predicates(def_id);
774 debug!("convert: trait_bounds={:?}", trait_predicates);
776 // FIXME: is the ordering here important? I think it is.
777 let container = TraitContainer(def_id);
779 // Convert all the associated constants.
780 for trait_item in trait_items {
781 if let hir::ConstTraitItem(ref ty, _) = trait_item.node {
782 let const_def_id = ccx.tcx.map.local_def_id(trait_item.id);
783 generics_of_def_id(ccx, const_def_id);
784 let ty = ccx.icx(&trait_predicates)
785 .to_ty(&ExplicitRscope, ty);
786 tcx.item_types.borrow_mut().insert(const_def_id, ty);
787 convert_associated_const(ccx, container, trait_item.id, ty)
791 // Convert all the associated types.
792 for trait_item in trait_items {
793 if let hir::TypeTraitItem(_, ref opt_ty) = trait_item.node {
794 let type_def_id = ccx.tcx.map.local_def_id(trait_item.id);
795 generics_of_def_id(ccx, type_def_id);
797 let typ = opt_ty.as_ref().map({
798 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
801 convert_associated_type(ccx, container, trait_item.id, typ);
805 // Convert all the methods
806 for trait_item in trait_items {
807 if let hir::MethodTraitItem(ref sig, _) = trait_item.node {
817 hir::ItemStruct(ref struct_def, _) |
818 hir::ItemUnion(ref struct_def, _) => {
819 let def_id = ccx.tcx.map.local_def_id(it.id);
820 let ty = type_of_def_id(ccx, def_id);
821 let generics = generics_of_def_id(ccx, def_id);
822 let predicates = predicates_of_item(ccx, it);
824 let variant = tcx.lookup_adt_def_master(def_id).struct_variant();
826 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
827 convert_field(ccx, generics, &predicates, f, ty_f)
830 if !struct_def.is_struct() {
831 convert_variant_ctor(ccx, struct_def.id(), variant, ty, predicates);
834 hir::ItemTy(_, ref generics) => {
835 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
836 let def_id = ccx.tcx.map.local_def_id(it.id);
837 type_of_def_id(ccx, def_id);
838 generics_of_def_id(ccx, def_id);
839 predicates_of_item(ccx, it);
842 let def_id = ccx.tcx.map.local_def_id(it.id);
843 type_of_def_id(ccx, def_id);
844 generics_of_def_id(ccx, def_id);
845 predicates_of_item(ccx, it);
850 fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
853 // we can lookup details about the impl because items are visited
855 let impl_def_id = tcx.map.get_parent_did(impl_item.id);
856 let impl_predicates = tcx.item_predicates(impl_def_id);
857 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
858 let impl_self_ty = tcx.item_type(impl_def_id);
860 match impl_item.node {
861 hir::ImplItemKind::Const(ref ty, _) => {
862 let const_def_id = ccx.tcx.map.local_def_id(impl_item.id);
863 generics_of_def_id(ccx, const_def_id);
864 let ty = ccx.icx(&impl_predicates)
865 .to_ty(&ExplicitRscope, &ty);
866 tcx.item_types.borrow_mut().insert(const_def_id, ty);
867 convert_associated_const(ccx, ImplContainer(impl_def_id),
871 hir::ImplItemKind::Type(ref ty) => {
872 let type_def_id = ccx.tcx.map.local_def_id(impl_item.id);
873 generics_of_def_id(ccx, type_def_id);
875 if impl_trait_ref.is_none() {
876 span_err!(tcx.sess, impl_item.span, E0202,
877 "associated types are not allowed in inherent impls");
880 let typ = ccx.icx(&impl_predicates).to_ty(&ExplicitRscope, ty);
882 convert_associated_type(ccx, ImplContainer(impl_def_id), impl_item.id, Some(typ));
885 hir::ImplItemKind::Method(ref sig, _) => {
886 convert_method(ccx, ImplContainer(impl_def_id),
887 impl_item.id, sig, impl_self_ty,
893 fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
894 ctor_id: ast::NodeId,
895 variant: ty::VariantDef<'tcx>,
897 predicates: ty::GenericPredicates<'tcx>) {
899 let def_id = tcx.map.local_def_id(ctor_id);
900 generics_of_def_id(ccx, def_id);
901 let ctor_ty = match variant.ctor_kind {
902 CtorKind::Fictive | CtorKind::Const => ty,
907 .map(|field| field.unsubst_ty())
909 let substs = mk_item_substs(&ccx.icx(&predicates),
910 ccx.tcx.map.span(ctor_id), def_id);
911 tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy {
912 unsafety: hir::Unsafety::Normal,
914 sig: ty::Binder(ty::FnSig {
922 tcx.item_types.borrow_mut().insert(def_id, ctor_ty);
923 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
926 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
927 def: ty::AdtDefMaster<'tcx>,
929 generics: &'tcx ty::Generics<'tcx>,
930 predicates: ty::GenericPredicates<'tcx>,
931 variants: &[hir::Variant]) {
932 // fill the field types
933 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
934 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
935 convert_field(ccx, generics, &predicates, f, ty_f)
938 // Convert the ctor, if any. This also registers the variant as
940 convert_variant_ctor(
942 variant.node.data.id(),
950 fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
954 def: &hir::VariantData)
955 -> ty::VariantDefData<'tcx, 'tcx> {
956 let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
957 let node_id = ccx.tcx.map.as_local_node_id(did).unwrap();
958 let fields = def.fields().iter().map(|f| {
959 let fid = ccx.tcx.map.local_def_id(f.id);
960 let dup_span = seen_fields.get(&f.name).cloned();
961 if let Some(prev_span) = dup_span {
962 struct_span_err!(ccx.tcx.sess, f.span, E0124,
963 "field `{}` is already declared",
965 .span_label(f.span, &"field already declared")
966 .span_label(prev_span, &format!("`{}` first declared here", f.name))
969 seen_fields.insert(f.name, f.span);
972 ty::FieldDefData::new(fid, f.name,
973 ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx))
980 ctor_kind: CtorKind::from_hir(def),
984 fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
986 def: &hir::VariantData)
987 -> ty::AdtDefMaster<'tcx>
989 let did = ccx.tcx.map.local_def_id(it.id);
990 // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
991 let ctor_id = if !def.is_struct() { Some(ccx.tcx.map.local_def_id(def.id())) } else { None };
992 let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
993 ConstInt::Infer(0), def)];
994 let adt = ccx.tcx.intern_adt_def(did, AdtKind::Struct, variants);
995 if let Some(ctor_id) = ctor_id {
996 // Make adt definition available through constructor id as well.
997 ccx.tcx.insert_adt_def(ctor_id, adt);
1002 fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1004 def: &hir::VariantData)
1005 -> ty::AdtDefMaster<'tcx>
1007 let did = ccx.tcx.map.local_def_id(it.id);
1008 let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)];
1009 ccx.tcx.intern_adt_def(did, AdtKind::Union, variants)
1012 fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
1013 -> Option<ty::Disr> {
1014 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1016 let ty_hint = repr_ty.to_ty(ccx.tcx);
1017 let print_err = |cv: ConstVal| {
1018 struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types")
1019 .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description()))
1020 .span_label(e.span, &format!("expected '{}' type", ty_hint))
1024 let hint = UncheckedExprHint(ty_hint);
1025 match eval_const_expr_partial(ccx.tcx, e, hint, None) {
1026 Ok(ConstVal::Integral(i)) => {
1027 // FIXME: eval_const_expr_partial should return an error if the hint is wrong
1028 match (repr_ty, i) {
1029 (attr::SignedInt(ast::IntTy::I8), ConstInt::I8(_)) |
1030 (attr::SignedInt(ast::IntTy::I16), ConstInt::I16(_)) |
1031 (attr::SignedInt(ast::IntTy::I32), ConstInt::I32(_)) |
1032 (attr::SignedInt(ast::IntTy::I64), ConstInt::I64(_)) |
1033 (attr::SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) |
1034 (attr::UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) |
1035 (attr::UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) |
1036 (attr::UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) |
1037 (attr::UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) |
1038 (attr::UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) => Some(i),
1040 print_err(ConstVal::Integral(i));
1049 // enum variant evaluation happens before the global constant check
1050 // so we need to report the real error
1052 let mut diag = report_const_eval_err(
1053 ccx.tcx, &err, e.span, "enum discriminant");
1060 fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1063 -> ty::AdtDefMaster<'tcx>
1066 let did = tcx.map.local_def_id(it.id);
1067 let repr_hints = tcx.lookup_repr_hints(did);
1068 let repr_type = tcx.enum_repr_type(repr_hints.get(0));
1069 let initial = repr_type.initial_discriminant(tcx);
1070 let mut prev_disr = None::<ty::Disr>;
1071 let variants = def.variants.iter().map(|v| {
1072 let wrapped_disr = prev_disr.map_or(initial, |d| d.wrap_incr());
1073 let disr = if let Some(ref e) = v.node.disr_expr {
1074 evaluate_disr_expr(ccx, repr_type, e)
1075 } else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) {
1078 struct_span_err!(tcx.sess, v.span, E0370,
1079 "enum discriminant overflowed")
1080 .span_label(v.span, &format!("overflowed on value after {}", prev_disr.unwrap()))
1081 .note(&format!("explicitly set `{} = {}` if that is desired outcome",
1082 v.node.name, wrapped_disr))
1085 }.unwrap_or(wrapped_disr);
1086 prev_disr = Some(disr);
1088 let did = tcx.map.local_def_id(v.node.data.id());
1089 convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
1091 tcx.intern_adt_def(tcx.map.local_def_id(it.id), AdtKind::Enum, variants)
1094 /// Ensures that the super-predicates of the trait with def-id
1095 /// trait_def_id are converted and stored. This does NOT ensure that
1096 /// the transitive super-predicates are converted; that is the job of
1097 /// the `ensure_super_predicates()` method in the `AstConv` impl
1098 /// above. Returns a list of trait def-ids that must be ensured as
1099 /// well to guarantee that the transitive superpredicates are
1101 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1102 trait_def_id: DefId)
1107 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1109 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1112 // If this trait comes from an external crate, then all of the
1113 // supertraits it may depend on also must come from external
1114 // crates, and hence all of them already have their
1115 // super-predicates "converted" (and available from crate
1116 // meta-data), so there is no need to transitively test them.
1120 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1121 let superpredicates = superpredicates.unwrap_or_else(|| {
1122 let item = match ccx.tcx.map.get(trait_node_id) {
1123 hir_map::NodeItem(item) => item,
1124 _ => bug!("trait_node_id {} is not an item", trait_node_id)
1127 let (generics, bounds) = match item.node {
1128 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1129 _ => span_bug!(item.span,
1130 "ensure_super_predicates_step invoked on non-trait"),
1133 // In-scope when converting the superbounds for `Trait` are
1134 // that `Self:Trait` as well as any bounds that appear on the
1136 let trait_def = trait_def_of_item(ccx, item);
1137 let self_predicate = ty::GenericPredicates {
1139 predicates: vec![trait_def.trait_ref.to_predicate()]
1141 let scope = &(generics, &self_predicate);
1143 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1144 let self_param_ty = tcx.mk_self_type();
1145 let superbounds1 = compute_bounds(&ccx.icx(scope),
1152 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1154 // Convert any explicit superbounds in the where clause,
1155 // e.g. `trait Foo where Self : Bar`:
1156 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1158 // Combine the two lists to form the complete set of superbounds:
1159 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1160 let superpredicates = ty::GenericPredicates {
1162 predicates: superbounds
1164 debug!("superpredicates for trait {:?} = {:?}",
1165 tcx.map.local_def_id(item.id),
1168 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1173 let def_ids: Vec<_> = superpredicates.predicates
1175 .filter_map(|p| p.to_opt_poly_trait_ref())
1176 .map(|tr| tr.def_id())
1179 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1184 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1186 -> &'tcx ty::TraitDef<'tcx>
1188 let def_id = ccx.tcx.map.local_def_id(it.id);
1191 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1195 let (unsafety, generics) = match it.node {
1196 hir::ItemTrait(unsafety, ref generics, _, _) => {
1197 (unsafety, generics)
1199 _ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
1202 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1203 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1204 let mut err = ccx.tcx.sess.struct_span_err(
1206 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1207 which traits can use parenthetical notation");
1209 "add `#![feature(unboxed_closures)]` to \
1210 the crate attributes to use it");
1214 let ty_generics = generics_of_def_id(ccx, def_id);
1215 let substs = mk_item_substs(&ccx.icx(generics), it.span, def_id);
1217 let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
1219 let trait_ref = ty::TraitRef::new(def_id, substs);
1220 let trait_def = ty::TraitDef::new(unsafety, paren_sugar, ty_generics, trait_ref,
1223 tcx.intern_trait_def(trait_def)
1226 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1228 let trait_def = trait_def_of_item(ccx, it);
1230 let def_id = ccx.tcx.map.local_def_id(it.id);
1232 let (generics, items) = match it.node {
1233 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1237 "trait_def_of_item invoked on {:?}",
1242 let super_predicates = ccx.tcx.item_super_predicates(def_id);
1244 // `ty_generic_predicates` below will consider the bounds on the type
1245 // parameters (including `Self`) and the explicit where-clauses,
1246 // but to get the full set of predicates on a trait we need to add
1247 // in the supertrait bounds and anything declared on the
1248 // associated types.
1249 let mut base_predicates = super_predicates.predicates;
1251 // Add in a predicate that `Self:Trait` (where `Trait` is the
1252 // current trait). This is needed for builtin bounds.
1253 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1254 base_predicates.push(self_predicate);
1256 // add in the explicit where-clauses
1257 let mut trait_predicates =
1258 ty_generic_predicates(ccx, generics, None, base_predicates, true);
1260 let assoc_predicates = predicates_for_associated_types(ccx,
1263 trait_def.trait_ref,
1265 trait_predicates.predicates.extend(assoc_predicates);
1267 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1268 assert!(prev_predicates.is_none());
1272 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1273 ast_generics: &hir::Generics,
1274 trait_predicates: &ty::GenericPredicates<'tcx>,
1275 self_trait_ref: ty::TraitRef<'tcx>,
1276 trait_items: &[hir::TraitItem])
1277 -> Vec<ty::Predicate<'tcx>>
1279 trait_items.iter().flat_map(|trait_item| {
1280 let bounds = match trait_item.node {
1281 hir::TypeTraitItem(ref bounds, _) => bounds,
1283 return vec![].into_iter();
1287 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1290 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1293 SizedByDefault::Yes,
1297 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1302 fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1304 -> &'tcx ty::Generics<'tcx> {
1306 let node_id = if let Some(id) = tcx.map.as_local_node_id(def_id) {
1309 return tcx.item_generics(def_id);
1311 tcx.generics.memoize(def_id, || {
1312 use rustc::hir::map::*;
1315 let node = tcx.map.get(node_id);
1316 let parent_def_id = match node {
1320 NodeStructCtor(_) => {
1321 let parent_id = tcx.map.get_parent(node_id);
1322 Some(tcx.map.local_def_id(parent_id))
1324 NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
1325 let mut parent_id = node_id;
1327 match tcx.map.get(parent_id) {
1328 NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
1330 parent_id = tcx.map.get_parent_node(parent_id);
1334 Some(tcx.map.local_def_id(parent_id))
1339 let mut opt_self = None;
1340 let mut allow_defaults = false;
1342 let no_generics = hir::Generics::empty();
1343 let ast_generics = match node {
1344 NodeTraitItem(item) => {
1346 MethodTraitItem(ref sig, _) => &sig.generics,
1351 NodeImplItem(item) => {
1353 ImplItemKind::Method(ref sig, _) => &sig.generics,
1360 ItemFn(.., ref generics, _) |
1361 ItemImpl(_, _, ref generics, ..) => generics,
1363 ItemTy(_, ref generics) |
1364 ItemEnum(_, ref generics) |
1365 ItemStruct(_, ref generics) |
1366 ItemUnion(_, ref generics) => {
1367 allow_defaults = true;
1371 ItemTrait(_, ref generics, ..) => {
1372 // Add in the self type parameter.
1374 // Something of a hack: use the node id for the trait, also as
1375 // the node id for the Self type parameter.
1376 let param_id = item.id;
1378 let parent = ccx.tcx.map.get_parent(param_id);
1380 let def = ty::TypeParameterDef {
1382 name: keywords::SelfType.name(),
1383 def_id: tcx.map.local_def_id(param_id),
1384 default_def_id: tcx.map.local_def_id(parent),
1386 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1387 pure_wrt_drop: false,
1389 tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1390 opt_self = Some(def);
1392 allow_defaults = true;
1400 NodeForeignItem(item) => {
1402 ForeignItemStatic(..) => &no_generics,
1403 ForeignItemFn(_, ref generics) => generics
1410 let has_self = opt_self.is_some();
1411 let mut parent_has_self = false;
1412 let mut own_start = has_self as u32;
1413 let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
1414 let generics = generics_of_def_id(ccx, def_id);
1415 assert_eq!(has_self, false);
1416 parent_has_self = generics.has_self;
1417 own_start = generics.count() as u32;
1418 (generics.parent_regions + generics.regions.len() as u32,
1419 generics.parent_types + generics.types.len() as u32)
1422 let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
1423 let regions = early_lifetimes.iter().enumerate().map(|(i, l)| {
1424 ty::RegionParameterDef {
1425 name: l.lifetime.name,
1426 index: own_start + i as u32,
1427 def_id: tcx.map.local_def_id(l.lifetime.id),
1428 bounds: l.bounds.iter().map(|l| {
1429 ast_region_to_region(tcx, l)
1431 pure_wrt_drop: l.pure_wrt_drop,
1433 }).collect::<Vec<_>>();
1435 // Now create the real type parameters.
1436 let type_start = own_start + regions.len() as u32;
1437 let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
1438 let i = type_start + i as u32;
1439 get_or_create_type_parameter_def(ccx, ast_generics, i, p, allow_defaults)
1441 let types: Vec<_> = opt_self.into_iter().chain(types).collect();
1444 if tcx.has_attr(def_id, "rustc_object_lifetime_default") {
1445 let object_lifetime_default_reprs: String =
1446 types.iter().map(|t| {
1447 match t.object_lifetime_default {
1448 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1449 d => format!("{:?}", d),
1451 }).collect::<Vec<String>>().join(",");
1452 tcx.sess.span_err(tcx.map.span(node_id), &object_lifetime_default_reprs);
1455 tcx.alloc_generics(ty::Generics {
1456 parent: parent_def_id,
1457 parent_regions: parent_regions,
1458 parent_types: parent_types,
1461 has_self: has_self || parent_has_self
1466 fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1469 let node_id = if let Some(id) = ccx.tcx.map.as_local_node_id(def_id) {
1472 return ccx.tcx.item_type(def_id);
1474 ccx.tcx.item_types.memoize(def_id, || {
1475 use rustc::hir::map::*;
1478 // Alway bring in generics, as computing the type needs them.
1479 generics_of_def_id(ccx, def_id);
1481 let ty = match ccx.tcx.map.get(node_id) {
1484 ItemStatic(ref t, ..) | ItemConst(ref t, _) => {
1485 ccx.icx(&()).to_ty(&StaticRscope::new(&ccx.tcx), &t)
1487 ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1488 let tofd = AstConv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl,
1489 Some(AnonTypeScope::new(def_id)));
1490 let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
1491 ccx.tcx.mk_fn_def(def_id, substs, tofd)
1493 ItemTy(ref t, ref generics) => {
1494 ccx.icx(generics).to_ty(&ExplicitRscope, &t)
1496 ItemEnum(ref ei, ref generics) => {
1497 let def = convert_enum_def(ccx, item, ei);
1498 let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
1499 ccx.tcx.mk_adt(def, substs)
1501 ItemStruct(ref si, ref generics) => {
1502 let def = convert_struct_def(ccx, item, si);
1503 let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
1504 ccx.tcx.mk_adt(def, substs)
1506 ItemUnion(ref un, ref generics) => {
1507 let def = convert_union_def(ccx, item, un);
1508 let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
1509 ccx.tcx.mk_adt(def, substs)
1511 ItemDefaultImpl(..) |
1515 ItemForeignMod(..) |
1516 ItemExternCrate(..) |
1520 "compute_type_of_item: unexpected item type: {:?}",
1525 NodeForeignItem(foreign_item) => {
1526 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1528 match foreign_item.node {
1529 ForeignItemFn(ref fn_decl, ref generics) => {
1530 compute_type_of_foreign_fn_decl(
1531 ccx, ccx.tcx.map.local_def_id(foreign_item.id),
1532 fn_decl, generics, abi)
1534 ForeignItemStatic(ref t, _) => {
1535 ccx.icx(&()).to_ty(&ExplicitRscope, t)
1539 NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1540 ccx.tcx.mk_closure(def_id, Substs::for_item(
1542 |def, _| ccx.tcx.mk_region(def.to_early_bound_region()),
1543 |def, _| ccx.tcx.mk_param_from_def(def)
1547 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
1555 fn predicates_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1557 -> ty::GenericPredicates<'tcx> {
1558 let def_id = ccx.tcx.map.local_def_id(it.id);
1560 let no_generics = hir::Generics::empty();
1561 let generics = match it.node {
1562 hir::ItemFn(.., ref generics, _) |
1563 hir::ItemTy(_, ref generics) |
1564 hir::ItemEnum(_, ref generics) |
1565 hir::ItemStruct(_, ref generics) |
1566 hir::ItemUnion(_, ref generics) => generics,
1570 let predicates = ty_generic_predicates(ccx, generics, None, vec![], false);
1571 let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id,
1572 predicates.clone());
1573 assert!(prev_predicates.is_none());
1578 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1579 it: &hir::ForeignItem)
1581 // For reasons I cannot fully articulate, I do so hate the AST
1582 // map, and I regard each time that I use it as a personal and
1583 // moral failing, but at the moment it seems like the only
1584 // convenient way to extract the ABI. - ndm
1585 let def_id = ccx.tcx.map.local_def_id(it.id);
1586 type_of_def_id(ccx, def_id);
1587 generics_of_def_id(ccx, def_id);
1589 let no_generics = hir::Generics::empty();
1590 let generics = match it.node {
1591 hir::ForeignItemFn(_, ref generics) => generics,
1592 hir::ForeignItemStatic(..) => &no_generics
1595 let predicates = ty_generic_predicates(ccx, generics, None, vec![], false);
1596 let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
1597 assert!(prev_predicates.is_none());
1600 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1601 fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1602 bounds: &mut ty::BuiltinBounds,
1603 ast_bounds: &[hir::TyParamBound],
1606 let tcx = astconv.tcx();
1608 // Try to find an unbound in bounds.
1609 let mut unbound = None;
1610 for ab in ast_bounds {
1611 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1612 if unbound.is_none() {
1613 assert!(ptr.bound_lifetimes.is_empty());
1614 unbound = Some(ptr.trait_ref.clone());
1616 span_err!(tcx.sess, span, E0203,
1617 "type parameter has more than one relaxed default \
1618 bound, only one is supported");
1623 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1626 // FIXME(#8559) currently requires the unbound to be built-in.
1627 if let Ok(kind_id) = kind_id {
1628 let trait_def = tcx.expect_def(tpb.ref_id);
1629 if trait_def != Def::Trait(kind_id) {
1630 tcx.sess.span_warn(span,
1631 "default bound relaxed for a type parameter, but \
1632 this does nothing because the given bound is not \
1633 a default. Only `?Sized` is supported");
1634 tcx.try_add_builtin_trait(kind_id, bounds);
1638 _ if kind_id.is_ok() => {
1639 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1641 // No lang item for Sized, so we can't add it as a bound.
1646 /// Returns the early-bound lifetimes declared in this generics
1647 /// listing. For anything other than fns/methods, this is just all
1648 /// the lifetimes that are declared. For fns or methods, we have to
1649 /// screen out those that do not appear in any where-clauses etc using
1650 /// `resolve_lifetime::early_bound_lifetimes`.
1651 fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>(
1652 ccx: &CrateCtxt<'a, 'tcx>,
1653 ast_generics: &'hir hir::Generics)
1654 -> Vec<&'hir hir::LifetimeDef>
1659 .filter(|l| !ccx.tcx.named_region_map.late_bound.contains_key(&l.lifetime.id))
1663 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1664 ast_generics: &hir::Generics,
1665 parent: Option<DefId>,
1666 super_predicates: Vec<ty::Predicate<'tcx>>,
1668 -> ty::GenericPredicates<'tcx>
1671 let parent_count = parent.map_or(0, |def_id| {
1672 let generics = generics_of_def_id(ccx, def_id);
1673 assert_eq!(generics.parent, None);
1674 assert_eq!(generics.parent_regions, 0);
1675 assert_eq!(generics.parent_types, 0);
1676 generics.count() as u32
1678 let ref base_predicates = match parent {
1680 assert_eq!(super_predicates, vec![]);
1681 tcx.item_predicates(def_id)
1684 ty::GenericPredicates {
1686 predicates: super_predicates.clone()
1690 let mut predicates = super_predicates;
1692 // Collect the region predicates that were declared inline as
1693 // well. In the case of parameters declared on a fn or method, we
1694 // have to be careful to only iterate over early-bound regions.
1695 let own_start = parent_count + has_self as u32;
1696 let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
1697 for (index, param) in early_lifetimes.iter().enumerate() {
1698 let index = own_start + index as u32;
1699 let region = ccx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
1701 name: param.lifetime.name
1703 for bound in ¶m.bounds {
1704 let bound_region = ast_region_to_region(ccx.tcx, bound);
1705 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1706 predicates.push(outlives.to_predicate());
1710 // Collect the predicates that were written inline by the user on each
1711 // type parameter (e.g., `<T:Foo>`).
1712 let type_start = own_start + early_lifetimes.len() as u32;
1713 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1714 let index = type_start + index as u32;
1715 let param_ty = ty::ParamTy::new(index, param.name).to_ty(ccx.tcx);
1716 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1719 SizedByDefault::Yes,
1722 predicates.extend(bounds.predicates(ccx.tcx, param_ty));
1725 // Add in the bounds that appear in the where-clause
1726 let where_clause = &ast_generics.where_clause;
1727 for predicate in &where_clause.predicates {
1729 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1730 let ty = AstConv::ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1732 &bound_pred.bounded_ty);
1734 for bound in bound_pred.bounds.iter() {
1736 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1737 let mut projections = Vec::new();
1740 AstConv::instantiate_poly_trait_ref(&ccx.icx(&(base_predicates,
1747 predicates.push(trait_ref.to_predicate());
1749 for projection in &projections {
1750 predicates.push(projection.to_predicate());
1754 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1755 let region = ast_region_to_region(tcx, lifetime);
1756 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1757 predicates.push(ty::Predicate::TypeOutlives(pred))
1763 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1764 let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime);
1765 for bound in ®ion_pred.bounds {
1766 let r2 = ast_region_to_region(tcx, bound);
1767 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1768 predicates.push(ty::Predicate::RegionOutlives(pred))
1772 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1774 span_bug!(eq_pred.span,
1775 "Equality constraints are not yet \
1776 implemented (#20041)")
1781 ty::GenericPredicates {
1783 predicates: predicates
1787 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1788 ast_generics: &hir::Generics,
1790 param: &hir::TyParam,
1791 allow_defaults: bool)
1792 -> ty::TypeParameterDef<'tcx>
1795 match tcx.ty_param_defs.borrow().get(¶m.id) {
1796 Some(d) => { return d.clone(); }
1801 param.default.as_ref().map(|def| ccx.icx(&()).to_ty(&ExplicitRscope, def));
1803 let object_lifetime_default =
1804 compute_object_lifetime_default(ccx, param.id,
1805 ¶m.bounds, &ast_generics.where_clause);
1807 let parent = tcx.map.get_parent(param.id);
1809 if !allow_defaults && default.is_some() {
1810 if !tcx.sess.features.borrow().default_type_parameter_fallback {
1812 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1815 format!("defaults for type parameters are only allowed in `struct`, \
1816 `enum`, `type`, or `trait` definitions."));
1820 let def = ty::TypeParameterDef {
1823 def_id: ccx.tcx.map.local_def_id(param.id),
1824 default_def_id: ccx.tcx.map.local_def_id(parent),
1826 object_lifetime_default: object_lifetime_default,
1827 pure_wrt_drop: param.pure_wrt_drop,
1830 if def.name == keywords::SelfType.name() {
1831 span_bug!(param.span, "`Self` should not be the name of a regular parameter");
1834 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
1836 debug!("get_or_create_type_parameter_def: def for type param: {:?}", def);
1841 /// Scan the bounds and where-clauses on a parameter to extract bounds
1842 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
1843 /// This runs as part of computing the minimal type scheme, so we
1844 /// intentionally avoid just asking astconv to convert all the where
1845 /// clauses into a `ty::Predicate`. This is because that could induce
1846 /// artificial cycles.
1847 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1848 param_id: ast::NodeId,
1849 param_bounds: &[hir::TyParamBound],
1850 where_clause: &hir::WhereClause)
1851 -> ty::ObjectLifetimeDefault<'tcx>
1853 let inline_bounds = from_bounds(ccx, param_bounds);
1854 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
1855 let all_bounds: FxHashSet<_> = inline_bounds.into_iter()
1856 .chain(where_bounds)
1858 return if all_bounds.len() > 1 {
1859 ty::ObjectLifetimeDefault::Ambiguous
1860 } else if all_bounds.len() == 0 {
1861 ty::ObjectLifetimeDefault::BaseDefault
1863 ty::ObjectLifetimeDefault::Specific(
1864 all_bounds.into_iter().next().unwrap())
1867 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1868 bounds: &[hir::TyParamBound])
1869 -> Vec<&'tcx ty::Region>
1872 .filter_map(|bound| {
1874 hir::TraitTyParamBound(..) =>
1876 hir::RegionTyParamBound(ref lifetime) =>
1877 Some(ast_region_to_region(ccx.tcx, lifetime)),
1883 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1884 param_id: ast::NodeId,
1885 predicates: &[hir::WherePredicate])
1886 -> Vec<&'tcx ty::Region>
1889 .flat_map(|predicate| {
1891 hir::WherePredicate::BoundPredicate(ref data) => {
1892 if data.bound_lifetimes.is_empty() &&
1893 is_param(ccx.tcx, &data.bounded_ty, param_id)
1895 from_bounds(ccx, &data.bounds).into_iter()
1897 Vec::new().into_iter()
1900 hir::WherePredicate::RegionPredicate(..) |
1901 hir::WherePredicate::EqPredicate(..) => {
1902 Vec::new().into_iter()
1910 pub enum SizedByDefault { Yes, No, }
1912 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
1913 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
1914 /// built-in trait (formerly known as kind): Send.
1915 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
1916 param_ty: ty::Ty<'tcx>,
1917 ast_bounds: &[hir::TyParamBound],
1918 sized_by_default: SizedByDefault,
1919 anon_scope: Option<AnonTypeScope>,
1923 let tcx = astconv.tcx();
1924 let PartitionedBounds {
1928 } = partition_bounds(tcx, span, &ast_bounds);
1930 if let SizedByDefault::Yes = sized_by_default {
1931 add_unsized_bound(astconv, &mut builtin_bounds, ast_bounds, span);
1934 let mut projection_bounds = vec![];
1936 let rscope = MaybeWithAnonTypes::new(ExplicitRscope, anon_scope);
1937 let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1938 astconv.instantiate_poly_trait_ref(&rscope,
1941 &mut projection_bounds)
1944 let region_bounds = region_bounds.into_iter().map(|r| {
1945 ast_region_to_region(tcx, r)
1948 trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
1951 region_bounds: region_bounds,
1952 builtin_bounds: builtin_bounds,
1953 trait_bounds: trait_bounds,
1954 projection_bounds: projection_bounds,
1958 /// Converts a specific TyParamBound from the AST into a set of
1959 /// predicates that apply to the self-type. A vector is returned
1960 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
1961 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
1962 /// and `<T as Bar>::X == i32`).
1963 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
1965 bound: &hir::TyParamBound)
1966 -> Vec<ty::Predicate<'tcx>>
1969 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
1970 let mut projections = Vec::new();
1971 let pred = astconv.instantiate_poly_trait_ref(&ExplicitRscope,
1975 projections.into_iter()
1976 .map(|p| p.to_predicate())
1977 .chain(Some(pred.to_predicate()))
1980 hir::RegionTyParamBound(ref lifetime) => {
1981 let region = ast_region_to_region(astconv.tcx(), lifetime);
1982 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
1983 vec![ty::Predicate::TypeOutlives(pred)]
1985 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
1991 fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
1992 ccx: &CrateCtxt<'a, 'tcx>,
1995 ast_generics: &hir::Generics,
1999 let rb = BindingRscope::new();
2000 let input_tys = decl.inputs
2002 .map(|a| AstConv::ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2003 .collect::<Vec<_>>();
2005 let output = match decl.output {
2006 hir::Return(ref ty) =>
2007 AstConv::ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &ty),
2008 hir::DefaultReturn(..) =>
2012 // feature gate SIMD types in FFI, since I (huonw) am not sure the
2013 // ABIs are handled at all correctly.
2014 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
2015 && !ccx.tcx.sess.features.borrow().simd_ffi {
2016 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
2018 ccx.tcx.sess.struct_span_err(ast_ty.span,
2019 &format!("use of SIMD type `{}` in FFI is highly experimental and \
2020 may result in invalid code",
2021 pprust::ty_to_string(ast_ty)))
2022 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
2026 for (input, ty) in decl.inputs.iter().zip(&input_tys) {
2027 check(&input.ty, ty)
2029 if let hir::Return(ref ty) = decl.output {
2034 let id = ccx.tcx.map.as_local_node_id(def_id).unwrap();
2035 let substs = mk_item_substs(&ccx.icx(ast_generics), ccx.tcx.map.span(id), def_id);
2036 ccx.tcx.mk_fn_def(def_id, substs, ccx.tcx.mk_bare_fn(ty::BareFnTy {
2038 unsafety: hir::Unsafety::Unsafe,
2039 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2041 variadic: decl.variadic}),
2045 pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
2048 -> &'tcx Substs<'tcx> {
2049 let tcx = astconv.tcx();
2050 // FIXME(eddyb) Do this request from Substs::for_item in librustc.
2051 if let Err(ErrorReported) = astconv.get_generics(span, def_id) {
2052 // No convenient way to recover from a cycle here. Just bail. Sorry!
2053 tcx.sess.abort_if_errors();
2054 bug!("ErrorReported returned, but no errors reports?")
2057 Substs::for_item(tcx, def_id,
2058 |def, _| tcx.mk_region(def.to_early_bound_region()),
2059 |def, _| tcx.mk_param_from_def(def))