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