]> git.proxmox.com Git - rustc.git/blob - src/librustc_typeck/collect.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc_typeck / collect.rs
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.
4 //
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.
10
11 /*
12
13 # Collect phase
14
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.
21
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.
28
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`.
36
37 Currently, we "convert" types and traits in two phases (note that
38 conversion only affects the types of items / enum variants / methods;
39 it does not e.g. compute the types of individual expressions):
40
41 0. Intrinsics
42 1. Trait/Type definitions
43
44 Conversion itself is done by simply walking each of the items in turn
45 and invoking an appropriate function (e.g., `trait_def_of_item` or
46 `convert_item`). However, it is possible that while converting an
47 item, we may need to compute the *type scheme* or *trait definition*
48 for other items.
49
50 There are some shortcomings in this design:
51
52 - Before walking the set of supertraits for a given trait, you must
53 call `ensure_super_predicates` on that trait def-id. Otherwise,
54 `lookup_super_predicates` will result in ICEs.
55 - Because the type scheme includes defaults, cycles through type
56 parameter defaults are illegal even if those defaults are never
57 employed. This is not necessarily a bug.
58
59 */
60
61 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
62 use lint;
63 use hir::def::Def;
64 use hir::def_id::DefId;
65 use constrained_type_params as ctp;
66 use coherence;
67 use middle::lang_items::SizedTraitLangItem;
68 use middle::resolve_lifetime;
69 use middle::const_val::ConstVal;
70 use rustc_const_eval::EvalHint::UncheckedExprHint;
71 use rustc_const_eval::eval_const_expr_partial;
72 use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
73 use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
74 use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
75 use rustc::ty::{VariantKind};
76 use rustc::ty::fold::{TypeFolder};
77 use rustc::ty::util::IntTypeExt;
78 use rscope::*;
79 use rustc::dep_graph::DepNode;
80 use rustc::hir::map as hir_map;
81 use util::common::{ErrorReported, MemoizationMap};
82 use util::nodemap::{FnvHashMap, FnvHashSet};
83 use write_ty_to_tcx;
84
85 use rustc_const_math::ConstInt;
86
87 use std::cell::RefCell;
88 use std::collections::HashSet;
89 use std::rc::Rc;
90
91 use syntax::abi;
92 use syntax::ast;
93 use syntax::attr;
94 use syntax::codemap::Span;
95 use syntax::parse::token::special_idents;
96 use syntax::ptr::P;
97 use rustc::hir::{self, PatKind};
98 use rustc::hir::intravisit;
99 use rustc::hir::print as pprust;
100
101 ///////////////////////////////////////////////////////////////////////////
102 // Main entry point
103
104 pub fn collect_item_types(tcx: &TyCtxt) {
105 let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) };
106 let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
107 ccx.tcx.visit_all_items_in_krate(DepNode::CollectItem, &mut visitor);
108 }
109
110 ///////////////////////////////////////////////////////////////////////////
111
112 struct CrateCtxt<'a,'tcx:'a> {
113 tcx: &'a TyCtxt<'tcx>,
114
115 // This stack is used to identify cycles in the user's source.
116 // Note that these cycles can cross multiple items.
117 stack: RefCell<Vec<AstConvRequest>>,
118 }
119
120 /// Context specific to some particular item. This is what implements
121 /// AstConv. It has information about the predicates that are defined
122 /// on the trait. Unfortunately, this predicate information is
123 /// available in various different forms at various points in the
124 /// process. So we can't just store a pointer to e.g. the AST or the
125 /// parsed ty form, we have to be more flexible. To this end, the
126 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
127 /// that it uses to satisfy `get_type_parameter_bounds` requests.
128 /// This object might draw the information from the AST
129 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
130 /// or both (a tuple).
131 struct ItemCtxt<'a,'tcx:'a> {
132 ccx: &'a CrateCtxt<'a,'tcx>,
133 param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
134 }
135
136 #[derive(Copy, Clone, PartialEq, Eq)]
137 enum AstConvRequest {
138 GetItemTypeScheme(DefId),
139 GetTraitDef(DefId),
140 EnsureSuperPredicates(DefId),
141 GetTypeParameterBounds(ast::NodeId),
142 }
143
144 ///////////////////////////////////////////////////////////////////////////
145
146 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
147 ccx: &'a CrateCtxt<'a, 'tcx>
148 }
149
150 impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
151 fn visit_item(&mut self, item: &hir::Item) {
152 convert_item(self.ccx, item);
153 }
154 }
155
156 ///////////////////////////////////////////////////////////////////////////
157 // Utility types and common code for the above passes.
158
159 impl<'a,'tcx> CrateCtxt<'a,'tcx> {
160 fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
161 ItemCtxt { ccx: self, param_bounds: param_bounds }
162 }
163
164 fn cycle_check<F,R>(&self,
165 span: Span,
166 request: AstConvRequest,
167 code: F)
168 -> Result<R,ErrorReported>
169 where F: FnOnce() -> Result<R,ErrorReported>
170 {
171 {
172 let mut stack = self.stack.borrow_mut();
173 match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
174 None => { }
175 Some((i, _)) => {
176 let cycle = &stack[i..];
177 self.report_cycle(span, cycle);
178 return Err(ErrorReported);
179 }
180 }
181 stack.push(request);
182 }
183
184 let result = code();
185
186 self.stack.borrow_mut().pop();
187 result
188 }
189
190 fn report_cycle(&self,
191 span: Span,
192 cycle: &[AstConvRequest])
193 {
194 assert!(!cycle.is_empty());
195 let tcx = self.tcx;
196
197 let mut err = struct_span_err!(tcx.sess, span, E0391,
198 "unsupported cyclic reference between types/traits detected");
199
200 match cycle[0] {
201 AstConvRequest::GetItemTypeScheme(def_id) |
202 AstConvRequest::GetTraitDef(def_id) => {
203 err.note(
204 &format!("the cycle begins when processing `{}`...",
205 tcx.item_path_str(def_id)));
206 }
207 AstConvRequest::EnsureSuperPredicates(def_id) => {
208 err.note(
209 &format!("the cycle begins when computing the supertraits of `{}`...",
210 tcx.item_path_str(def_id)));
211 }
212 AstConvRequest::GetTypeParameterBounds(id) => {
213 let def = tcx.type_parameter_def(id);
214 err.note(
215 &format!("the cycle begins when computing the bounds \
216 for type parameter `{}`...",
217 def.name));
218 }
219 }
220
221 for request in &cycle[1..] {
222 match *request {
223 AstConvRequest::GetItemTypeScheme(def_id) |
224 AstConvRequest::GetTraitDef(def_id) => {
225 err.note(
226 &format!("...which then requires processing `{}`...",
227 tcx.item_path_str(def_id)));
228 }
229 AstConvRequest::EnsureSuperPredicates(def_id) => {
230 err.note(
231 &format!("...which then requires computing the supertraits of `{}`...",
232 tcx.item_path_str(def_id)));
233 }
234 AstConvRequest::GetTypeParameterBounds(id) => {
235 let def = tcx.type_parameter_def(id);
236 err.note(
237 &format!("...which then requires computing the bounds \
238 for type parameter `{}`...",
239 def.name));
240 }
241 }
242 }
243
244 match cycle[0] {
245 AstConvRequest::GetItemTypeScheme(def_id) |
246 AstConvRequest::GetTraitDef(def_id) => {
247 err.note(
248 &format!("...which then again requires processing `{}`, completing the cycle.",
249 tcx.item_path_str(def_id)));
250 }
251 AstConvRequest::EnsureSuperPredicates(def_id) => {
252 err.note(
253 &format!("...which then again requires computing the supertraits of `{}`, \
254 completing the cycle.",
255 tcx.item_path_str(def_id)));
256 }
257 AstConvRequest::GetTypeParameterBounds(id) => {
258 let def = tcx.type_parameter_def(id);
259 err.note(
260 &format!("...which then again requires computing the bounds \
261 for type parameter `{}`, completing the cycle.",
262 def.name));
263 }
264 }
265 err.emit();
266 }
267
268 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
269 fn get_trait_def(&self, trait_id: DefId)
270 -> &'tcx ty::TraitDef<'tcx>
271 {
272 let tcx = self.tcx;
273
274 if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
275 let item = match tcx.map.get(trait_id) {
276 hir_map::NodeItem(item) => item,
277 _ => bug!("get_trait_def({:?}): not an item", trait_id)
278 };
279
280 trait_def_of_item(self, &item)
281 } else {
282 tcx.lookup_trait_def(trait_id)
283 }
284 }
285
286 /// Ensure that the (transitive) super predicates for
287 /// `trait_def_id` are available. This will report a cycle error
288 /// if a trait `X` (transitively) extends itself in some form.
289 fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId)
290 -> Result<(), ErrorReported>
291 {
292 self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
293 let def_ids = ensure_super_predicates_step(self, trait_def_id);
294
295 for def_id in def_ids {
296 self.ensure_super_predicates(span, def_id)?;
297 }
298
299 Ok(())
300 })
301 }
302 }
303
304 impl<'a,'tcx> ItemCtxt<'a,'tcx> {
305 fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> {
306 ast_ty_to_ty(self, rs, ast_ty)
307 }
308 }
309
310 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
311 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
312
313 fn get_item_type_scheme(&self, span: Span, id: DefId)
314 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
315 {
316 self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
317 Ok(type_scheme_of_def_id(self.ccx, id))
318 })
319 }
320
321 fn get_trait_def(&self, span: Span, id: DefId)
322 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
323 {
324 self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
325 Ok(self.ccx.get_trait_def(id))
326 })
327 }
328
329 fn ensure_super_predicates(&self,
330 span: Span,
331 trait_def_id: DefId)
332 -> Result<(), ErrorReported>
333 {
334 debug!("ensure_super_predicates(trait_def_id={:?})",
335 trait_def_id);
336
337 self.ccx.ensure_super_predicates(span, trait_def_id)
338 }
339
340
341 fn get_type_parameter_bounds(&self,
342 span: Span,
343 node_id: ast::NodeId)
344 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
345 {
346 self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
347 let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
348 .into_iter()
349 .filter_map(|p| p.to_opt_poly_trait_ref())
350 .collect();
351 Ok(v)
352 })
353 }
354
355 fn trait_defines_associated_type_named(&self,
356 trait_def_id: DefId,
357 assoc_name: ast::Name)
358 -> bool
359 {
360 if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
361 trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
362 } else {
363 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
364 trait_def.associated_type_names.contains(&assoc_name)
365 }
366 }
367
368 fn ty_infer(&self,
369 _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
370 _substs: Option<&mut Substs<'tcx>>,
371 _space: Option<ParamSpace>,
372 span: Span) -> Ty<'tcx> {
373 span_err!(self.tcx().sess, span, E0121,
374 "the type placeholder `_` is not allowed within types on item signatures");
375 self.tcx().types.err
376 }
377
378 fn projected_ty(&self,
379 _span: Span,
380 trait_ref: ty::TraitRef<'tcx>,
381 item_name: ast::Name)
382 -> Ty<'tcx>
383 {
384 self.tcx().mk_projection(trait_ref, item_name)
385 }
386 }
387
388 /// Interface used to find the bounds on a type parameter from within
389 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
390 trait GetTypeParameterBounds<'tcx> {
391 fn get_type_parameter_bounds(&self,
392 astconv: &AstConv<'tcx>,
393 span: Span,
394 node_id: ast::NodeId)
395 -> Vec<ty::Predicate<'tcx>>;
396 }
397
398 /// Find bounds from both elements of the tuple.
399 impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
400 where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
401 {
402 fn get_type_parameter_bounds(&self,
403 astconv: &AstConv<'tcx>,
404 span: Span,
405 node_id: ast::NodeId)
406 -> Vec<ty::Predicate<'tcx>>
407 {
408 let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
409 v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id));
410 v
411 }
412 }
413
414 /// Empty set of bounds.
415 impl<'tcx> GetTypeParameterBounds<'tcx> for () {
416 fn get_type_parameter_bounds(&self,
417 _astconv: &AstConv<'tcx>,
418 _span: Span,
419 _node_id: ast::NodeId)
420 -> Vec<ty::Predicate<'tcx>>
421 {
422 Vec::new()
423 }
424 }
425
426 /// Find bounds from the parsed and converted predicates. This is
427 /// used when converting methods, because by that time the predicates
428 /// from the trait/impl have been fully converted.
429 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
430 fn get_type_parameter_bounds(&self,
431 astconv: &AstConv<'tcx>,
432 _span: Span,
433 node_id: ast::NodeId)
434 -> Vec<ty::Predicate<'tcx>>
435 {
436 let def = astconv.tcx().type_parameter_def(node_id);
437
438 self.predicates
439 .iter()
440 .filter(|predicate| {
441 match **predicate {
442 ty::Predicate::Trait(ref data) => {
443 data.skip_binder().self_ty().is_param(def.space, def.index)
444 }
445 ty::Predicate::TypeOutlives(ref data) => {
446 data.skip_binder().0.is_param(def.space, def.index)
447 }
448 ty::Predicate::Equate(..) |
449 ty::Predicate::RegionOutlives(..) |
450 ty::Predicate::WellFormed(..) |
451 ty::Predicate::ObjectSafe(..) |
452 ty::Predicate::Projection(..) => {
453 false
454 }
455 }
456 })
457 .cloned()
458 .collect()
459 }
460 }
461
462 /// Find bounds from hir::Generics. This requires scanning through the
463 /// AST. We do this to avoid having to convert *all* the bounds, which
464 /// would create artificial cycles. Instead we can only convert the
465 /// bounds for a type parameter `X` if `X::Foo` is used.
466 impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
467 fn get_type_parameter_bounds(&self,
468 astconv: &AstConv<'tcx>,
469 _: Span,
470 node_id: ast::NodeId)
471 -> Vec<ty::Predicate<'tcx>>
472 {
473 // In the AST, bounds can derive from two places. Either
474 // written inline like `<T:Foo>` or in a where clause like
475 // `where T:Foo`.
476
477 let def = astconv.tcx().type_parameter_def(node_id);
478 let ty = astconv.tcx().mk_param_from_def(&def);
479
480 let from_ty_params =
481 self.ty_params
482 .iter()
483 .filter(|p| p.id == node_id)
484 .flat_map(|p| p.bounds.iter())
485 .flat_map(|b| predicates_from_bound(astconv, ty, b));
486
487 let from_where_clauses =
488 self.where_clause
489 .predicates
490 .iter()
491 .filter_map(|wp| match *wp {
492 hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
493 _ => None
494 })
495 .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
496 .flat_map(|bp| bp.bounds.iter())
497 .flat_map(|b| predicates_from_bound(astconv, ty, b));
498
499 from_ty_params.chain(from_where_clauses).collect()
500 }
501 }
502
503 /// Tests whether this is the AST for a reference to the type
504 /// parameter with id `param_id`. We use this so as to avoid running
505 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
506 /// conversion of the type to avoid inducing unnecessary cycles.
507 fn is_param<'tcx>(tcx: &TyCtxt<'tcx>,
508 ast_ty: &hir::Ty,
509 param_id: ast::NodeId)
510 -> bool
511 {
512 if let hir::TyPath(None, _) = ast_ty.node {
513 let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
514 match path_res.base_def {
515 Def::SelfTy(Some(def_id), None) => {
516 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
517 }
518 Def::TyParam(_, _, def_id, _) => {
519 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
520 }
521 _ => {
522 false
523 }
524 }
525 } else {
526 false
527 }
528 }
529
530
531 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
532 container: ImplOrTraitItemContainer,
533 name: ast::Name,
534 id: ast::NodeId,
535 vis: &hir::Visibility,
536 sig: &hir::MethodSig,
537 defaultness: hir::Defaultness,
538 untransformed_rcvr_ty: Ty<'tcx>,
539 rcvr_ty_generics: &ty::Generics<'tcx>,
540 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
541 let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
542
543 let ty_generic_predicates =
544 ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
545
546 let (fty, explicit_self_category) =
547 astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
548 sig, untransformed_rcvr_ty);
549
550 let def_id = ccx.tcx.map.local_def_id(id);
551 let substs = ccx.tcx.mk_substs(mk_item_substs(ccx, &ty_generics));
552
553 let ty_method = ty::Method::new(name,
554 ty_generics,
555 ty_generic_predicates,
556 fty,
557 explicit_self_category,
558 ty::Visibility::from_hir(vis, id, ccx.tcx),
559 defaultness,
560 def_id,
561 container);
562
563 let fty = ccx.tcx.mk_fn_def(def_id, substs, ty_method.fty.clone());
564 debug!("method {} (id {}) has type {:?}",
565 name, id, fty);
566 ccx.tcx.register_item_type(def_id, TypeScheme {
567 generics: ty_method.generics.clone(),
568 ty: fty
569 });
570 ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
571
572 write_ty_to_tcx(ccx.tcx, id, fty);
573
574 debug!("writing method type: def_id={:?} mty={:?}",
575 def_id, ty_method);
576
577 ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
578 ty::MethodTraitItem(Rc::new(ty_method)));
579 }
580
581 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
582 struct_generics: &ty::Generics<'tcx>,
583 struct_predicates: &ty::GenericPredicates<'tcx>,
584 field: &hir::StructField,
585 ty_f: ty::FieldDefMaster<'tcx>)
586 {
587 let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty);
588 ty_f.fulfill_ty(tt);
589 write_ty_to_tcx(ccx.tcx, field.id, tt);
590
591 /* add the field to the tcache */
592 ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(field.id),
593 ty::TypeScheme {
594 generics: struct_generics.clone(),
595 ty: tt
596 });
597 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(field.id),
598 struct_predicates.clone());
599 }
600
601 fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
602 container: ImplOrTraitItemContainer,
603 name: ast::Name,
604 id: ast::NodeId,
605 vis: &hir::Visibility,
606 defaultness: hir::Defaultness,
607 ty: ty::Ty<'tcx>,
608 has_value: bool)
609 {
610 ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
611 ty::GenericPredicates::empty());
612
613 write_ty_to_tcx(ccx.tcx, id, ty);
614
615 let associated_const = Rc::new(ty::AssociatedConst {
616 name: name,
617 vis: ty::Visibility::from_hir(vis, id, ccx.tcx),
618 defaultness: defaultness,
619 def_id: ccx.tcx.map.local_def_id(id),
620 container: container,
621 ty: ty,
622 has_value: has_value
623 });
624 ccx.tcx.impl_or_trait_items.borrow_mut()
625 .insert(ccx.tcx.map.local_def_id(id), ty::ConstTraitItem(associated_const));
626 }
627
628 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
629 container: ImplOrTraitItemContainer,
630 name: ast::Name,
631 id: ast::NodeId,
632 vis: &hir::Visibility,
633 defaultness: hir::Defaultness,
634 ty: Option<Ty<'tcx>>)
635 {
636 let associated_type = Rc::new(ty::AssociatedType {
637 name: name,
638 vis: ty::Visibility::from_hir(vis, id, ccx.tcx),
639 defaultness: defaultness,
640 ty: ty,
641 def_id: ccx.tcx.map.local_def_id(id),
642 container: container
643 });
644 ccx.tcx.impl_or_trait_items.borrow_mut()
645 .insert(ccx.tcx.map.local_def_id(id), ty::TypeTraitItem(associated_type));
646 }
647
648 fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
649 span: Span,
650 generics: &hir::Generics,
651 thing: &'static str) {
652 let mut warn = false;
653
654 for ty_param in generics.ty_params.iter() {
655 for bound in ty_param.bounds.iter() {
656 match *bound {
657 hir::TraitTyParamBound(..) => {
658 warn = true;
659 }
660 hir::RegionTyParamBound(..) => { }
661 }
662 }
663 }
664
665 if warn {
666 // According to accepted RFC #XXX, we should
667 // eventually accept these, but it will not be
668 // part of this PR. Still, convert to warning to
669 // make bootstrapping easier.
670 span_warn!(ccx.tcx.sess, span, E0122,
671 "trait bounds are not (yet) enforced \
672 in {} definitions",
673 thing);
674 }
675 }
676
677 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
678 let tcx = ccx.tcx;
679 debug!("convert: item {} with id {}", it.name, it.id);
680 match it.node {
681 // These don't define types.
682 hir::ItemExternCrate(_) | hir::ItemUse(_) | hir::ItemMod(_) => {
683 }
684 hir::ItemForeignMod(ref foreign_mod) => {
685 for item in &foreign_mod.items {
686 convert_foreign_item(ccx, item);
687 }
688 }
689 hir::ItemEnum(ref enum_definition, _) => {
690 let (scheme, predicates) = convert_typed_item(ccx, it);
691 write_ty_to_tcx(tcx, it.id, scheme.ty);
692 convert_enum_variant_types(ccx,
693 tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
694 scheme,
695 predicates,
696 &enum_definition.variants);
697 },
698 hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
699 let trait_ref =
700 astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
701 &ExplicitRscope,
702 ast_trait_ref,
703 None);
704
705 tcx.record_trait_has_default_impl(trait_ref.def_id);
706
707 tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
708 Some(trait_ref));
709 }
710 hir::ItemImpl(_, _,
711 ref generics,
712 ref opt_trait_ref,
713 ref selfty,
714 ref impl_items) => {
715 // Create generics from the generics specified in the impl head.
716 debug!("convert: ast_generics={:?}", generics);
717 let def_id = ccx.tcx.map.local_def_id(it.id);
718 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
719 let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
720
721 debug!("convert: impl_bounds={:?}", ty_predicates);
722
723 let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &selfty);
724 write_ty_to_tcx(tcx, it.id, selfty);
725
726 tcx.register_item_type(def_id,
727 TypeScheme { generics: ty_generics.clone(),
728 ty: selfty });
729 let trait_ref = opt_trait_ref.as_ref().map(|ast_trait_ref| {
730 astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
731 &ExplicitRscope,
732 ast_trait_ref,
733 Some(selfty))
734 });
735 tcx.impl_trait_refs.borrow_mut().insert(def_id, trait_ref);
736
737 enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id);
738 tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
739
740
741 // Convert all the associated consts.
742 // Also, check if there are any duplicate associated items
743 let mut seen_type_items = FnvHashSet();
744 let mut seen_value_items = FnvHashSet();
745
746 for impl_item in impl_items {
747 let seen_items = match impl_item.node {
748 hir::ImplItemKind::Type(_) => &mut seen_type_items,
749 _ => &mut seen_value_items,
750 };
751 if !seen_items.insert(impl_item.name) {
752 coherence::report_duplicate_item(tcx, impl_item.span, impl_item.name).emit();
753 }
754
755 if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
756 let ty = ccx.icx(&ty_predicates)
757 .to_ty(&ExplicitRscope, &ty);
758 tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
759 TypeScheme {
760 generics: ty_generics.clone(),
761 ty: ty,
762 });
763 // Trait-associated constants are always public.
764 let public = &hir::Public;
765 let visibility = if opt_trait_ref.is_some() { public } else { &impl_item.vis };
766 convert_associated_const(ccx, ImplContainer(def_id),
767 impl_item.name, impl_item.id,
768 visibility,
769 impl_item.defaultness,
770 ty, true /* has_value */);
771 }
772 }
773
774 // Convert all the associated types.
775 for impl_item in impl_items {
776 if let hir::ImplItemKind::Type(ref ty) = impl_item.node {
777 if opt_trait_ref.is_none() {
778 span_err!(tcx.sess, impl_item.span, E0202,
779 "associated types are not allowed in inherent impls");
780 }
781
782 let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
783
784 convert_associated_type(ccx, ImplContainer(def_id),
785 impl_item.name, impl_item.id, &impl_item.vis,
786 impl_item.defaultness, Some(typ));
787 }
788 }
789
790 for impl_item in impl_items {
791 if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
792 // Trait methods are always public.
793 let public = &hir::Public;
794 let method_vis = if opt_trait_ref.is_some() { public } else { &impl_item.vis };
795
796 convert_method(ccx, ImplContainer(def_id),
797 impl_item.name, impl_item.id, method_vis,
798 sig, impl_item.defaultness, selfty, &ty_generics,
799 &ty_predicates);
800 }
801 }
802
803 enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
804 },
805 hir::ItemTrait(_, _, _, ref trait_items) => {
806 let trait_def = trait_def_of_item(ccx, it);
807 let def_id = trait_def.trait_ref.def_id;
808 let _: Result<(), ErrorReported> = // any error is already reported, can ignore
809 ccx.ensure_super_predicates(it.span, def_id);
810 convert_trait_predicates(ccx, it);
811 let trait_predicates = tcx.lookup_predicates(def_id);
812
813 debug!("convert: trait_bounds={:?}", trait_predicates);
814
815 // FIXME: is the ordering here important? I think it is.
816 let container = TraitContainer(def_id);
817
818 // Convert all the associated constants.
819 for trait_item in trait_items {
820 if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node {
821 let ty = ccx.icx(&trait_predicates)
822 .to_ty(&ExplicitRscope, ty);
823 tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
824 TypeScheme {
825 generics: trait_def.generics.clone(),
826 ty: ty,
827 });
828 convert_associated_const(ccx,
829 container,
830 trait_item.name,
831 trait_item.id,
832 &hir::Public,
833 hir::Defaultness::Default,
834 ty,
835 default.is_some())
836 }
837 }
838
839 // Convert all the associated types.
840 for trait_item in trait_items {
841 if let hir::TypeTraitItem(_, ref opt_ty) = trait_item.node {
842 let typ = opt_ty.as_ref().map({
843 |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
844 });
845
846 convert_associated_type(ccx,
847 container,
848 trait_item.name,
849 trait_item.id,
850 &hir::Public,
851 hir::Defaultness::Default,
852 typ);
853 }
854 }
855
856 // Convert all the methods
857 for trait_item in trait_items {
858 if let hir::MethodTraitItem(ref sig, _) = trait_item.node {
859 convert_method(ccx,
860 container,
861 trait_item.name,
862 trait_item.id,
863 &hir::Inherited,
864 sig,
865 hir::Defaultness::Default,
866 tcx.mk_self_type(),
867 &trait_def.generics,
868 &trait_predicates);
869
870 }
871 }
872
873 // Add an entry mapping
874 let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
875 let def_id = ccx.tcx.map.local_def_id(trait_item.id);
876 match trait_item.node {
877 hir::ConstTraitItem(..) => ty::ConstTraitItemId(def_id),
878 hir::MethodTraitItem(..) => ty::MethodTraitItemId(def_id),
879 hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id)
880 }
881 }).collect());
882 tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
883 trait_item_def_ids);
884 },
885 hir::ItemStruct(ref struct_def, _) => {
886 let (scheme, predicates) = convert_typed_item(ccx, it);
887 write_ty_to_tcx(tcx, it.id, scheme.ty);
888
889 let it_def_id = ccx.tcx.map.local_def_id(it.id);
890 let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
891
892 for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
893 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
894 }
895
896 if !struct_def.is_struct() {
897 convert_variant_ctor(ccx, struct_def.id(), variant, scheme, predicates);
898 }
899 },
900 hir::ItemTy(_, ref generics) => {
901 ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
902 let (scheme, _) = convert_typed_item(ccx, it);
903 write_ty_to_tcx(tcx, it.id, scheme.ty);
904 },
905 _ => {
906 // This call populates the type cache with the converted type
907 // of the item in passing. All we have to do here is to write
908 // it into the node type table.
909 let (scheme, _) = convert_typed_item(ccx, it);
910 write_ty_to_tcx(tcx, it.id, scheme.ty);
911 },
912 }
913 }
914
915 fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
916 ctor_id: ast::NodeId,
917 variant: ty::VariantDef<'tcx>,
918 scheme: ty::TypeScheme<'tcx>,
919 predicates: ty::GenericPredicates<'tcx>) {
920 let tcx = ccx.tcx;
921 let ctor_ty = match variant.kind() {
922 VariantKind::Unit | VariantKind::Struct => scheme.ty,
923 VariantKind::Tuple => {
924 let inputs: Vec<_> =
925 variant.fields
926 .iter()
927 .map(|field| field.unsubst_ty())
928 .collect();
929 let def_id = tcx.map.local_def_id(ctor_id);
930 let substs = tcx.mk_substs(mk_item_substs(ccx, &scheme.generics));
931 tcx.mk_fn_def(def_id, substs, ty::BareFnTy {
932 unsafety: hir::Unsafety::Normal,
933 abi: abi::Abi::Rust,
934 sig: ty::Binder(ty::FnSig {
935 inputs: inputs,
936 output: ty::FnConverging(scheme.ty),
937 variadic: false
938 })
939 })
940 }
941 };
942 write_ty_to_tcx(tcx, ctor_id, ctor_ty);
943 tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
944 tcx.register_item_type(tcx.map.local_def_id(ctor_id),
945 TypeScheme {
946 generics: scheme.generics,
947 ty: ctor_ty
948 });
949 }
950
951 fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
952 def: ty::AdtDefMaster<'tcx>,
953 scheme: ty::TypeScheme<'tcx>,
954 predicates: ty::GenericPredicates<'tcx>,
955 variants: &[hir::Variant]) {
956 // fill the field types
957 for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
958 for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) {
959 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
960 }
961
962 // Convert the ctor, if any. This also registers the variant as
963 // an item.
964 convert_variant_ctor(
965 ccx,
966 variant.node.data.id(),
967 ty_variant,
968 scheme.clone(),
969 predicates.clone()
970 );
971 }
972 }
973
974 fn convert_struct_variant<'tcx>(tcx: &TyCtxt<'tcx>,
975 did: DefId,
976 name: ast::Name,
977 disr_val: ty::Disr,
978 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
979 let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
980 let node_id = tcx.map.as_local_node_id(did).unwrap();
981 let fields = def.fields().iter().map(|f| {
982 let fid = tcx.map.local_def_id(f.id);
983 let dup_span = seen_fields.get(&f.name).cloned();
984 if let Some(prev_span) = dup_span {
985 let mut err = struct_span_err!(tcx.sess, f.span, E0124,
986 "field `{}` is already declared",
987 f.name);
988 span_note!(&mut err, prev_span, "previously declared here");
989 err.emit();
990 } else {
991 seen_fields.insert(f.name, f.span);
992 }
993
994 ty::FieldDefData::new(fid, f.name, ty::Visibility::from_hir(&f.vis, node_id, tcx))
995 }).collect();
996 ty::VariantDefData {
997 did: did,
998 name: name,
999 disr_val: disr_val,
1000 fields: fields,
1001 kind: VariantKind::from_variant_data(def),
1002 }
1003 }
1004
1005 fn convert_struct_def<'tcx>(tcx: &TyCtxt<'tcx>,
1006 it: &hir::Item,
1007 def: &hir::VariantData)
1008 -> ty::AdtDefMaster<'tcx>
1009 {
1010
1011 let did = tcx.map.local_def_id(it.id);
1012 let ctor_id = if !def.is_struct() {
1013 tcx.map.local_def_id(def.id())
1014 } else {
1015 did
1016 };
1017 tcx.intern_adt_def(
1018 did,
1019 ty::AdtKind::Struct,
1020 vec![convert_struct_variant(tcx, ctor_id, it.name, ConstInt::Infer(0), def)]
1021 )
1022 }
1023
1024 fn convert_enum_def<'tcx>(tcx: &TyCtxt<'tcx>,
1025 it: &hir::Item,
1026 def: &hir::EnumDef)
1027 -> ty::AdtDefMaster<'tcx>
1028 {
1029 fn print_err(tcx: &TyCtxt, span: Span, ty: ty::Ty, cv: ConstVal) {
1030 span_err!(tcx.sess, span, E0079, "mismatched types: expected `{}` got `{}`",
1031 ty, cv.description());
1032 }
1033 fn evaluate_disr_expr<'tcx>(tcx: &TyCtxt<'tcx>,
1034 repr_ty: attr::IntType,
1035 e: &hir::Expr) -> Option<ty::Disr> {
1036 debug!("disr expr, checking {}", pprust::expr_to_string(e));
1037
1038 let ty_hint = repr_ty.to_ty(tcx);
1039 let hint = UncheckedExprHint(ty_hint);
1040 match eval_const_expr_partial(tcx, e, hint, None) {
1041 Ok(ConstVal::Integral(i)) => {
1042 // FIXME: eval_const_expr_partial should return an error if the hint is wrong
1043 match (repr_ty, i) {
1044 (attr::SignedInt(ast::IntTy::I8), ConstInt::I8(_)) => Some(i),
1045 (attr::SignedInt(ast::IntTy::I16), ConstInt::I16(_)) => Some(i),
1046 (attr::SignedInt(ast::IntTy::I32), ConstInt::I32(_)) => Some(i),
1047 (attr::SignedInt(ast::IntTy::I64), ConstInt::I64(_)) => Some(i),
1048 (attr::SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) => Some(i),
1049 (attr::UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) => Some(i),
1050 (attr::UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) => Some(i),
1051 (attr::UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) => Some(i),
1052 (attr::UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) => Some(i),
1053 (attr::UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) => Some(i),
1054 (_, i) => {
1055 print_err(tcx, e.span, ty_hint, ConstVal::Integral(i));
1056 None
1057 },
1058 }
1059 },
1060 Ok(cv) => {
1061 print_err(tcx, e.span, ty_hint, cv);
1062 None
1063 },
1064 Err(err) => {
1065 let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
1066 "constant evaluation error: {}",
1067 err.description());
1068 if !e.span.contains(err.span) {
1069 diag.span_note(e.span, "for enum discriminant here");
1070 }
1071 diag.emit();
1072 None
1073 }
1074 }
1075 }
1076
1077 fn report_discrim_overflow(tcx: &TyCtxt,
1078 variant_span: Span,
1079 variant_name: &str,
1080 prev_val: ty::Disr) {
1081 span_err!(tcx.sess, variant_span, E0370,
1082 "enum discriminant overflowed on value after {}; \
1083 set explicitly via {} = {} if that is desired outcome",
1084 prev_val, variant_name, prev_val.wrap_incr());
1085 }
1086
1087 fn next_disr(tcx: &TyCtxt,
1088 v: &hir::Variant,
1089 repr_type: attr::IntType,
1090 prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
1091 if let Some(prev_disr_val) = prev_disr_val {
1092 let result = repr_type.disr_incr(prev_disr_val);
1093 if let None = result {
1094 report_discrim_overflow(tcx, v.span, &v.node.name.as_str(), prev_disr_val);
1095 }
1096 result
1097 } else {
1098 Some(repr_type.initial_discriminant(tcx))
1099 }
1100 }
1101 fn convert_enum_variant<'tcx>(tcx: &TyCtxt<'tcx>,
1102 v: &hir::Variant,
1103 disr: ty::Disr)
1104 -> ty::VariantDefData<'tcx, 'tcx>
1105 {
1106 let did = tcx.map.local_def_id(v.node.data.id());
1107 let name = v.node.name;
1108 convert_struct_variant(tcx, did, name, disr, &v.node.data)
1109 }
1110 let did = tcx.map.local_def_id(it.id);
1111 let repr_hints = tcx.lookup_repr_hints(did);
1112 let repr_type = tcx.enum_repr_type(repr_hints.get(0));
1113 let mut prev_disr = None;
1114 let variants = def.variants.iter().map(|v| {
1115 let disr = match v.node.disr_expr {
1116 Some(ref e) => evaluate_disr_expr(tcx, repr_type, e),
1117 None => next_disr(tcx, v, repr_type, prev_disr)
1118 }.unwrap_or_else(|| {
1119 prev_disr.map(ty::Disr::wrap_incr)
1120 .unwrap_or(repr_type.initial_discriminant(tcx))
1121 });
1122
1123 prev_disr = Some(disr);
1124 convert_enum_variant(tcx, v, disr)
1125 }).collect();
1126 tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
1127 }
1128
1129 /// Ensures that the super-predicates of the trait with def-id
1130 /// trait_def_id are converted and stored. This does NOT ensure that
1131 /// the transitive super-predicates are converted; that is the job of
1132 /// the `ensure_super_predicates()` method in the `AstConv` impl
1133 /// above. Returns a list of trait def-ids that must be ensured as
1134 /// well to guarantee that the transitive superpredicates are
1135 /// converted.
1136 fn ensure_super_predicates_step(ccx: &CrateCtxt,
1137 trait_def_id: DefId)
1138 -> Vec<DefId>
1139 {
1140 let tcx = ccx.tcx;
1141
1142 debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
1143
1144 let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
1145 n
1146 } else {
1147 // If this trait comes from an external crate, then all of the
1148 // supertraits it may depend on also must come from external
1149 // crates, and hence all of them already have their
1150 // super-predicates "converted" (and available from crate
1151 // meta-data), so there is no need to transitively test them.
1152 return Vec::new();
1153 };
1154
1155 let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
1156 let superpredicates = superpredicates.unwrap_or_else(|| {
1157 let item = match ccx.tcx.map.get(trait_node_id) {
1158 hir_map::NodeItem(item) => item,
1159 _ => bug!("trait_node_id {} is not an item", trait_node_id)
1160 };
1161
1162 let (generics, bounds) = match item.node {
1163 hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
1164 _ => span_bug!(item.span,
1165 "ensure_super_predicates_step invoked on non-trait"),
1166 };
1167
1168 // In-scope when converting the superbounds for `Trait` are
1169 // that `Self:Trait` as well as any bounds that appear on the
1170 // generic types:
1171 let trait_def = trait_def_of_item(ccx, item);
1172 let self_predicate = ty::GenericPredicates {
1173 predicates: VecPerParamSpace::new(vec![],
1174 vec![trait_def.trait_ref.to_predicate()],
1175 vec![])
1176 };
1177 let scope = &(generics, &self_predicate);
1178
1179 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1180 let self_param_ty = tcx.mk_self_type();
1181 let superbounds1 = compute_bounds(&ccx.icx(scope),
1182 self_param_ty,
1183 bounds,
1184 SizedByDefault::No,
1185 item.span);
1186
1187 let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
1188
1189 // Convert any explicit superbounds in the where clause,
1190 // e.g. `trait Foo where Self : Bar`:
1191 let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
1192
1193 // Combine the two lists to form the complete set of superbounds:
1194 let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
1195 let superpredicates = ty::GenericPredicates {
1196 predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
1197 };
1198 debug!("superpredicates for trait {:?} = {:?}",
1199 tcx.map.local_def_id(item.id),
1200 superpredicates);
1201
1202 tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
1203
1204 superpredicates
1205 });
1206
1207 let def_ids: Vec<_> = superpredicates.predicates
1208 .iter()
1209 .filter_map(|p| p.to_opt_poly_trait_ref())
1210 .map(|tr| tr.def_id())
1211 .collect();
1212
1213 debug!("ensure_super_predicates_step: def_ids={:?}", def_ids);
1214
1215 def_ids
1216 }
1217
1218 fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1219 it: &hir::Item)
1220 -> &'tcx ty::TraitDef<'tcx>
1221 {
1222 let def_id = ccx.tcx.map.local_def_id(it.id);
1223 let tcx = ccx.tcx;
1224
1225 if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
1226 return def.clone();
1227 }
1228
1229 let (unsafety, generics, items) = match it.node {
1230 hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
1231 _ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
1232 };
1233
1234 let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
1235 if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
1236 let mut err = ccx.tcx.sess.struct_span_err(
1237 it.span,
1238 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1239 which traits can use parenthetical notation");
1240 fileline_help!(&mut err, it.span,
1241 "add `#![feature(unboxed_closures)]` to \
1242 the crate attributes to use it");
1243 err.emit();
1244 }
1245
1246 let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
1247
1248 let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
1249
1250 let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
1251 match trait_item.node {
1252 hir::TypeTraitItem(..) => Some(trait_item.name),
1253 _ => None,
1254 }
1255 }).collect();
1256
1257 let trait_ref = ty::TraitRef {
1258 def_id: def_id,
1259 substs: substs,
1260 };
1261
1262 let trait_def = ty::TraitDef::new(unsafety,
1263 paren_sugar,
1264 ty_generics,
1265 trait_ref,
1266 associated_type_names);
1267
1268 return tcx.intern_trait_def(trait_def);
1269
1270 fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1271 generics: &hir::Generics)
1272 -> Substs<'tcx>
1273 {
1274 let tcx = ccx.tcx;
1275
1276 // Creates a no-op substitution for the trait's type parameters.
1277 let regions =
1278 generics.lifetimes
1279 .iter()
1280 .enumerate()
1281 .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
1282 space: TypeSpace,
1283 index: i as u32,
1284 name: def.lifetime.name
1285 }))
1286 .collect();
1287
1288 // Start with the generics in the type parameters...
1289 let types: Vec<_> =
1290 generics.ty_params
1291 .iter()
1292 .enumerate()
1293 .map(|(i, def)| tcx.mk_param(TypeSpace,
1294 i as u32, def.name))
1295 .collect();
1296
1297 // ...and also create the `Self` parameter.
1298 let self_ty = tcx.mk_self_type();
1299
1300 Substs::new_trait(types, regions, self_ty)
1301 }
1302 }
1303
1304 fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1305 trait_node_id: ast::NodeId,
1306 assoc_name: ast::Name)
1307 -> bool
1308 {
1309 let item = match ccx.tcx.map.get(trait_node_id) {
1310 hir_map::NodeItem(item) => item,
1311 _ => bug!("trait_node_id {} is not an item", trait_node_id)
1312 };
1313
1314 let trait_items = match item.node {
1315 hir::ItemTrait(_, _, _, ref trait_items) => trait_items,
1316 _ => bug!("trait_node_id {} is not a trait", trait_node_id)
1317 };
1318
1319 trait_items.iter().any(|trait_item| {
1320 match trait_item.node {
1321 hir::TypeTraitItem(..) => trait_item.name == assoc_name,
1322 _ => false,
1323 }
1324 })
1325 }
1326
1327 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
1328 let tcx = ccx.tcx;
1329 let trait_def = trait_def_of_item(ccx, it);
1330
1331 let def_id = ccx.tcx.map.local_def_id(it.id);
1332
1333 let (generics, items) = match it.node {
1334 hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
1335 ref s => {
1336 span_bug!(
1337 it.span,
1338 "trait_def_of_item invoked on {:?}",
1339 s);
1340 }
1341 };
1342
1343 let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
1344
1345 // `ty_generic_predicates` below will consider the bounds on the type
1346 // parameters (including `Self`) and the explicit where-clauses,
1347 // but to get the full set of predicates on a trait we need to add
1348 // in the supertrait bounds and anything declared on the
1349 // associated types.
1350 let mut base_predicates = super_predicates;
1351
1352 // Add in a predicate that `Self:Trait` (where `Trait` is the
1353 // current trait). This is needed for builtin bounds.
1354 let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
1355 base_predicates.predicates.push(SelfSpace, self_predicate);
1356
1357 // add in the explicit where-clauses
1358 let mut trait_predicates =
1359 ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
1360
1361 let assoc_predicates = predicates_for_associated_types(ccx,
1362 generics,
1363 &trait_predicates,
1364 trait_def.trait_ref,
1365 items);
1366 trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
1367
1368 let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
1369 assert!(prev_predicates.is_none());
1370
1371 return;
1372
1373 fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1374 ast_generics: &hir::Generics,
1375 trait_predicates: &ty::GenericPredicates<'tcx>,
1376 self_trait_ref: ty::TraitRef<'tcx>,
1377 trait_items: &[hir::TraitItem])
1378 -> Vec<ty::Predicate<'tcx>>
1379 {
1380 trait_items.iter().flat_map(|trait_item| {
1381 let bounds = match trait_item.node {
1382 hir::TypeTraitItem(ref bounds, _) => bounds,
1383 _ => {
1384 return vec!().into_iter();
1385 }
1386 };
1387
1388 let assoc_ty = ccx.tcx.mk_projection(self_trait_ref,
1389 trait_item.name);
1390
1391 let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
1392 assoc_ty,
1393 bounds,
1394 SizedByDefault::Yes,
1395 trait_item.span);
1396
1397 bounds.predicates(ccx.tcx, assoc_ty).into_iter()
1398 }).collect()
1399 }
1400 }
1401
1402 fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1403 def_id: DefId)
1404 -> ty::TypeScheme<'tcx>
1405 {
1406 if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
1407 match ccx.tcx.map.find(node_id) {
1408 Some(hir_map::NodeItem(item)) => {
1409 type_scheme_of_item(ccx, &item)
1410 }
1411 Some(hir_map::NodeForeignItem(foreign_item)) => {
1412 let abi = ccx.tcx.map.get_foreign_abi(node_id);
1413 type_scheme_of_foreign_item(ccx, &foreign_item, abi)
1414 }
1415 x => {
1416 bug!("unexpected sort of node in get_item_type_scheme(): {:?}",
1417 x);
1418 }
1419 }
1420 } else {
1421 ccx.tcx.lookup_item_type(def_id)
1422 }
1423 }
1424
1425 fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1426 item: &hir::Item)
1427 -> ty::TypeScheme<'tcx>
1428 {
1429 let item_def_id = ccx.tcx.map.local_def_id(item.id);
1430 ccx.tcx.tcache.memoize(item_def_id, || {
1431 // NB. Since the `memoized` function enters a new task, and we
1432 // are giving this task access to the item `item`, we must
1433 // register a read.
1434 ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
1435 compute_type_scheme_of_item(ccx, item)
1436 })
1437 }
1438
1439 fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1440 it: &hir::Item)
1441 -> ty::TypeScheme<'tcx>
1442 {
1443 let tcx = ccx.tcx;
1444 match it.node {
1445 hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
1446 let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &t);
1447 ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1448 }
1449 hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1450 let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
1451 let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl);
1452 let def_id = ccx.tcx.map.local_def_id(it.id);
1453 let substs = tcx.mk_substs(mk_item_substs(ccx, &ty_generics));
1454 let ty = tcx.mk_fn_def(def_id, substs, tofd);
1455 ty::TypeScheme { ty: ty, generics: ty_generics }
1456 }
1457 hir::ItemTy(ref t, ref generics) => {
1458 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1459 let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &t);
1460 ty::TypeScheme { ty: ty, generics: ty_generics }
1461 }
1462 hir::ItemEnum(ref ei, ref generics) => {
1463 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1464 let substs = mk_item_substs(ccx, &ty_generics);
1465 let def = convert_enum_def(tcx, it, ei);
1466 let t = tcx.mk_enum(def, tcx.mk_substs(substs));
1467 ty::TypeScheme { ty: t, generics: ty_generics }
1468 }
1469 hir::ItemStruct(ref si, ref generics) => {
1470 let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
1471 let substs = mk_item_substs(ccx, &ty_generics);
1472 let def = convert_struct_def(tcx, it, si);
1473 let t = tcx.mk_struct(def, tcx.mk_substs(substs));
1474 ty::TypeScheme { ty: t, generics: ty_generics }
1475 }
1476 hir::ItemDefaultImpl(..) |
1477 hir::ItemTrait(..) |
1478 hir::ItemImpl(..) |
1479 hir::ItemMod(..) |
1480 hir::ItemForeignMod(..) |
1481 hir::ItemExternCrate(..) |
1482 hir::ItemUse(..) => {
1483 span_bug!(
1484 it.span,
1485 "compute_type_scheme_of_item: unexpected item type: {:?}",
1486 it.node);
1487 }
1488 }
1489 }
1490
1491 fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1492 it: &hir::Item)
1493 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
1494 {
1495 let tcx = ccx.tcx;
1496
1497 let tag = type_scheme_of_item(ccx, it);
1498 let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
1499 let predicates = match it.node {
1500 hir::ItemStatic(..) | hir::ItemConst(..) => {
1501 ty::GenericPredicates::empty()
1502 }
1503 hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
1504 ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
1505 }
1506 hir::ItemTy(_, ref generics) => {
1507 ty_generic_predicates_for_type_or_impl(ccx, generics)
1508 }
1509 hir::ItemEnum(_, ref generics) => {
1510 ty_generic_predicates_for_type_or_impl(ccx, generics)
1511 }
1512 hir::ItemStruct(_, ref generics) => {
1513 ty_generic_predicates_for_type_or_impl(ccx, generics)
1514 }
1515 hir::ItemDefaultImpl(..) |
1516 hir::ItemTrait(..) |
1517 hir::ItemExternCrate(..) |
1518 hir::ItemUse(..) |
1519 hir::ItemImpl(..) |
1520 hir::ItemMod(..) |
1521 hir::ItemForeignMod(..) => {
1522 span_bug!(
1523 it.span,
1524 "compute_type_scheme_of_item: unexpected item type: {:?}",
1525 it.node);
1526 }
1527 };
1528
1529 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1530 predicates.clone());
1531 assert!(prev_predicates.is_none());
1532
1533 // Debugging aid.
1534 if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
1535 let object_lifetime_default_reprs: String =
1536 scheme.generics.types.iter()
1537 .map(|t| match t.object_lifetime_default {
1538 ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
1539 d => format!("{:?}", d),
1540 })
1541 .collect::<Vec<String>>()
1542 .join(",");
1543
1544 tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
1545 }
1546
1547 return (scheme, predicates);
1548 }
1549
1550 fn type_scheme_of_foreign_item<'a, 'tcx>(
1551 ccx: &CrateCtxt<'a, 'tcx>,
1552 item: &hir::ForeignItem,
1553 abi: abi::Abi)
1554 -> ty::TypeScheme<'tcx>
1555 {
1556 let item_def_id = ccx.tcx.map.local_def_id(item.id);
1557 ccx.tcx.tcache.memoize(item_def_id, || {
1558 // NB. Since the `memoized` function enters a new task, and we
1559 // are giving this task access to the item `item`, we must
1560 // register a read.
1561 ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
1562 compute_type_scheme_of_foreign_item(ccx, item, abi)
1563 })
1564 }
1565
1566 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
1567 ccx: &CrateCtxt<'a, 'tcx>,
1568 it: &hir::ForeignItem,
1569 abi: abi::Abi)
1570 -> ty::TypeScheme<'tcx>
1571 {
1572 match it.node {
1573 hir::ForeignItemFn(ref fn_decl, ref generics) => {
1574 compute_type_scheme_of_foreign_fn_decl(
1575 ccx, ccx.tcx.map.local_def_id(it.id),
1576 fn_decl, generics, abi)
1577 }
1578 hir::ForeignItemStatic(ref t, _) => {
1579 ty::TypeScheme {
1580 generics: ty::Generics::empty(),
1581 ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
1582 }
1583 }
1584 }
1585 }
1586
1587 fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1588 it: &hir::ForeignItem)
1589 {
1590 // For reasons I cannot fully articulate, I do so hate the AST
1591 // map, and I regard each time that I use it as a personal and
1592 // moral failing, but at the moment it seems like the only
1593 // convenient way to extract the ABI. - ndm
1594 let tcx = ccx.tcx;
1595 let abi = tcx.map.get_foreign_abi(it.id);
1596
1597 let scheme = type_scheme_of_foreign_item(ccx, it, abi);
1598 write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
1599
1600 let predicates = match it.node {
1601 hir::ForeignItemFn(_, ref generics) => {
1602 ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
1603 }
1604 hir::ForeignItemStatic(..) => {
1605 ty::GenericPredicates::empty()
1606 }
1607 };
1608
1609 let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
1610 predicates);
1611 assert!(prev_predicates.is_none());
1612 }
1613
1614 fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1615 generics: &hir::Generics)
1616 -> ty::Generics<'tcx> {
1617 ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
1618 }
1619
1620 fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1621 generics: &hir::Generics)
1622 -> ty::GenericPredicates<'tcx>
1623 {
1624 ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
1625 }
1626
1627 fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1628 trait_id: ast::NodeId,
1629 substs: &'tcx Substs<'tcx>,
1630 ast_generics: &hir::Generics)
1631 -> ty::Generics<'tcx>
1632 {
1633 debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1634 ccx.tcx.map.local_def_id(trait_id), substs);
1635
1636 let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
1637
1638 // Add in the self type parameter.
1639 //
1640 // Something of a hack: use the node id for the trait, also as
1641 // the node id for the Self type parameter.
1642 let param_id = trait_id;
1643
1644 let parent = ccx.tcx.map.get_parent(param_id);
1645
1646 let def = ty::TypeParameterDef {
1647 space: SelfSpace,
1648 index: 0,
1649 name: special_idents::type_self.name,
1650 def_id: ccx.tcx.map.local_def_id(param_id),
1651 default_def_id: ccx.tcx.map.local_def_id(parent),
1652 default: None,
1653 object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
1654 };
1655
1656 ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
1657
1658 generics.types.push(SelfSpace, def);
1659
1660 return generics;
1661 }
1662
1663 fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1664 generics: &hir::Generics,
1665 base_generics: &ty::Generics<'tcx>)
1666 -> ty::Generics<'tcx>
1667 {
1668 ty_generics(ccx, FnSpace, generics, base_generics)
1669 }
1670
1671 fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1672 generics: &hir::Generics,
1673 base_predicates: &ty::GenericPredicates<'tcx>)
1674 -> ty::GenericPredicates<'tcx>
1675 {
1676 ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
1677 }
1678
1679 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1680 fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
1681 bounds: &mut ty::BuiltinBounds,
1682 ast_bounds: &[hir::TyParamBound],
1683 span: Span)
1684 {
1685 let tcx = astconv.tcx();
1686
1687 // Try to find an unbound in bounds.
1688 let mut unbound = None;
1689 for ab in ast_bounds {
1690 if let &hir::TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
1691 if unbound.is_none() {
1692 assert!(ptr.bound_lifetimes.is_empty());
1693 unbound = Some(ptr.trait_ref.clone());
1694 } else {
1695 span_err!(tcx.sess, span, E0203,
1696 "type parameter has more than one relaxed default \
1697 bound, only one is supported");
1698 }
1699 }
1700 }
1701
1702 let kind_id = tcx.lang_items.require(SizedTraitLangItem);
1703 match unbound {
1704 Some(ref tpb) => {
1705 // FIXME(#8559) currently requires the unbound to be built-in.
1706 let trait_def_id = tcx.trait_ref_to_def_id(tpb);
1707 match kind_id {
1708 Ok(kind_id) if trait_def_id != kind_id => {
1709 tcx.sess.span_warn(span,
1710 "default bound relaxed for a type parameter, but \
1711 this does nothing because the given bound is not \
1712 a default. Only `?Sized` is supported");
1713 tcx.try_add_builtin_trait(kind_id, bounds);
1714 }
1715 _ => {}
1716 }
1717 }
1718 _ if kind_id.is_ok() => {
1719 tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
1720 }
1721 // No lang item for Sized, so we can't add it as a bound.
1722 None => {}
1723 }
1724 }
1725
1726 /// Returns the early-bound lifetimes declared in this generics
1727 /// listing. For anything other than fns/methods, this is just all
1728 /// the lifetimes that are declared. For fns or methods, we have to
1729 /// screen out those that do not appear in any where-clauses etc using
1730 /// `resolve_lifetime::early_bound_lifetimes`.
1731 fn early_bound_lifetimes_from_generics(space: ParamSpace,
1732 ast_generics: &hir::Generics)
1733 -> Vec<hir::LifetimeDef>
1734 {
1735 match space {
1736 SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
1737 FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
1738 }
1739 }
1740
1741 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1742 space: ParamSpace,
1743 ast_generics: &hir::Generics,
1744 base_predicates: &ty::GenericPredicates<'tcx>)
1745 -> ty::GenericPredicates<'tcx>
1746 {
1747 let tcx = ccx.tcx;
1748 let mut result = base_predicates.clone();
1749
1750 // Collect the predicates that were written inline by the user on each
1751 // type parameter (e.g., `<T:Foo>`).
1752 for (index, param) in ast_generics.ty_params.iter().enumerate() {
1753 let index = index as u32;
1754 let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
1755 let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
1756 param_ty,
1757 &param.bounds,
1758 SizedByDefault::Yes,
1759 param.span);
1760 let predicates = bounds.predicates(ccx.tcx, param_ty);
1761 result.predicates.extend(space, predicates.into_iter());
1762 }
1763
1764 // Collect the region predicates that were declared inline as
1765 // well. In the case of parameters declared on a fn or method, we
1766 // have to be careful to only iterate over early-bound regions.
1767 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1768 for (index, param) in early_lifetimes.iter().enumerate() {
1769 let index = index as u32;
1770 let region =
1771 ty::ReEarlyBound(ty::EarlyBoundRegion {
1772 space: space,
1773 index: index,
1774 name: param.lifetime.name
1775 });
1776 for bound in &param.bounds {
1777 let bound_region = ast_region_to_region(ccx.tcx, bound);
1778 let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
1779 result.predicates.push(space, outlives.to_predicate());
1780 }
1781 }
1782
1783 // Add in the bounds that appear in the where-clause
1784 let where_clause = &ast_generics.where_clause;
1785 for predicate in &where_clause.predicates {
1786 match predicate {
1787 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
1788 let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
1789 &ExplicitRscope,
1790 &bound_pred.bounded_ty);
1791
1792 for bound in bound_pred.bounds.iter() {
1793 match bound {
1794 &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
1795 let mut projections = Vec::new();
1796
1797 let trait_ref =
1798 conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
1799 ty,
1800 poly_trait_ref,
1801 &mut projections);
1802
1803 result.predicates.push(space, trait_ref.to_predicate());
1804
1805 for projection in &projections {
1806 result.predicates.push(space, projection.to_predicate());
1807 }
1808 }
1809
1810 &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
1811 let region = ast_region_to_region(tcx, lifetime);
1812 let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1813 result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1814 }
1815 }
1816 }
1817 }
1818
1819 &hir::WherePredicate::RegionPredicate(ref region_pred) => {
1820 let r1 = ast_region_to_region(tcx, &region_pred.lifetime);
1821 for bound in &region_pred.bounds {
1822 let r2 = ast_region_to_region(tcx, bound);
1823 let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1824 result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1825 }
1826 }
1827
1828 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1829 // FIXME(#20041)
1830 span_bug!(eq_pred.span,
1831 "Equality constraints are not yet \
1832 implemented (#20041)")
1833 }
1834 }
1835 }
1836
1837 return result;
1838 }
1839
1840 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1841 space: ParamSpace,
1842 ast_generics: &hir::Generics,
1843 base_generics: &ty::Generics<'tcx>)
1844 -> ty::Generics<'tcx>
1845 {
1846 let tcx = ccx.tcx;
1847 let mut result = base_generics.clone();
1848
1849 let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
1850 for (i, l) in early_lifetimes.iter().enumerate() {
1851 let bounds = l.bounds.iter()
1852 .map(|l| ast_region_to_region(tcx, l))
1853 .collect();
1854 let def = ty::RegionParameterDef { name: l.lifetime.name,
1855 space: space,
1856 index: i as u32,
1857 def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
1858 bounds: bounds };
1859 result.regions.push(space, def);
1860 }
1861
1862 assert!(result.types.is_empty_in(space));
1863
1864 // Now create the real type parameters.
1865 for i in 0..ast_generics.ty_params.len() {
1866 let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
1867 debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
1868 result.types.push(space, def);
1869 }
1870
1871 result
1872 }
1873
1874 fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1875 path: &P<hir::Ty>,
1876 space: ParamSpace,
1877 index: u32)
1878 -> Ty<'tcx>
1879 {
1880 let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
1881
1882 for leaf_ty in ty.walk() {
1883 if let ty::TyParam(p) = leaf_ty.sty {
1884 if p.space == space && p.idx >= index {
1885 span_err!(ccx.tcx.sess, path.span, E0128,
1886 "type parameters with a default cannot use \
1887 forward declared identifiers");
1888
1889 return ccx.tcx.types.err
1890 }
1891 }
1892 }
1893
1894 ty
1895 }
1896
1897 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1898 ast_generics: &hir::Generics,
1899 space: ParamSpace,
1900 index: u32)
1901 -> ty::TypeParameterDef<'tcx>
1902 {
1903 let param = &ast_generics.ty_params[index as usize];
1904
1905 let tcx = ccx.tcx;
1906 match tcx.ty_param_defs.borrow().get(&param.id) {
1907 Some(d) => { return d.clone(); }
1908 None => { }
1909 }
1910
1911 let default = param.default.as_ref().map(
1912 |def| convert_default_type_parameter(ccx, def, space, index)
1913 );
1914
1915 let object_lifetime_default =
1916 compute_object_lifetime_default(ccx, param.id,
1917 &param.bounds, &ast_generics.where_clause);
1918
1919 let parent = tcx.map.get_parent(param.id);
1920
1921 if space != TypeSpace && default.is_some() {
1922 if !tcx.sess.features.borrow().default_type_parameter_fallback {
1923 tcx.sess.add_lint(
1924 lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
1925 param.id,
1926 param.span,
1927 format!("defaults for type parameters are only allowed in `struct`, \
1928 `enum`, `type`, or `trait` definitions."));
1929 }
1930 }
1931
1932 let def = ty::TypeParameterDef {
1933 space: space,
1934 index: index,
1935 name: param.name,
1936 def_id: ccx.tcx.map.local_def_id(param.id),
1937 default_def_id: ccx.tcx.map.local_def_id(parent),
1938 default: default,
1939 object_lifetime_default: object_lifetime_default,
1940 };
1941
1942 tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
1943
1944 def
1945 }
1946
1947 /// Scan the bounds and where-clauses on a parameter to extract bounds
1948 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
1949 /// This runs as part of computing the minimal type scheme, so we
1950 /// intentionally avoid just asking astconv to convert all the where
1951 /// clauses into a `ty::Predicate`. This is because that could induce
1952 /// artificial cycles.
1953 fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1954 param_id: ast::NodeId,
1955 param_bounds: &[hir::TyParamBound],
1956 where_clause: &hir::WhereClause)
1957 -> ty::ObjectLifetimeDefault
1958 {
1959 let inline_bounds = from_bounds(ccx, param_bounds);
1960 let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
1961 let all_bounds: HashSet<_> = inline_bounds.into_iter()
1962 .chain(where_bounds)
1963 .collect();
1964 return if all_bounds.len() > 1 {
1965 ty::ObjectLifetimeDefault::Ambiguous
1966 } else if all_bounds.len() == 0 {
1967 ty::ObjectLifetimeDefault::BaseDefault
1968 } else {
1969 ty::ObjectLifetimeDefault::Specific(
1970 all_bounds.into_iter().next().unwrap())
1971 };
1972
1973 fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1974 bounds: &[hir::TyParamBound])
1975 -> Vec<ty::Region>
1976 {
1977 bounds.iter()
1978 .filter_map(|bound| {
1979 match *bound {
1980 hir::TraitTyParamBound(..) =>
1981 None,
1982 hir::RegionTyParamBound(ref lifetime) =>
1983 Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
1984 }
1985 })
1986 .collect()
1987 }
1988
1989 fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1990 param_id: ast::NodeId,
1991 predicates: &[hir::WherePredicate])
1992 -> Vec<ty::Region>
1993 {
1994 predicates.iter()
1995 .flat_map(|predicate| {
1996 match *predicate {
1997 hir::WherePredicate::BoundPredicate(ref data) => {
1998 if data.bound_lifetimes.is_empty() &&
1999 is_param(ccx.tcx, &data.bounded_ty, param_id)
2000 {
2001 from_bounds(ccx, &data.bounds).into_iter()
2002 } else {
2003 Vec::new().into_iter()
2004 }
2005 }
2006 hir::WherePredicate::RegionPredicate(..) |
2007 hir::WherePredicate::EqPredicate(..) => {
2008 Vec::new().into_iter()
2009 }
2010 }
2011 })
2012 .collect()
2013 }
2014 }
2015
2016 enum SizedByDefault { Yes, No, }
2017
2018 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2019 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2020 /// built-in trait (formerly known as kind): Send.
2021 fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
2022 param_ty: ty::Ty<'tcx>,
2023 ast_bounds: &[hir::TyParamBound],
2024 sized_by_default: SizedByDefault,
2025 span: Span)
2026 -> astconv::Bounds<'tcx>
2027 {
2028 let mut bounds =
2029 conv_param_bounds(astconv,
2030 span,
2031 param_ty,
2032 ast_bounds);
2033
2034 if let SizedByDefault::Yes = sized_by_default {
2035 add_unsized_bound(astconv,
2036 &mut bounds.builtin_bounds,
2037 ast_bounds,
2038 span);
2039 }
2040
2041 bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
2042
2043 bounds
2044 }
2045
2046 /// Converts a specific TyParamBound from the AST into a set of
2047 /// predicates that apply to the self-type. A vector is returned
2048 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2049 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2050 /// and `<T as Bar>::X == i32`).
2051 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
2052 param_ty: Ty<'tcx>,
2053 bound: &hir::TyParamBound)
2054 -> Vec<ty::Predicate<'tcx>>
2055 {
2056 match *bound {
2057 hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => {
2058 let mut projections = Vec::new();
2059 let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
2060 projections.into_iter()
2061 .map(|p| p.to_predicate())
2062 .chain(Some(pred.to_predicate()))
2063 .collect()
2064 }
2065 hir::RegionTyParamBound(ref lifetime) => {
2066 let region = ast_region_to_region(astconv.tcx(), lifetime);
2067 let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
2068 vec![ty::Predicate::TypeOutlives(pred)]
2069 }
2070 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {
2071 Vec::new()
2072 }
2073 }
2074 }
2075
2076 fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
2077 param_ty: Ty<'tcx>,
2078 trait_ref: &hir::PolyTraitRef,
2079 projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
2080 -> ty::PolyTraitRef<'tcx>
2081 {
2082 astconv::instantiate_poly_trait_ref(astconv,
2083 &ExplicitRscope,
2084 trait_ref,
2085 Some(param_ty),
2086 projections)
2087 }
2088
2089 fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
2090 span: Span,
2091 param_ty: ty::Ty<'tcx>,
2092 ast_bounds: &[hir::TyParamBound])
2093 -> astconv::Bounds<'tcx>
2094 {
2095 let tcx = astconv.tcx();
2096 let astconv::PartitionedBounds {
2097 builtin_bounds,
2098 trait_bounds,
2099 region_bounds
2100 } = astconv::partition_bounds(tcx, span, &ast_bounds);
2101
2102 let mut projection_bounds = Vec::new();
2103
2104 let trait_bounds: Vec<ty::PolyTraitRef> =
2105 trait_bounds.iter()
2106 .map(|bound| conv_poly_trait_ref(astconv,
2107 param_ty,
2108 *bound,
2109 &mut projection_bounds))
2110 .collect();
2111
2112 let region_bounds: Vec<ty::Region> =
2113 region_bounds.into_iter()
2114 .map(|r| ast_region_to_region(tcx, r))
2115 .collect();
2116
2117 astconv::Bounds {
2118 region_bounds: region_bounds,
2119 builtin_bounds: builtin_bounds,
2120 trait_bounds: trait_bounds,
2121 projection_bounds: projection_bounds,
2122 }
2123 }
2124
2125 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
2126 ccx: &CrateCtxt<'a, 'tcx>,
2127 id: DefId,
2128 decl: &hir::FnDecl,
2129 ast_generics: &hir::Generics,
2130 abi: abi::Abi)
2131 -> ty::TypeScheme<'tcx>
2132 {
2133 for i in &decl.inputs {
2134 match i.pat.node {
2135 PatKind::Ident(_, _, _) => (),
2136 PatKind::Wild => (),
2137 _ => {
2138 span_err!(ccx.tcx.sess, i.pat.span, E0130,
2139 "patterns aren't allowed in foreign function declarations");
2140 }
2141 }
2142 }
2143
2144 let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
2145
2146 let rb = BindingRscope::new();
2147 let input_tys = decl.inputs
2148 .iter()
2149 .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
2150 .collect::<Vec<_>>();
2151
2152 let output = match decl.output {
2153 hir::Return(ref ty) =>
2154 ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &ty)),
2155 hir::DefaultReturn(..) =>
2156 ty::FnConverging(ccx.tcx.mk_nil()),
2157 hir::NoReturn(..) =>
2158 ty::FnDiverging
2159 };
2160
2161 // feature gate SIMD types in FFI, since I (huonw) am not sure the
2162 // ABIs are handled at all correctly.
2163 if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic
2164 && !ccx.tcx.sess.features.borrow().simd_ffi {
2165 let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
2166 if ty.is_simd() {
2167 ccx.tcx.sess.struct_span_err(ast_ty.span,
2168 &format!("use of SIMD type `{}` in FFI is highly experimental and \
2169 may result in invalid code",
2170 pprust::ty_to_string(ast_ty)))
2171 .fileline_help(ast_ty.span,
2172 "add #![feature(simd_ffi)] to the crate attributes to enable")
2173 .emit();
2174 }
2175 };
2176 for (input, ty) in decl.inputs.iter().zip(&input_tys) {
2177 check(&input.ty, ty)
2178 }
2179 if let hir::Return(ref ty) = decl.output {
2180 check(&ty, output.unwrap())
2181 }
2182 }
2183
2184 let substs = ccx.tcx.mk_substs(mk_item_substs(ccx, &ty_generics));
2185 let t_fn = ccx.tcx.mk_fn_def(id, substs, ty::BareFnTy {
2186 abi: abi,
2187 unsafety: hir::Unsafety::Unsafe,
2188 sig: ty::Binder(ty::FnSig {inputs: input_tys,
2189 output: output,
2190 variadic: decl.variadic}),
2191 });
2192
2193 ty::TypeScheme {
2194 generics: ty_generics,
2195 ty: t_fn
2196 }
2197 }
2198
2199 fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
2200 ty_generics: &ty::Generics<'tcx>)
2201 -> Substs<'tcx>
2202 {
2203 let types =
2204 ty_generics.types.map(
2205 |def| ccx.tcx.mk_param_from_def(def));
2206
2207 let regions =
2208 ty_generics.regions.map(
2209 |def| def.to_early_bound_region());
2210
2211 Substs::new(types, regions)
2212 }
2213
2214 /// Checks that all the type parameters on an impl
2215 fn enforce_impl_params_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
2216 ast_generics: &hir::Generics,
2217 impl_predicates: &mut ty::GenericPredicates<'tcx>,
2218 impl_def_id: DefId)
2219 {
2220 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2221 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2222
2223 assert!(impl_predicates.predicates.is_empty_in(FnSpace));
2224 assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
2225
2226 // The trait reference is an input, so find all type parameters
2227 // reachable from there, to start (if this is an inherent impl,
2228 // then just examine the self type).
2229 let mut input_parameters: HashSet<_> =
2230 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2231 if let Some(ref trait_ref) = impl_trait_ref {
2232 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2233 }
2234
2235 ctp::setup_constraining_predicates(tcx,
2236 impl_predicates.predicates.get_mut_slice(TypeSpace),
2237 impl_trait_ref,
2238 &mut input_parameters);
2239
2240 for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
2241 let param_ty = ty::ParamTy { space: TypeSpace,
2242 idx: index as u32,
2243 name: ty_param.name };
2244 if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2245 report_unused_parameter(tcx, ty_param.span, "type", &param_ty.to_string());
2246 }
2247 }
2248 }
2249
2250 fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
2251 ast_generics: &hir::Generics,
2252 impl_def_id: DefId,
2253 impl_items: &[hir::ImplItem])
2254 {
2255 // Every lifetime used in an associated type must be constrained.
2256 let impl_scheme = tcx.lookup_item_type(impl_def_id);
2257 let impl_predicates = tcx.lookup_predicates(impl_def_id);
2258 let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
2259
2260 let mut input_parameters: HashSet<_> =
2261 ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
2262 if let Some(ref trait_ref) = impl_trait_ref {
2263 input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
2264 }
2265 ctp::identify_constrained_type_params(tcx,
2266 &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
2267
2268 let lifetimes_in_associated_types: HashSet<_> =
2269 impl_items.iter()
2270 .map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
2271 .filter_map(|item| match item {
2272 ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
2273 ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
2274 })
2275 .flat_map(|ty| ctp::parameters_for_type(ty, true))
2276 .filter_map(|p| match p {
2277 ctp::Parameter::Type(_) => None,
2278 ctp::Parameter::Region(r) => Some(r),
2279 })
2280 .collect();
2281
2282 for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2283 let region = ty::EarlyBoundRegion { space: TypeSpace,
2284 index: index as u32,
2285 name: lifetime_def.lifetime.name };
2286 if
2287 lifetimes_in_associated_types.contains(&region) && // (*)
2288 !input_parameters.contains(&ctp::Parameter::Region(region))
2289 {
2290 report_unused_parameter(tcx, lifetime_def.lifetime.span,
2291 "lifetime", &region.name.to_string());
2292 }
2293 }
2294
2295 // (*) This is a horrible concession to reality. I think it'd be
2296 // better to just ban unconstrianed lifetimes outright, but in
2297 // practice people do non-hygenic macros like:
2298 //
2299 // ```
2300 // macro_rules! __impl_slice_eq1 {
2301 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2302 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2303 // ....
2304 // }
2305 // }
2306 // }
2307 // ```
2308 //
2309 // In a concession to backwards compatbility, we continue to
2310 // permit those, so long as the lifetimes aren't used in
2311 // associated types. I believe this is sound, because lifetimes
2312 // used elsewhere are not projected back out.
2313 }
2314
2315 fn report_unused_parameter(tcx: &TyCtxt,
2316 span: Span,
2317 kind: &str,
2318 name: &str)
2319 {
2320 span_err!(tcx.sess, span, E0207,
2321 "the {} parameter `{}` is not constrained by the \
2322 impl trait, self type, or predicates",
2323 kind, name);
2324 }