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