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