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