]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/mod.rs
Auto merge of #29582 - oli-obk:token_tree, r=sfackler
[rust.git] / src / librustc_typeck / check / mod.rs
1 // Copyright 2012-2015 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 # check.rs
14
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function).  Inference is used to supply types wherever they are
18 unknown.
19
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
22
23 - gather: creates type variables to represent the type of each local
24   variable and pattern binding.
25
26 - main: the main pass does the lion's share of the work: it
27   determines the types of all expressions, resolves
28   methods, checks for most invalid conditions, and so forth.  In
29   some cases, where a type is unknown, it may create a type or region
30   variable and use that as the type of an expression.
31
32   In the process of checking, various constraints will be placed on
33   these type variables through the subtyping relationships requested
34   through the `demand` module.  The `infer` module is in charge
35   of resolving those constraints.
36
37 - regionck: after main is complete, the regionck pass goes over all
38   types looking for regions and making sure that they did not escape
39   into places they are not in scope.  This may also influence the
40   final assignments of the various region variables if there is some
41   flexibility.
42
43 - vtable: find and records the impls to use for each trait bound that
44   appears on a type parameter.
45
46 - writeback: writes the final types within a function body, replacing
47   type variables with their final inferred types.  These final types
48   are written into the `tcx.node_types` table, which should *never* contain
49   any reference to a type variable.
50
51 ## Intermediate types
52
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.item_substs`.  These types
56 may contain unresolved type variables.  After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `ccx.tcx`.
60
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
64
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
67
68 n.b.: A type variable is not the same thing as a type parameter.  A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract.  When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`.  This variable will
74 eventually be resolved to some concrete type (which might itself be
75 type parameter).
76
77 */
78
79 pub use self::Expectation::*;
80 pub use self::compare_method::{compare_impl_method, compare_const_impl};
81 use self::TupleArgumentsFlag::*;
82
83 use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
84 use check::_match::pat_ctxt;
85 use fmt_macros::{Parser, Piece, Position};
86 use metadata::cstore::LOCAL_CRATE;
87 use middle::astconv_util::prohibit_type_params;
88 use middle::def;
89 use middle::def_id::DefId;
90 use middle::infer;
91 use middle::infer::type_variable;
92 use middle::pat_util::{self, pat_id_map};
93 use middle::privacy::{AllPublic, LastMod};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
97 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::util::Representability;
105 use require_c_abi_if_variadic;
106 use rscope::{ElisionFailureInfo, RegionScope};
107 use session::Session;
108 use {CrateCtxt, lookup_full_def};
109 use TypeAndSubsts;
110 use lint;
111 use util::common::{block_query, ErrorReported, indenter, loop_query};
112 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
113 use util::lev_distance::lev_distance;
114
115 use std::cell::{Cell, Ref, RefCell};
116 use std::collections::{HashSet};
117 use std::mem::replace;
118 use syntax::abi;
119 use syntax::ast;
120 use syntax::attr;
121 use syntax::attr::AttrMetaMethods;
122 use syntax::codemap::{self, Span, Spanned};
123 use syntax::owned_slice::OwnedSlice;
124 use syntax::parse::token::{self, InternedString};
125 use syntax::ptr::P;
126
127 use rustc_front::visit::{self, Visitor};
128 use rustc_front::hir;
129 use rustc_front::hir::Visibility;
130 use rustc_front::hir::{Item, ItemImpl};
131 use rustc_front::print::pprust;
132 use rustc_back::slice;
133
134 mod assoc;
135 pub mod dropck;
136 pub mod _match;
137 pub mod writeback;
138 pub mod regionck;
139 pub mod coercion;
140 pub mod demand;
141 pub mod method;
142 mod upvar;
143 mod wf;
144 mod wfcheck;
145 mod cast;
146 mod closure;
147 mod callee;
148 mod compare_method;
149 mod intrinsic;
150 mod op;
151
152 /// closures defined within the function.  For example:
153 ///
154 ///     fn foo() {
155 ///         bar(move|| { ... })
156 ///     }
157 ///
158 /// Here, the function `foo()` and the closure passed to
159 /// `bar()` will each have their own `FnCtxt`, but they will
160 /// share the inherited fields.
161 pub struct Inherited<'a, 'tcx: 'a> {
162     infcx: infer::InferCtxt<'a, 'tcx>,
163     locals: RefCell<NodeMap<Ty<'tcx>>>,
164
165     tables: &'a RefCell<ty::Tables<'tcx>>,
166
167     // When we process a call like `c()` where `c` is a closure type,
168     // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
169     // `FnOnce` closure. In that case, we defer full resolution of the
170     // call until upvar inference can kick in and make the
171     // decision. We keep these deferred resolutions grouped by the
172     // def-id of the closure, so that once we decide, we can easily go
173     // back and process them.
174     deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
175
176     deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
177 }
178
179 trait DeferredCallResolution<'tcx> {
180     fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
181 }
182
183 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
184
185 /// When type-checking an expression, we propagate downward
186 /// whatever type hint we are able in the form of an `Expectation`.
187 #[derive(Copy, Clone, Debug)]
188 pub enum Expectation<'tcx> {
189     /// We know nothing about what type this expression should have.
190     NoExpectation,
191
192     /// This expression should have the type given (or some subtype)
193     ExpectHasType(Ty<'tcx>),
194
195     /// This expression will be cast to the `Ty`
196     ExpectCastableToType(Ty<'tcx>),
197
198     /// This rvalue expression will be wrapped in `&` or `Box` and coerced
199     /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
200     ExpectRvalueLikeUnsized(Ty<'tcx>),
201 }
202
203 impl<'tcx> Expectation<'tcx> {
204     // Disregard "castable to" expectations because they
205     // can lead us astray. Consider for example `if cond
206     // {22} else {c} as u8` -- if we propagate the
207     // "castable to u8" constraint to 22, it will pick the
208     // type 22u8, which is overly constrained (c might not
209     // be a u8). In effect, the problem is that the
210     // "castable to" expectation is not the tightest thing
211     // we can say, so we want to drop it in this case.
212     // The tightest thing we can say is "must unify with
213     // else branch". Note that in the case of a "has type"
214     // constraint, this limitation does not hold.
215
216     // If the expected type is just a type variable, then don't use
217     // an expected type. Otherwise, we might write parts of the type
218     // when checking the 'then' block which are incompatible with the
219     // 'else' branch.
220     fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
221         match *self {
222             ExpectHasType(ety) => {
223                 let ety = fcx.infcx().shallow_resolve(ety);
224                 if !ety.is_ty_var() {
225                     ExpectHasType(ety)
226                 } else {
227                     NoExpectation
228                 }
229             }
230             ExpectRvalueLikeUnsized(ety) => {
231                 ExpectRvalueLikeUnsized(ety)
232             }
233             _ => NoExpectation
234         }
235     }
236 }
237
238 #[derive(Copy, Clone)]
239 pub struct UnsafetyState {
240     pub def: ast::NodeId,
241     pub unsafety: hir::Unsafety,
242     pub unsafe_push_count: u32,
243     from_fn: bool
244 }
245
246 impl UnsafetyState {
247     pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
248         UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
249     }
250
251     pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
252         match self.unsafety {
253             // If this unsafe, then if the outer function was already marked as
254             // unsafe we shouldn't attribute the unsafe'ness to the block. This
255             // way the block can be warned about instead of ignoring this
256             // extraneous block (functions are never warned about).
257             hir::Unsafety::Unsafe if self.from_fn => *self,
258
259             unsafety => {
260                 let (unsafety, def, count) = match blk.rules {
261                     hir::PushUnsafeBlock(..) =>
262                         (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
263                     hir::PopUnsafeBlock(..) =>
264                         (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
265                     hir::UnsafeBlock(..) =>
266                         (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
267                     hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
268                         (unsafety, self.def, self.unsafe_push_count),
269                 };
270                 UnsafetyState{ def: def,
271                                unsafety: unsafety,
272                                unsafe_push_count: count,
273                                from_fn: false }
274             }
275         }
276     }
277 }
278
279 #[derive(Clone)]
280 pub struct FnCtxt<'a, 'tcx: 'a> {
281     body_id: ast::NodeId,
282
283     // This flag is set to true if, during the writeback phase, we encounter
284     // a type error in this function.
285     writeback_errors: Cell<bool>,
286
287     // Number of errors that had been reported when we started
288     // checking this function. On exit, if we find that *more* errors
289     // have been reported, we will skip regionck and other work that
290     // expects the types within the function to be consistent.
291     err_count_on_creation: usize,
292
293     ret_ty: ty::FnOutput<'tcx>,
294
295     ps: RefCell<UnsafetyState>,
296
297     inh: &'a Inherited<'a, 'tcx>,
298
299     ccx: &'a CrateCtxt<'a, 'tcx>,
300 }
301
302 impl<'a, 'tcx> Inherited<'a, 'tcx> {
303     fn new(tcx: &'a ty::ctxt<'tcx>,
304            tables: &'a RefCell<ty::Tables<'tcx>>,
305            param_env: ty::ParameterEnvironment<'a, 'tcx>)
306            -> Inherited<'a, 'tcx> {
307
308         Inherited {
309             infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
310             locals: RefCell::new(NodeMap()),
311             tables: tables,
312             deferred_call_resolutions: RefCell::new(DefIdMap()),
313             deferred_cast_checks: RefCell::new(Vec::new()),
314         }
315     }
316
317     fn normalize_associated_types_in<T>(&self,
318                                         span: Span,
319                                         body_id: ast::NodeId,
320                                         value: &T)
321                                         -> T
322         where T : TypeFoldable<'tcx> + HasTypeFlags
323     {
324         let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
325         assoc::normalize_associated_types_in(&self.infcx,
326                                              &mut fulfillment_cx,
327                                              span,
328                                              body_id,
329                                              value)
330     }
331
332 }
333
334 // Used by check_const and check_enum_variants
335 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
336                                inh: &'a Inherited<'a, 'tcx>,
337                                rty: ty::FnOutput<'tcx>,
338                                body_id: ast::NodeId)
339                                -> FnCtxt<'a, 'tcx> {
340     FnCtxt {
341         body_id: body_id,
342         writeback_errors: Cell::new(false),
343         err_count_on_creation: ccx.tcx.sess.err_count(),
344         ret_ty: rty,
345         ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
346         inh: inh,
347         ccx: ccx
348     }
349 }
350
351 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
352                                      tables: &'a RefCell<ty::Tables<'tcx>>)
353                                     -> Inherited<'a, 'tcx> {
354     // It's kind of a kludge to manufacture a fake function context
355     // and statement context, but we might as well do write the code only once
356     let param_env = ccx.tcx.empty_parameter_environment();
357     Inherited::new(ccx.tcx, &tables, param_env)
358 }
359
360 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
361 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
362
363 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
364     fn visit_item(&mut self, i: &'tcx hir::Item) {
365         check_item_type(self.ccx, i);
366         visit::walk_item(self, i);
367     }
368
369     fn visit_ty(&mut self, t: &'tcx hir::Ty) {
370         match t.node {
371             hir::TyFixedLengthVec(_, ref expr) => {
372                 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
373             }
374             hir::TyBareFn(ref function_declaration) => {
375                 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
376                 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
377                 return
378             }
379             _ => {}
380         }
381
382         visit::walk_ty(self, t);
383     }
384 }
385
386 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
387     fn visit_item(&mut self, i: &'tcx hir::Item) {
388         check_item_body(self.ccx, i);
389         visit::walk_item(self, i);
390     }
391 }
392
393 pub fn check_wf_old(ccx: &CrateCtxt) {
394     // FIXME(#25759). The new code below is much more reliable but (for now)
395     // only generates warnings. So as to ensure that we continue
396     // getting errors where we used to get errors, we run the old wf
397     // code first and abort if it encounters any errors. If no abort
398     // comes, we run the new code and issue warnings.
399     let krate = ccx.tcx.map.krate();
400     let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
401     visit::walk_crate(&mut visit, krate);
402
403     // If types are not well-formed, it leads to all manner of errors
404     // downstream, so stop reporting errors at this point.
405     ccx.tcx.sess.abort_if_errors();
406 }
407
408 pub fn check_wf_new(ccx: &CrateCtxt) {
409     let krate = ccx.tcx.map.krate();
410     let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
411     visit::walk_crate(&mut visit, krate);
412
413     // If types are not well-formed, it leads to all manner of errors
414     // downstream, so stop reporting errors at this point.
415     ccx.tcx.sess.abort_if_errors();
416 }
417
418 pub fn check_item_types(ccx: &CrateCtxt) {
419     let krate = ccx.tcx.map.krate();
420     let mut visit = CheckItemTypesVisitor { ccx: ccx };
421     visit::walk_crate(&mut visit, krate);
422     ccx.tcx.sess.abort_if_errors();
423 }
424
425 pub fn check_item_bodies(ccx: &CrateCtxt) {
426     let krate = ccx.tcx.map.krate();
427     let mut visit = CheckItemBodiesVisitor { ccx: ccx };
428     visit::walk_crate(&mut visit, krate);
429
430     ccx.tcx.sess.abort_if_errors();
431 }
432
433 pub fn check_drop_impls(ccx: &CrateCtxt) {
434     let drop_trait = match ccx.tcx.lang_items.drop_trait() {
435         Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
436     };
437     drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
438         if drop_impl_did.is_local() {
439             match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
440                 Ok(()) => {}
441                 Err(()) => {
442                     assert!(ccx.tcx.sess.has_errors());
443                 }
444             }
445         }
446     });
447
448     ccx.tcx.sess.abort_if_errors();
449 }
450
451 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
452                            decl: &'tcx hir::FnDecl,
453                            body: &'tcx hir::Block,
454                            fn_id: ast::NodeId,
455                            fn_span: Span,
456                            raw_fty: Ty<'tcx>,
457                            param_env: ty::ParameterEnvironment<'a, 'tcx>)
458 {
459     match raw_fty.sty {
460         ty::TyBareFn(_, ref fn_ty) => {
461             let tables = RefCell::new(ty::Tables::empty());
462             let inh = Inherited::new(ccx.tcx, &tables, param_env);
463
464             // Compute the fty from point of view of inside fn.
465             let fn_scope = ccx.tcx.region_maps.item_extent(body.id);
466             let fn_sig =
467                 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
468             let fn_sig =
469                 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
470             let fn_sig =
471                 inh.normalize_associated_types_in(body.span,
472                                                   body.id,
473                                                   &fn_sig);
474
475             let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
476                                decl, fn_id, body, &inh);
477
478             fcx.select_all_obligations_and_apply_defaults();
479             upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
480             fcx.select_obligations_where_possible();
481             fcx.check_casts();
482             fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
483
484             regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
485             writeback::resolve_type_vars_in_fn(&fcx, decl, body);
486         }
487         _ => ccx.tcx.sess.impossible_case(body.span,
488                                  "check_bare_fn: function type expected")
489     }
490 }
491
492 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
493     fcx: &'a FnCtxt<'a, 'tcx>
494 }
495
496 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
497     fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
498         match ty_opt {
499             None => {
500                 // infer the variable's type
501                 let var_ty = self.fcx.infcx().next_ty_var();
502                 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
503                 var_ty
504             }
505             Some(typ) => {
506                 // take type that the user specified
507                 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
508                 typ
509             }
510         }
511     }
512 }
513
514 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
515     // Add explicitly-declared locals.
516     fn visit_local(&mut self, local: &'tcx hir::Local) {
517         let o_ty = match local.ty {
518             Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
519             None => None
520         };
521         self.assign(local.span, local.id, o_ty);
522         debug!("Local variable {:?} is assigned type {}",
523                local.pat,
524                self.fcx.infcx().ty_to_string(
525                    self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
526         visit::walk_local(self, local);
527     }
528
529     // Add pattern bindings.
530     fn visit_pat(&mut self, p: &'tcx hir::Pat) {
531         if let hir::PatIdent(_, ref path1, _) = p.node {
532             if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
533                 let var_ty = self.assign(p.span, p.id, None);
534
535                 self.fcx.require_type_is_sized(var_ty, p.span,
536                                                traits::VariableType(p.id));
537
538                 debug!("Pattern binding {} is assigned to {} with type {:?}",
539                        path1.node,
540                        self.fcx.infcx().ty_to_string(
541                            self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
542                        var_ty);
543             }
544         }
545         visit::walk_pat(self, p);
546     }
547
548     fn visit_block(&mut self, b: &'tcx hir::Block) {
549         // non-obvious: the `blk` variable maps to region lb, so
550         // we have to keep this up-to-date.  This
551         // is... unfortunate.  It'd be nice to not need this.
552         visit::walk_block(self, b);
553     }
554
555     // Since an expr occurs as part of the type fixed size arrays we
556     // need to record the type for that node
557     fn visit_ty(&mut self, t: &'tcx hir::Ty) {
558         match t.node {
559             hir::TyFixedLengthVec(ref ty, ref count_expr) => {
560                 self.visit_ty(&**ty);
561                 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
562             }
563             hir::TyBareFn(ref function_declaration) => {
564                 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
565                 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
566             }
567             _ => visit::walk_ty(self, t)
568         }
569     }
570
571     // Don't descend into fns and items
572     fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
573                 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
574     fn visit_item(&mut self, _: &hir::Item) { }
575
576 }
577
578 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
579 /// body and returns the function context used for that purpose, since in the case of a fn item
580 /// there is still a bit more to do.
581 ///
582 /// * ...
583 /// * inherited: other fields inherited from the enclosing fn (if any)
584 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
585                       unsafety: hir::Unsafety,
586                       unsafety_id: ast::NodeId,
587                       fn_sig: &ty::FnSig<'tcx>,
588                       decl: &'tcx hir::FnDecl,
589                       fn_id: ast::NodeId,
590                       body: &'tcx hir::Block,
591                       inherited: &'a Inherited<'a, 'tcx>)
592                       -> FnCtxt<'a, 'tcx>
593 {
594     let tcx = ccx.tcx;
595     let err_count_on_creation = tcx.sess.err_count();
596
597     let arg_tys = &fn_sig.inputs;
598     let ret_ty = fn_sig.output;
599
600     debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
601            arg_tys,
602            ret_ty,
603            fn_id);
604
605     // Create the function context.  This is either derived from scratch or,
606     // in the case of function expressions, based on the outer context.
607     let fcx = FnCtxt {
608         body_id: body.id,
609         writeback_errors: Cell::new(false),
610         err_count_on_creation: err_count_on_creation,
611         ret_ty: ret_ty,
612         ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
613         inh: inherited,
614         ccx: ccx
615     };
616
617     if let ty::FnConverging(ret_ty) = ret_ty {
618         fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
619     }
620
621     debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
622
623     inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
624
625     {
626         let mut visit = GatherLocalsVisitor { fcx: &fcx, };
627
628         // Add formal parameters.
629         for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
630             // The type of the argument must be well-formed.
631             //
632             // NB -- this is now checked in wfcheck, but that
633             // currently only results in warnings, so we issue an
634             // old-style WF obligation here so that we still get the
635             // errors that we used to get.
636             fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
637
638             // Create type variables for each argument.
639             pat_util::pat_bindings(
640                 &tcx.def_map,
641                 &*input.pat,
642                 |_bm, pat_id, sp, _path| {
643                     let var_ty = visit.assign(sp, pat_id, None);
644                     fcx.require_type_is_sized(var_ty, sp,
645                                               traits::VariableType(pat_id));
646                 });
647
648             // Check the pattern.
649             let pcx = pat_ctxt {
650                 fcx: &fcx,
651                 map: pat_id_map(&tcx.def_map, &*input.pat),
652             };
653             _match::check_pat(&pcx, &*input.pat, *arg_ty);
654         }
655
656         visit.visit_block(body);
657     }
658
659     check_block_with_expected(&fcx, body, match ret_ty {
660         ty::FnConverging(result_type) => ExpectHasType(result_type),
661         ty::FnDiverging => NoExpectation
662     });
663
664     for (input, arg) in decl.inputs.iter().zip(arg_tys) {
665         fcx.write_ty(input.id, arg);
666     }
667
668     fcx
669 }
670
671 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
672     let tcx = ccx.tcx;
673
674     check_representable(tcx, span, id, "struct");
675
676     if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
677         check_simd(tcx, span, id);
678     }
679 }
680
681 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
682     debug!("check_item_type(it.id={}, it.name={})",
683            it.id,
684            ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
685     let _indenter = indenter();
686     match it.node {
687       // Consts can play a role in type-checking, so they are included here.
688       hir::ItemStatic(_, _, ref e) |
689       hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
690       hir::ItemEnum(ref enum_definition, _) => {
691         check_enum_variants(ccx,
692                             it.span,
693                             &enum_definition.variants,
694                             it.id);
695       }
696       hir::ItemFn(..) => {} // entirely within check_item_body
697       hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
698           debug!("ItemImpl {} with id {}", it.name, it.id);
699           match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
700               Some(impl_trait_ref) => {
701                 check_impl_items_against_trait(ccx,
702                                                it.span,
703                                                &impl_trait_ref,
704                                                impl_items);
705               }
706               None => { }
707           }
708       }
709       hir::ItemTrait(_, ref generics, _, _) => {
710         check_trait_on_unimplemented(ccx, generics, it);
711       }
712       hir::ItemStruct(..) => {
713         check_struct(ccx, it.id, it.span);
714       }
715       hir::ItemTy(ref t, ref generics) => {
716         let pty_ty = ccx.tcx.node_id_to_type(it.id);
717         check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
718       }
719       hir::ItemForeignMod(ref m) => {
720         if m.abi == abi::RustIntrinsic {
721             for item in &m.items {
722                 intrinsic::check_intrinsic_type(ccx, &**item);
723             }
724         } else if m.abi == abi::PlatformIntrinsic {
725             for item in &m.items {
726                 intrinsic::check_platform_intrinsic_type(ccx, &**item);
727             }
728         } else {
729             for item in &m.items {
730                 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
731                 if !pty.generics.types.is_empty() {
732                     span_err!(ccx.tcx.sess, item.span, E0044,
733                         "foreign items may not have type parameters");
734                     span_help!(ccx.tcx.sess, item.span,
735                         "consider using specialization instead of \
736                         type parameters");
737                 }
738
739                 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
740                     require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
741                 }
742             }
743         }
744       }
745       _ => {/* nothing to do */ }
746     }
747 }
748
749 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
750     debug!("check_item_body(it.id={}, it.name={})",
751            it.id,
752            ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
753     let _indenter = indenter();
754     match it.node {
755       hir::ItemFn(ref decl, _, _, _, _, ref body) => {
756         let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
757         let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
758         check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
759       }
760       hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
761         debug!("ItemImpl {} with id {}", it.name, it.id);
762
763         let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
764
765         for impl_item in impl_items {
766             match impl_item.node {
767                 hir::ConstImplItem(_, ref expr) => {
768                     check_const(ccx, impl_item.span, &*expr, impl_item.id)
769                 }
770                 hir::MethodImplItem(ref sig, ref body) => {
771                     check_method_body(ccx, &impl_pty.generics, sig, body,
772                                       impl_item.id, impl_item.span);
773                 }
774                 hir::TypeImplItem(_) => {
775                     // Nothing to do here.
776                 }
777             }
778         }
779       }
780       hir::ItemTrait(_, _, _, ref trait_items) => {
781         let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
782         for trait_item in trait_items {
783             match trait_item.node {
784                 hir::ConstTraitItem(_, Some(ref expr)) => {
785                     check_const(ccx, trait_item.span, &*expr, trait_item.id)
786                 }
787                 hir::MethodTraitItem(ref sig, Some(ref body)) => {
788                     check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
789
790                     check_method_body(ccx, &trait_def.generics, sig, body,
791                                       trait_item.id, trait_item.span);
792                 }
793                 hir::MethodTraitItem(ref sig, None) => {
794                     check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
795                 }
796                 hir::ConstTraitItem(_, None) |
797                 hir::TypeTraitItem(..) => {
798                     // Nothing to do.
799                 }
800             }
801         }
802       }
803       _ => {/* nothing to do */ }
804     }
805 }
806
807 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
808                                      span: Span,
809                                      constness: hir::Constness)
810 {
811     match constness {
812         hir::Constness::NotConst => {
813             // good
814         }
815         hir::Constness::Const => {
816             span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
817         }
818     }
819 }
820
821 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
822                                generics: &hir::Generics,
823                                item: &hir::Item) {
824     if let Some(ref attr) = item.attrs.iter().find(|a| {
825         a.check_name("rustc_on_unimplemented")
826     }) {
827         if let Some(ref istring) = attr.value_str() {
828             let parser = Parser::new(&istring);
829             let types = &*generics.ty_params;
830             for token in parser {
831                 match token {
832                     Piece::String(_) => (), // Normal string, no need to check it
833                     Piece::NextArgument(a) => match a.position {
834                         // `{Self}` is allowed
835                         Position::ArgumentNamed(s) if s == "Self" => (),
836                         // So is `{A}` if A is a type parameter
837                         Position::ArgumentNamed(s) => match types.iter().find(|t| {
838                             t.name.as_str() == s
839                         }) {
840                             Some(_) => (),
841                             None => {
842                                 span_err!(ccx.tcx.sess, attr.span, E0230,
843                                                  "there is no type parameter \
844                                                           {} on trait {}",
845                                                            s, item.name);
846                             }
847                         },
848                         // `{:1}` and `{}` are not to be used
849                         Position::ArgumentIs(_) | Position::ArgumentNext => {
850                             span_err!(ccx.tcx.sess, attr.span, E0231,
851                                                   "only named substitution \
852                                                    parameters are allowed");
853                         }
854                     }
855                 }
856             }
857         } else {
858             span_err!(ccx.tcx.sess, attr.span, E0232,
859                                   "this attribute must have a value, \
860                                    eg `#[rustc_on_unimplemented = \"foo\"]`")
861         }
862     }
863 }
864
865 /// Type checks a method body.
866 ///
867 /// # Parameters
868 ///
869 /// * `item_generics`: generics defined on the impl/trait that contains
870 ///   the method
871 /// * `self_bound`: bound for the `Self` type parameter, if any
872 /// * `method`: the method definition
873 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
874                                item_generics: &ty::Generics<'tcx>,
875                                sig: &'tcx hir::MethodSig,
876                                body: &'tcx hir::Block,
877                                id: ast::NodeId, span: Span) {
878     debug!("check_method_body(item_generics={:?}, id={})",
879             item_generics, id);
880     let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
881
882     let fty = ccx.tcx.node_id_to_type(id);
883     debug!("check_method_body: fty={:?}", fty);
884
885     check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
886 }
887
888 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
889                                             impl_span: Span,
890                                             impl_trait_ref: &ty::TraitRef<'tcx>,
891                                             impl_items: &[P<hir::ImplItem>]) {
892     // Locate trait methods
893     let tcx = ccx.tcx;
894     let trait_items = tcx.trait_items(impl_trait_ref.def_id);
895     let mut overridden_associated_type = None;
896
897     // Check existing impl methods to see if they are both present in trait
898     // and compatible with trait signature
899     for impl_item in impl_items {
900         let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
901         let ty_trait_item = trait_items.iter()
902             .find(|ac| ac.name() == ty_impl_item.name())
903             .unwrap_or_else(|| {
904                 // This is checked by resolve
905                 tcx.sess.span_bug(impl_item.span,
906                                   &format!("impl-item `{}` is not a member of `{:?}`",
907                                            ty_impl_item.name(),
908                                            impl_trait_ref));
909             });
910         match impl_item.node {
911             hir::ConstImplItem(..) => {
912                 let impl_const = match ty_impl_item {
913                     ty::ConstTraitItem(ref cti) => cti,
914                     _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
915                 };
916
917                 // Find associated const definition.
918                 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
919                     compare_const_impl(ccx.tcx,
920                                        &impl_const,
921                                        impl_item.span,
922                                        trait_const,
923                                        &*impl_trait_ref);
924                 } else {
925                     span_err!(tcx.sess, impl_item.span, E0323,
926                               "item `{}` is an associated const, \
927                               which doesn't match its trait `{:?}`",
928                               impl_const.name,
929                               impl_trait_ref)
930                 }
931             }
932             hir::MethodImplItem(ref sig, ref body) => {
933                 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
934
935                 let impl_method = match ty_impl_item {
936                     ty::MethodTraitItem(ref mti) => mti,
937                     _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
938                 };
939
940                 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
941                     compare_impl_method(ccx.tcx,
942                                         &impl_method,
943                                         impl_item.span,
944                                         body.id,
945                                         &trait_method,
946                                         &impl_trait_ref);
947                 } else {
948                     span_err!(tcx.sess, impl_item.span, E0324,
949                               "item `{}` is an associated method, \
950                               which doesn't match its trait `{:?}`",
951                               impl_method.name,
952                               impl_trait_ref)
953                 }
954             }
955             hir::TypeImplItem(_) => {
956                 let impl_type = match ty_impl_item {
957                     ty::TypeTraitItem(ref tti) => tti,
958                     _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
959                 };
960
961                 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
962                     if let Some(_) = at.ty {
963                         overridden_associated_type = Some(impl_item);
964                     }
965                 } else {
966                     span_err!(tcx.sess, impl_item.span, E0325,
967                               "item `{}` is an associated type, \
968                               which doesn't match its trait `{:?}`",
969                               impl_type.name,
970                               impl_trait_ref)
971                 }
972             }
973         }
974     }
975
976     // Check for missing items from trait
977     let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
978     let mut missing_items = Vec::new();
979     let mut invalidated_items = Vec::new();
980     let associated_type_overridden = overridden_associated_type.is_some();
981     for trait_item in trait_items.iter() {
982         match *trait_item {
983             ty::ConstTraitItem(ref associated_const) => {
984                 let is_implemented = impl_items.iter().any(|ii| {
985                     match ii.node {
986                         hir::ConstImplItem(..) => {
987                             ii.name == associated_const.name
988                         }
989                         _ => false,
990                     }
991                 });
992                 let is_provided = associated_const.has_value;
993
994                 if !is_implemented {
995                     if !is_provided {
996                         missing_items.push(associated_const.name);
997                     } else if associated_type_overridden {
998                         invalidated_items.push(associated_const.name);
999                     }
1000                 }
1001             }
1002             ty::MethodTraitItem(ref trait_method) => {
1003                 let is_implemented =
1004                     impl_items.iter().any(|ii| {
1005                         match ii.node {
1006                             hir::MethodImplItem(..) => {
1007                                 ii.name == trait_method.name
1008                             }
1009                             _ => false,
1010                         }
1011                     });
1012                 let is_provided =
1013                     provided_methods.iter().any(|m| m.name == trait_method.name);
1014                 if !is_implemented {
1015                     if !is_provided {
1016                         missing_items.push(trait_method.name);
1017                     } else if associated_type_overridden {
1018                         invalidated_items.push(trait_method.name);
1019                     }
1020                 }
1021             }
1022             ty::TypeTraitItem(ref associated_type) => {
1023                 let is_implemented = impl_items.iter().any(|ii| {
1024                     match ii.node {
1025                         hir::TypeImplItem(_) => {
1026                             ii.name == associated_type.name
1027                         }
1028                         _ => false,
1029                     }
1030                 });
1031                 let is_provided = associated_type.ty.is_some();
1032                 if !is_implemented {
1033                     if !is_provided {
1034                         missing_items.push(associated_type.name);
1035                     } else if associated_type_overridden {
1036                         invalidated_items.push(associated_type.name);
1037                     }
1038                 }
1039             }
1040         }
1041     }
1042
1043     if !missing_items.is_empty() {
1044         span_err!(tcx.sess, impl_span, E0046,
1045             "not all trait items implemented, missing: `{}`",
1046             missing_items.iter()
1047                   .map(|name| name.to_string())
1048                   .collect::<Vec<_>>().join("`, `"))
1049     }
1050
1051     if !invalidated_items.is_empty() {
1052         let invalidator = overridden_associated_type.unwrap();
1053         span_err!(tcx.sess, invalidator.span, E0399,
1054                   "the following trait items need to be reimplemented \
1055                    as `{}` was overridden: `{}`",
1056                   invalidator.name,
1057                   invalidated_items.iter()
1058                                    .map(|name| name.to_string())
1059                                    .collect::<Vec<_>>().join("`, `"))
1060     }
1061 }
1062
1063 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1064                                          span: Span,
1065                                          t_span: Span,
1066                                          e_span: Span,
1067                                          t_cast: Ty<'tcx>,
1068                                          t_expr: Ty<'tcx>,
1069                                          id: ast::NodeId) {
1070     let tstr = fcx.infcx().ty_to_string(t_cast);
1071     fcx.type_error_message(span, |actual| {
1072         format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1073     }, t_expr, None);
1074     match t_expr.sty {
1075         ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1076             let mtstr = match mt {
1077                 hir::MutMutable => "mut ",
1078                 hir::MutImmutable => ""
1079             };
1080             if t_cast.is_trait() {
1081                 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1082                     Ok(s) => {
1083                         fcx.tcx().sess.span_suggestion(t_span,
1084                                                        "try casting to a reference instead:",
1085                                                        format!("&{}{}", mtstr, s));
1086                     },
1087                     Err(_) =>
1088                         span_help!(fcx.tcx().sess, t_span,
1089                                    "did you mean `&{}{}`?", mtstr, tstr),
1090                 }
1091             } else {
1092                 span_help!(fcx.tcx().sess, span,
1093                            "consider using an implicit coercion to `&{}{}` instead",
1094                            mtstr, tstr);
1095             }
1096         }
1097         ty::TyBox(..) => {
1098             match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1099                 Ok(s) => {
1100                     fcx.tcx().sess.span_suggestion(t_span,
1101                                                    "try casting to a `Box` instead:",
1102                                                    format!("Box<{}>", s));
1103                 },
1104                 Err(_) =>
1105                     span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1106             }
1107         }
1108         _ => {
1109             span_help!(fcx.tcx().sess, e_span,
1110                        "consider using a box or reference as appropriate");
1111         }
1112     }
1113     fcx.write_error(id);
1114 }
1115
1116
1117 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1118     fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1119
1120     fn get_item_type_scheme(&self, _: Span, id: DefId)
1121                             -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1122     {
1123         Ok(self.tcx().lookup_item_type(id))
1124     }
1125
1126     fn get_trait_def(&self, _: Span, id: DefId)
1127                      -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1128     {
1129         Ok(self.tcx().lookup_trait_def(id))
1130     }
1131
1132     fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1133         // all super predicates are ensured during collect pass
1134         Ok(())
1135     }
1136
1137     fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1138         Some(&self.inh.infcx.parameter_environment.free_substs)
1139     }
1140
1141     fn get_type_parameter_bounds(&self,
1142                                  _: Span,
1143                                  node_id: ast::NodeId)
1144                                  -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1145     {
1146         let def = self.tcx().type_parameter_def(node_id);
1147         let r = self.inh.infcx.parameter_environment
1148                                   .caller_bounds
1149                                   .iter()
1150                                   .filter_map(|predicate| {
1151                                       match *predicate {
1152                                           ty::Predicate::Trait(ref data) => {
1153                                               if data.0.self_ty().is_param(def.space, def.index) {
1154                                                   Some(data.to_poly_trait_ref())
1155                                               } else {
1156                                                   None
1157                                               }
1158                                           }
1159                                           _ => {
1160                                               None
1161                                           }
1162                                       }
1163                                   })
1164                                   .collect();
1165         Ok(r)
1166     }
1167
1168     fn trait_defines_associated_type_named(&self,
1169                                            trait_def_id: DefId,
1170                                            assoc_name: ast::Name)
1171                                            -> bool
1172     {
1173         let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1174         trait_def.associated_type_names.contains(&assoc_name)
1175     }
1176
1177     fn ty_infer(&self,
1178                 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1179                 substs: Option<&mut subst::Substs<'tcx>>,
1180                 space: Option<subst::ParamSpace>,
1181                 span: Span) -> Ty<'tcx> {
1182         // Grab the default doing subsitution
1183         let default = ty_param_def.and_then(|def| {
1184             def.default.map(|ty| type_variable::Default {
1185                 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1186                 origin_span: span,
1187                 def_id: def.default_def_id
1188             })
1189         });
1190
1191         let ty_var = self.infcx().next_ty_var_with_default(default);
1192
1193         // Finally we add the type variable to the substs
1194         match substs {
1195             None => ty_var,
1196             Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1197         }
1198     }
1199
1200     fn projected_ty_from_poly_trait_ref(&self,
1201                                         span: Span,
1202                                         poly_trait_ref: ty::PolyTraitRef<'tcx>,
1203                                         item_name: ast::Name)
1204                                         -> Ty<'tcx>
1205     {
1206         let (trait_ref, _) =
1207             self.infcx().replace_late_bound_regions_with_fresh_var(
1208                 span,
1209                 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1210                 &poly_trait_ref);
1211
1212         self.normalize_associated_type(span, trait_ref, item_name)
1213     }
1214
1215     fn projected_ty(&self,
1216                     span: Span,
1217                     trait_ref: ty::TraitRef<'tcx>,
1218                     item_name: ast::Name)
1219                     -> Ty<'tcx>
1220     {
1221         self.normalize_associated_type(span, trait_ref, item_name)
1222     }
1223 }
1224
1225 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1226     fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1227
1228     pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1229         &self.inh.infcx
1230     }
1231
1232     pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1233         &self.inh.infcx.parameter_environment
1234     }
1235
1236     pub fn sess(&self) -> &Session {
1237         &self.tcx().sess
1238     }
1239
1240     pub fn err_count_since_creation(&self) -> usize {
1241         self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1242     }
1243
1244     /// Resolves type variables in `ty` if possible. Unlike the infcx
1245     /// version, this version will also select obligations if it seems
1246     /// useful, in an effort to get more type information.
1247     fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1248         debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1249
1250         // No TyInfer()? Nothing needs doing.
1251         if !ty.has_infer_types() {
1252             debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1253             return ty;
1254         }
1255
1256         // If `ty` is a type variable, see whether we already know what it is.
1257         ty = self.infcx().resolve_type_vars_if_possible(&ty);
1258         if !ty.has_infer_types() {
1259             debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1260             return ty;
1261         }
1262
1263         // If not, try resolving any new fcx obligations that have cropped up.
1264         self.select_new_obligations();
1265         ty = self.infcx().resolve_type_vars_if_possible(&ty);
1266         if !ty.has_infer_types() {
1267             debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1268             return ty;
1269         }
1270
1271         // If not, try resolving *all* pending obligations as much as
1272         // possible. This can help substantially when there are
1273         // indirect dependencies that don't seem worth tracking
1274         // precisely.
1275         self.select_obligations_where_possible();
1276         ty = self.infcx().resolve_type_vars_if_possible(&ty);
1277
1278         debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1279         ty
1280     }
1281
1282     fn record_deferred_call_resolution(&self,
1283                                        closure_def_id: DefId,
1284                                        r: DeferredCallResolutionHandler<'tcx>) {
1285         let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1286         deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1287     }
1288
1289     fn remove_deferred_call_resolutions(&self,
1290                                         closure_def_id: DefId)
1291                                         -> Vec<DeferredCallResolutionHandler<'tcx>>
1292     {
1293         let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1294         deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1295     }
1296
1297     pub fn tag(&self) -> String {
1298         let self_ptr: *const FnCtxt = self;
1299         format!("{:?}", self_ptr)
1300     }
1301
1302     pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1303         match self.inh.locals.borrow().get(&nid) {
1304             Some(&t) => t,
1305             None => {
1306                 span_err!(self.tcx().sess, span, E0513,
1307                           "no type for local variable {}",
1308                           nid);
1309                 self.tcx().types.err
1310             }
1311         }
1312     }
1313
1314     #[inline]
1315     pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1316         debug!("write_ty({}, {:?}) in fcx {}",
1317                node_id, ty, self.tag());
1318         self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1319     }
1320
1321     pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1322         if !substs.substs.is_noop() {
1323             debug!("write_substs({}, {:?}) in fcx {}",
1324                    node_id,
1325                    substs,
1326                    self.tag());
1327
1328             self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1329         }
1330     }
1331
1332     pub fn write_autoderef_adjustment(&self,
1333                                       node_id: ast::NodeId,
1334                                       derefs: usize) {
1335         self.write_adjustment(
1336             node_id,
1337             adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1338                 autoderefs: derefs,
1339                 autoref: None,
1340                 unsize: None
1341             })
1342         );
1343     }
1344
1345     pub fn write_adjustment(&self,
1346                             node_id: ast::NodeId,
1347                             adj: adjustment::AutoAdjustment<'tcx>) {
1348         debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1349
1350         if adj.is_identity() {
1351             return;
1352         }
1353
1354         self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1355     }
1356
1357     /// Basically whenever we are converting from a type scheme into
1358     /// the fn body space, we always want to normalize associated
1359     /// types as well. This function combines the two.
1360     fn instantiate_type_scheme<T>(&self,
1361                                   span: Span,
1362                                   substs: &Substs<'tcx>,
1363                                   value: &T)
1364                                   -> T
1365         where T : TypeFoldable<'tcx> + HasTypeFlags
1366     {
1367         let value = value.subst(self.tcx(), substs);
1368         let result = self.normalize_associated_types_in(span, &value);
1369         debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1370                value,
1371                substs,
1372                result);
1373         result
1374     }
1375
1376     /// As `instantiate_type_scheme`, but for the bounds found in a
1377     /// generic type scheme.
1378     fn instantiate_bounds(&self,
1379                           span: Span,
1380                           substs: &Substs<'tcx>,
1381                           bounds: &ty::GenericPredicates<'tcx>)
1382                           -> ty::InstantiatedPredicates<'tcx>
1383     {
1384         ty::InstantiatedPredicates {
1385             predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1386         }
1387     }
1388
1389
1390     fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1391         where T : TypeFoldable<'tcx> + HasTypeFlags
1392     {
1393         self.inh.normalize_associated_types_in(span, self.body_id, value)
1394     }
1395
1396     fn normalize_associated_type(&self,
1397                                  span: Span,
1398                                  trait_ref: ty::TraitRef<'tcx>,
1399                                  item_name: ast::Name)
1400                                  -> Ty<'tcx>
1401     {
1402         let cause = traits::ObligationCause::new(span,
1403                                                  self.body_id,
1404                                                  traits::ObligationCauseCode::MiscObligation);
1405         self.inh
1406             .infcx
1407             .fulfillment_cx
1408             .borrow_mut()
1409             .normalize_projection_type(self.infcx(),
1410                                        ty::ProjectionTy {
1411                                            trait_ref: trait_ref,
1412                                            item_name: item_name,
1413                                        },
1414                                        cause)
1415     }
1416
1417     /// Instantiates the type in `did` with the generics in `path` and returns
1418     /// it (registering the necessary trait obligations along the way).
1419     ///
1420     /// Note that this function is only intended to be used with type-paths,
1421     /// not with value-paths.
1422     pub fn instantiate_type(&self,
1423                             did: DefId,
1424                             path: &hir::Path)
1425                             -> Ty<'tcx>
1426     {
1427         debug!("instantiate_type(did={:?}, path={:?})", did, path);
1428         let type_scheme =
1429             self.tcx().lookup_item_type(did);
1430         let type_predicates =
1431             self.tcx().lookup_predicates(did);
1432         let substs = astconv::ast_path_substs_for_ty(self, self,
1433                                                      path.span,
1434                                                      PathParamMode::Optional,
1435                                                      &type_scheme.generics,
1436                                                      path.segments.last().unwrap());
1437         debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1438         let bounds =
1439             self.instantiate_bounds(path.span, &substs, &type_predicates);
1440         self.add_obligations_for_parameters(
1441             traits::ObligationCause::new(
1442                 path.span,
1443                 self.body_id,
1444                 traits::ItemObligation(did)),
1445             &bounds);
1446
1447         self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1448     }
1449
1450     /// Return the dict-like variant corresponding to a given `Def`.
1451     pub fn def_struct_variant(&self,
1452                               def: def::Def,
1453                               span: Span)
1454                               -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1455     {
1456         let (adt, variant) = match def {
1457             def::DefVariant(enum_id, variant_id, true) => {
1458                 let adt = self.tcx().lookup_adt_def(enum_id);
1459                 (adt, adt.variant_with_id(variant_id))
1460             }
1461             def::DefTy(did, _) | def::DefStruct(did) => {
1462                 let typ = self.tcx().lookup_item_type(did);
1463                 if let ty::TyStruct(adt, _) = typ.ty.sty {
1464                     (adt, adt.struct_variant())
1465                 } else {
1466                     return None;
1467                 }
1468             }
1469             _ => return None
1470         };
1471
1472         let var_kind = variant.kind();
1473         if var_kind == ty::VariantKind::Struct {
1474             Some((adt, variant))
1475         } else if var_kind == ty::VariantKind::Unit {
1476             if !self.tcx().sess.features.borrow().braced_empty_structs {
1477                 self.tcx().sess.span_err(span, "empty structs and enum variants \
1478                                                 with braces are unstable");
1479                 fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
1480                                                        the crate features to enable");
1481             }
1482
1483              Some((adt, variant))
1484          } else {
1485              None
1486          }
1487     }
1488
1489     pub fn write_nil(&self, node_id: ast::NodeId) {
1490         self.write_ty(node_id, self.tcx().mk_nil());
1491     }
1492     pub fn write_error(&self, node_id: ast::NodeId) {
1493         self.write_ty(node_id, self.tcx().types.err);
1494     }
1495
1496     pub fn require_type_meets(&self,
1497                               ty: Ty<'tcx>,
1498                               span: Span,
1499                               code: traits::ObligationCauseCode<'tcx>,
1500                               bound: ty::BuiltinBound)
1501     {
1502         self.register_builtin_bound(
1503             ty,
1504             bound,
1505             traits::ObligationCause::new(span, self.body_id, code));
1506     }
1507
1508     pub fn require_type_is_sized(&self,
1509                                  ty: Ty<'tcx>,
1510                                  span: Span,
1511                                  code: traits::ObligationCauseCode<'tcx>)
1512     {
1513         self.require_type_meets(ty, span, code, ty::BoundSized);
1514     }
1515
1516     pub fn require_expr_have_sized_type(&self,
1517                                         expr: &hir::Expr,
1518                                         code: traits::ObligationCauseCode<'tcx>)
1519     {
1520         self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1521     }
1522
1523     pub fn type_is_known_to_be_sized(&self,
1524                                      ty: Ty<'tcx>,
1525                                      span: Span)
1526                                      -> bool
1527     {
1528         traits::type_known_to_meet_builtin_bound(self.infcx(),
1529                                                  ty,
1530                                                  ty::BoundSized,
1531                                                  span)
1532     }
1533
1534     pub fn register_builtin_bound(&self,
1535                                   ty: Ty<'tcx>,
1536                                   builtin_bound: ty::BuiltinBound,
1537                                   cause: traits::ObligationCause<'tcx>)
1538     {
1539         self.inh.infcx.fulfillment_cx.borrow_mut()
1540             .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1541     }
1542
1543     pub fn register_predicate(&self,
1544                               obligation: traits::PredicateObligation<'tcx>)
1545     {
1546         debug!("register_predicate({:?})",
1547                obligation);
1548         self.inh.infcx.fulfillment_cx
1549             .borrow_mut()
1550             .register_predicate_obligation(self.infcx(), obligation);
1551     }
1552
1553     pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1554         let t = ast_ty_to_ty(self, self, ast_t);
1555         self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1556         t
1557     }
1558
1559     pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1560         match self.inh.tables.borrow().node_types.get(&ex.id) {
1561             Some(&t) => t,
1562             None => {
1563                 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1564                                             self.tag()));
1565             }
1566         }
1567     }
1568
1569     /// Apply `adjustment` to the type of `expr`
1570     pub fn adjust_expr_ty(&self,
1571                           expr: &hir::Expr,
1572                           adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1573                           -> Ty<'tcx>
1574     {
1575         let raw_ty = self.expr_ty(expr);
1576         let raw_ty = self.infcx().shallow_resolve(raw_ty);
1577         let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1578         raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1579             self.inh.tables.borrow().method_map.get(&method_call)
1580                                         .map(|method| resolve_ty(method.ty))
1581         })
1582     }
1583
1584     pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1585         match self.inh.tables.borrow().node_types.get(&id) {
1586             Some(&t) => t,
1587             None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1588             None => {
1589                 self.tcx().sess.bug(
1590                     &format!("no type for node {}: {} in fcx {}",
1591                             id, self.tcx().map.node_to_string(id),
1592                             self.tag()));
1593             }
1594         }
1595     }
1596
1597     pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1598         // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1599         // it changes when we upgrade the snapshot compiler
1600         fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1601                                         -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1602             &tables.item_substs
1603         }
1604
1605         Ref::map(self.inh.tables.borrow(), project_item_susbts)
1606     }
1607
1608     pub fn opt_node_ty_substs<F>(&self,
1609                                  id: ast::NodeId,
1610                                  f: F) where
1611         F: FnOnce(&ty::ItemSubsts<'tcx>),
1612     {
1613         match self.inh.tables.borrow().item_substs.get(&id) {
1614             Some(s) => { f(s) }
1615             None => { }
1616         }
1617     }
1618
1619     pub fn mk_subty(&self,
1620                     a_is_expected: bool,
1621                     origin: infer::TypeOrigin,
1622                     sub: Ty<'tcx>,
1623                     sup: Ty<'tcx>)
1624                     -> Result<(), TypeError<'tcx>> {
1625         infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1626     }
1627
1628     pub fn mk_eqty(&self,
1629                    a_is_expected: bool,
1630                    origin: infer::TypeOrigin,
1631                    sub: Ty<'tcx>,
1632                    sup: Ty<'tcx>)
1633                    -> Result<(), TypeError<'tcx>> {
1634         infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1635     }
1636
1637     pub fn mk_subr(&self,
1638                    origin: infer::SubregionOrigin<'tcx>,
1639                    sub: ty::Region,
1640                    sup: ty::Region) {
1641         infer::mk_subr(self.infcx(), origin, sub, sup)
1642     }
1643
1644     pub fn type_error_message<M>(&self,
1645                                  sp: Span,
1646                                  mk_msg: M,
1647                                  actual_ty: Ty<'tcx>,
1648                                  err: Option<&TypeError<'tcx>>) where
1649         M: FnOnce(String) -> String,
1650     {
1651         self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1652     }
1653
1654     pub fn report_mismatched_types(&self,
1655                                    sp: Span,
1656                                    e: Ty<'tcx>,
1657                                    a: Ty<'tcx>,
1658                                    err: &TypeError<'tcx>) {
1659         self.infcx().report_mismatched_types(sp, e, a, err)
1660     }
1661
1662     /// Registers an obligation for checking later, during regionck, that the type `ty` must
1663     /// outlive the region `r`.
1664     pub fn register_region_obligation(&self,
1665                                       ty: Ty<'tcx>,
1666                                       region: ty::Region,
1667                                       cause: traits::ObligationCause<'tcx>)
1668     {
1669         let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1670         fulfillment_cx.register_region_obligation(ty, region, cause);
1671     }
1672
1673     /// Registers an obligation for checking later, during regionck, that the type `ty` must
1674     /// outlive the region `r`.
1675     pub fn register_wf_obligation(&self,
1676                                   ty: Ty<'tcx>,
1677                                   span: Span,
1678                                   code: traits::ObligationCauseCode<'tcx>)
1679     {
1680         // WF obligations never themselves fail, so no real need to give a detailed cause:
1681         let cause = traits::ObligationCause::new(span, self.body_id, code);
1682         self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1683     }
1684
1685     pub fn register_old_wf_obligation(&self,
1686                                       ty: Ty<'tcx>,
1687                                       span: Span,
1688                                       code: traits::ObligationCauseCode<'tcx>)
1689     {
1690         // Registers an "old-style" WF obligation that uses the
1691         // implicator code.  This is basically a buggy version of
1692         // `register_wf_obligation` that is being kept around
1693         // temporarily just to help with phasing in the newer rules.
1694         //
1695         // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1696         let cause = traits::ObligationCause::new(span, self.body_id, code);
1697         self.register_region_obligation(ty, ty::ReEmpty, cause);
1698     }
1699
1700     /// Registers obligations that all types appearing in `substs` are well-formed.
1701     pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1702     {
1703         for &ty in &substs.types {
1704             self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1705         }
1706     }
1707
1708     /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1709     /// type/region parameter was instantiated (`substs`), creates and registers suitable
1710     /// trait/region obligations.
1711     ///
1712     /// For example, if there is a function:
1713     ///
1714     /// ```
1715     /// fn foo<'a,T:'a>(...)
1716     /// ```
1717     ///
1718     /// and a reference:
1719     ///
1720     /// ```
1721     /// let f = foo;
1722     /// ```
1723     ///
1724     /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1725     /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1726     pub fn add_obligations_for_parameters(&self,
1727                                           cause: traits::ObligationCause<'tcx>,
1728                                           predicates: &ty::InstantiatedPredicates<'tcx>)
1729     {
1730         assert!(!predicates.has_escaping_regions());
1731
1732         debug!("add_obligations_for_parameters(predicates={:?})",
1733                predicates);
1734
1735         for obligation in traits::predicates_for_generics(cause, predicates) {
1736             self.register_predicate(obligation);
1737         }
1738     }
1739
1740     // FIXME(arielb1): use this instead of field.ty everywhere
1741     pub fn field_ty(&self,
1742                     span: Span,
1743                     field: ty::FieldDef<'tcx>,
1744                     substs: &Substs<'tcx>)
1745                     -> Ty<'tcx>
1746     {
1747         self.normalize_associated_types_in(span,
1748                                            &field.ty(self.tcx(), substs))
1749     }
1750
1751     // Only for fields! Returns <none> for methods>
1752     // Indifferent to privacy flags
1753     fn check_casts(&self) {
1754         let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1755         for cast in deferred_cast_checks.drain(..) {
1756             cast.check(self);
1757         }
1758     }
1759
1760     /// Apply "fallbacks" to some types
1761     /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1762     fn default_type_parameters(&self) {
1763         use middle::ty::error::UnconstrainedNumeric::Neither;
1764         use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1765         for ty in &self.infcx().unsolved_variables() {
1766             let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1767             if self.infcx().type_var_diverges(resolved) {
1768                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1769             } else {
1770                 match self.infcx().type_is_unconstrained_numeric(resolved) {
1771                     UnconstrainedInt => {
1772                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1773                     },
1774                     UnconstrainedFloat => {
1775                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1776                     }
1777                     Neither => { }
1778                 }
1779             }
1780         }
1781     }
1782
1783     fn select_all_obligations_and_apply_defaults(&self) {
1784         if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1785             self.new_select_all_obligations_and_apply_defaults();
1786         } else {
1787             self.old_select_all_obligations_and_apply_defaults();
1788         }
1789     }
1790
1791     // Implements old type inference fallback algorithm
1792     fn old_select_all_obligations_and_apply_defaults(&self) {
1793         self.select_obligations_where_possible();
1794         self.default_type_parameters();
1795         self.select_obligations_where_possible();
1796     }
1797
1798     fn new_select_all_obligations_and_apply_defaults(&self) {
1799         use middle::ty::error::UnconstrainedNumeric::Neither;
1800         use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1801
1802         // For the time being this errs on the side of being memory wasteful but provides better
1803         // error reporting.
1804         // let type_variables = self.infcx().type_variables.clone();
1805
1806         // There is a possibility that this algorithm will have to run an arbitrary number of times
1807         // to terminate so we bound it by the compiler's recursion limit.
1808         for _ in 0..self.tcx().sess.recursion_limit.get() {
1809             // First we try to solve all obligations, it is possible that the last iteration
1810             // has made it possible to make more progress.
1811             self.select_obligations_where_possible();
1812
1813             let mut conflicts = Vec::new();
1814
1815             // Collect all unsolved type, integral and floating point variables.
1816             let unsolved_variables = self.inh.infcx.unsolved_variables();
1817
1818             // We must collect the defaults *before* we do any unification. Because we have
1819             // directly attached defaults to the type variables any unification that occurs
1820             // will erase defaults causing conflicting defaults to be completely ignored.
1821             let default_map: FnvHashMap<_, _> =
1822                 unsolved_variables
1823                     .iter()
1824                     .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1825                     .collect();
1826
1827             let mut unbound_tyvars = HashSet::new();
1828
1829             debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1830
1831             // We loop over the unsolved variables, resolving them and if they are
1832             // and unconstrainted numberic type we add them to the set of unbound
1833             // variables. We do this so we only apply literal fallback to type
1834             // variables without defaults.
1835             for ty in &unsolved_variables {
1836                 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1837                 if self.infcx().type_var_diverges(resolved) {
1838                     demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1839                 } else {
1840                     match self.infcx().type_is_unconstrained_numeric(resolved) {
1841                         UnconstrainedInt | UnconstrainedFloat => {
1842                             unbound_tyvars.insert(resolved);
1843                         },
1844                         Neither => {}
1845                     }
1846                 }
1847             }
1848
1849             // We now remove any numeric types that also have defaults, and instead insert
1850             // the type variable with a defined fallback.
1851             for ty in &unsolved_variables {
1852                 if let Some(_default) = default_map.get(ty) {
1853                     let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1854
1855                     debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1856                              ty, _default);
1857
1858                     match resolved.sty {
1859                         ty::TyInfer(ty::TyVar(_)) => {
1860                             unbound_tyvars.insert(ty);
1861                         }
1862
1863                         ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1864                             unbound_tyvars.insert(ty);
1865                             if unbound_tyvars.contains(resolved) {
1866                                 unbound_tyvars.remove(resolved);
1867                             }
1868                         }
1869
1870                         _ => {}
1871                     }
1872                 }
1873             }
1874
1875             // If there are no more fallbacks to apply at this point we have applied all possible
1876             // defaults and type inference will proceed as normal.
1877             if unbound_tyvars.is_empty() {
1878                 break;
1879             }
1880
1881             // Finally we go through each of the unbound type variables and unify them with
1882             // the proper fallback, reporting a conflicting default error if any of the
1883             // unifications fail. We know it must be a conflicting default because the
1884             // variable would only be in `unbound_tyvars` and have a concrete value if
1885             // it had been solved by previously applying a default.
1886
1887             // We wrap this in a transaction for error reporting, if we detect a conflict
1888             // we will rollback the inference context to its prior state so we can probe
1889             // for conflicts and correctly report them.
1890
1891
1892             let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1893                 for ty in &unbound_tyvars {
1894                     if self.infcx().type_var_diverges(ty) {
1895                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1896                     } else {
1897                         match self.infcx().type_is_unconstrained_numeric(ty) {
1898                             UnconstrainedInt => {
1899                                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1900                             },
1901                             UnconstrainedFloat => {
1902                                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1903                             }
1904                             Neither => {
1905                                 if let Some(default) = default_map.get(ty) {
1906                                     let default = default.clone();
1907                                     match infer::mk_eqty(self.infcx(), false,
1908                                                          infer::Misc(default.origin_span),
1909                                                          ty, default.ty) {
1910                                         Ok(()) => {}
1911                                         Err(_) => {
1912                                             conflicts.push((*ty, default));
1913                                         }
1914                                     }
1915                                 }
1916                             }
1917                         }
1918                     }
1919                 }
1920
1921                 // If there are conflicts we rollback, otherwise commit
1922                 if conflicts.len() > 0 {
1923                     Err(())
1924                 } else {
1925                     Ok(())
1926                 }
1927             });
1928
1929             if conflicts.len() > 0 {
1930                 // Loop through each conflicting default, figuring out the default that caused
1931                 // a unification failure and then report an error for each.
1932                 for (conflict, default) in conflicts {
1933                     let conflicting_default =
1934                         self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1935                             .unwrap_or(type_variable::Default {
1936                                 ty: self.infcx().next_ty_var(),
1937                                 origin_span: codemap::DUMMY_SP,
1938                                 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1939                             });
1940
1941                     // This is to ensure that we elimnate any non-determinism from the error
1942                     // reporting by fixing an order, it doesn't matter what order we choose
1943                     // just that it is consistent.
1944                     let (first_default, second_default) =
1945                         if default.def_id < conflicting_default.def_id {
1946                             (default, conflicting_default)
1947                         } else {
1948                             (conflicting_default, default)
1949                         };
1950
1951
1952                     self.infcx().report_conflicting_default_types(
1953                         first_default.origin_span,
1954                         first_default,
1955                         second_default)
1956                 }
1957             }
1958         }
1959
1960         self.select_obligations_where_possible();
1961     }
1962
1963     // For use in error handling related to default type parameter fallback. We explicitly
1964     // apply the default that caused conflict first to a local version of the type variable
1965     // table then apply defaults until we find a conflict. That default must be the one
1966     // that caused conflict earlier.
1967     fn find_conflicting_default(&self,
1968                                 unbound_vars: &HashSet<Ty<'tcx>>,
1969                                 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1970                                 conflict: Ty<'tcx>)
1971                                 -> Option<type_variable::Default<'tcx>> {
1972         use middle::ty::error::UnconstrainedNumeric::Neither;
1973         use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1974
1975         // Ensure that we apply the conflicting default first
1976         let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1977         unbound_tyvars.push(conflict);
1978         unbound_tyvars.extend(unbound_vars.iter());
1979
1980         let mut result = None;
1981         // We run the same code as above applying defaults in order, this time when
1982         // we find the conflict we just return it for error reporting above.
1983
1984         // We also run this inside snapshot that never commits so we can do error
1985         // reporting for more then one conflict.
1986         for ty in &unbound_tyvars {
1987             if self.infcx().type_var_diverges(ty) {
1988                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1989             } else {
1990                 match self.infcx().type_is_unconstrained_numeric(ty) {
1991                     UnconstrainedInt => {
1992                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1993                     },
1994                     UnconstrainedFloat => {
1995                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1996                     },
1997                     Neither => {
1998                         if let Some(default) = default_map.get(ty) {
1999                             let default = default.clone();
2000                             match infer::mk_eqty(self.infcx(), false,
2001                                                  infer::Misc(default.origin_span),
2002                                                  ty, default.ty) {
2003                                 Ok(()) => {}
2004                                 Err(_) => {
2005                                     result = Some(default);
2006                                 }
2007                             }
2008                         }
2009                     }
2010                 }
2011             }
2012         }
2013
2014         return result;
2015     }
2016
2017     fn select_all_obligations_or_error(&self) {
2018         debug!("select_all_obligations_or_error");
2019
2020         // upvar inference should have ensured that all deferred call
2021         // resolutions are handled by now.
2022         assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2023
2024         self.select_all_obligations_and_apply_defaults();
2025
2026         let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
2027         match fulfillment_cx.select_all_or_error(self.infcx()) {
2028             Ok(()) => { }
2029             Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2030         }
2031     }
2032
2033     /// Select as many obligations as we can at present.
2034     fn select_obligations_where_possible(&self) {
2035         match
2036             self.inh.infcx.fulfillment_cx
2037             .borrow_mut()
2038             .select_where_possible(self.infcx())
2039         {
2040             Ok(()) => { }
2041             Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2042         }
2043     }
2044
2045     /// Try to select any fcx obligation that we haven't tried yet, in an effort
2046     /// to improve inference. You could just call
2047     /// `select_obligations_where_possible` except that it leads to repeated
2048     /// work.
2049     fn select_new_obligations(&self) {
2050         match
2051             self.inh.infcx.fulfillment_cx
2052             .borrow_mut()
2053             .select_new_obligations(self.infcx())
2054         {
2055             Ok(()) => { }
2056             Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2057         }
2058     }
2059
2060 }
2061
2062 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2063     fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2064         Some(self.base_object_lifetime_default(span))
2065     }
2066
2067     fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2068         // RFC #599 specifies that object lifetime defaults take
2069         // precedence over other defaults. But within a fn body we
2070         // don't have a *default* region, rather we use inference to
2071         // find the *correct* region, which is strictly more general
2072         // (and anyway, within a fn body the right region may not even
2073         // be something the user can write explicitly, since it might
2074         // be some expression).
2075         self.infcx().next_region_var(infer::MiscVariable(span))
2076     }
2077
2078     fn anon_regions(&self, span: Span, count: usize)
2079                     -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2080         Ok((0..count).map(|_| {
2081             self.infcx().next_region_var(infer::MiscVariable(span))
2082         }).collect())
2083     }
2084 }
2085
2086 /// Whether `autoderef` requires types to resolve.
2087 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2088 pub enum UnresolvedTypeAction {
2089     /// Produce an error and return `TyError` whenever a type cannot
2090     /// be resolved (i.e. it is `TyInfer`).
2091     Error,
2092     /// Go on without emitting any errors, and return the unresolved
2093     /// type. Useful for probing, e.g. in coercions.
2094     Ignore
2095 }
2096
2097 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2098 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2099 ///
2100 /// Note: this method does not modify the adjustments table. The caller is responsible for
2101 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2102 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2103                                  sp: Span,
2104                                  base_ty: Ty<'tcx>,
2105                                  opt_expr: Option<&hir::Expr>,
2106                                  unresolved_type_action: UnresolvedTypeAction,
2107                                  mut lvalue_pref: LvaluePreference,
2108                                  mut should_stop: F)
2109                                  -> (Ty<'tcx>, usize, Option<T>)
2110     where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2111 {
2112     debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2113            base_ty,
2114            opt_expr,
2115            lvalue_pref);
2116
2117     let mut t = base_ty;
2118     for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2119         let resolved_t = match unresolved_type_action {
2120             UnresolvedTypeAction::Error => {
2121                 structurally_resolved_type(fcx, sp, t)
2122             }
2123             UnresolvedTypeAction::Ignore => {
2124                 // We can continue even when the type cannot be resolved
2125                 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2126                 // and `try_overloaded_deref` both simply return `None`
2127                 // in such a case without producing spurious errors.
2128                 fcx.resolve_type_vars_if_possible(t)
2129             }
2130         };
2131         if resolved_t.references_error() {
2132             return (resolved_t, autoderefs, None);
2133         }
2134
2135         match should_stop(resolved_t, autoderefs) {
2136             Some(x) => return (resolved_t, autoderefs, Some(x)),
2137             None => {}
2138         }
2139
2140         // Otherwise, deref if type is derefable:
2141         let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2142             Some(mt) => Some(mt),
2143             None => {
2144                 let method_call =
2145                     opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2146
2147                 // Super subtle: it might seem as though we should
2148                 // pass `opt_expr` to `try_overloaded_deref`, so that
2149                 // the (implicit) autoref of using an overloaded deref
2150                 // would get added to the adjustment table. However we
2151                 // do not do that, because it's kind of a
2152                 // "meta-adjustment" -- instead, we just leave it
2153                 // unrecorded and know that there "will be" an
2154                 // autoref. regionck and other bits of the code base,
2155                 // when they encounter an overloaded autoderef, have
2156                 // to do some reconstructive surgery. This is a pretty
2157                 // complex mess that is begging for a proper MIR.
2158                 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2159             }
2160         };
2161         match mt {
2162             Some(mt) => {
2163                 t = mt.ty;
2164                 if mt.mutbl == hir::MutImmutable {
2165                     lvalue_pref = NoPreference;
2166                 }
2167             }
2168             None => return (resolved_t, autoderefs, None)
2169         }
2170     }
2171
2172     // We've reached the recursion limit, error gracefully.
2173     span_err!(fcx.tcx().sess, sp, E0055,
2174         "reached the recursion limit while auto-dereferencing {:?}",
2175         base_ty);
2176     (fcx.tcx().types.err, 0, None)
2177 }
2178
2179 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2180                                   span: Span,
2181                                   method_call: Option<MethodCall>,
2182                                   base_expr: Option<&hir::Expr>,
2183                                   base_ty: Ty<'tcx>,
2184                                   lvalue_pref: LvaluePreference)
2185                                   -> Option<ty::TypeAndMut<'tcx>>
2186 {
2187     // Try DerefMut first, if preferred.
2188     let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2189         (PreferMutLvalue, Some(trait_did)) => {
2190             method::lookup_in_trait(fcx, span, base_expr,
2191                                     token::intern("deref_mut"), trait_did,
2192                                     base_ty, None)
2193         }
2194         _ => None
2195     };
2196
2197     // Otherwise, fall back to Deref.
2198     let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2199         (None, Some(trait_did)) => {
2200             method::lookup_in_trait(fcx, span, base_expr,
2201                                     token::intern("deref"), trait_did,
2202                                     base_ty, None)
2203         }
2204         (method, _) => method
2205     };
2206
2207     make_overloaded_lvalue_return_type(fcx, method_call, method)
2208 }
2209
2210 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2211 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2212 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2213 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2214                                                 method_call: Option<MethodCall>,
2215                                                 method: Option<MethodCallee<'tcx>>)
2216                                                 -> Option<ty::TypeAndMut<'tcx>>
2217 {
2218     match method {
2219         Some(method) => {
2220             // extract method return type, which will be &T;
2221             // all LB regions should have been instantiated during method lookup
2222             let ret_ty = method.ty.fn_ret();
2223             let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2224
2225             if let Some(method_call) = method_call {
2226                 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2227             }
2228
2229             // method returns &T, but the type as visible to user is T, so deref
2230             ret_ty.builtin_deref(true, NoPreference)
2231         }
2232         None => None,
2233     }
2234 }
2235
2236 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2237                              expr: &hir::Expr,
2238                              base_expr: &'tcx hir::Expr,
2239                              base_ty: Ty<'tcx>,
2240                              idx_ty: Ty<'tcx>,
2241                              lvalue_pref: LvaluePreference)
2242                              -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2243 {
2244     // FIXME(#18741) -- this is almost but not quite the same as the
2245     // autoderef that normal method probing does. They could likely be
2246     // consolidated.
2247
2248     let (ty, autoderefs, final_mt) = autoderef(fcx,
2249                                                base_expr.span,
2250                                                base_ty,
2251                                                Some(base_expr),
2252                                                UnresolvedTypeAction::Error,
2253                                                lvalue_pref,
2254                                                |adj_ty, idx| {
2255         try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2256                        adj_ty, idx, false, lvalue_pref, idx_ty)
2257     });
2258
2259     if final_mt.is_some() {
2260         return final_mt;
2261     }
2262
2263     // After we have fully autoderef'd, if the resulting type is [T; n], then
2264     // do a final unsized coercion to yield [T].
2265     if let ty::TyArray(element_ty, _) = ty.sty {
2266         let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2267         try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2268                        adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2269     } else {
2270         None
2271     }
2272 }
2273
2274 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2275 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2276 /// This loop implements one step in that search; the autoderef loop is implemented by
2277 /// `lookup_indexing`.
2278 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2279                             method_call: MethodCall,
2280                             expr: &hir::Expr,
2281                             base_expr: &'tcx hir::Expr,
2282                             adjusted_ty: Ty<'tcx>,
2283                             autoderefs: usize,
2284                             unsize: bool,
2285                             lvalue_pref: LvaluePreference,
2286                             index_ty: Ty<'tcx>)
2287                             -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2288 {
2289     let tcx = fcx.tcx();
2290     debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2291                            autoderefs={}, unsize={}, index_ty={:?})",
2292            expr,
2293            base_expr,
2294            adjusted_ty,
2295            autoderefs,
2296            unsize,
2297            index_ty);
2298
2299     let input_ty = fcx.infcx().next_ty_var();
2300
2301     // First, try built-in indexing.
2302     match (adjusted_ty.builtin_index(), &index_ty.sty) {
2303         (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2304             debug!("try_index_step: success, using built-in indexing");
2305             // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2306             assert!(!unsize);
2307             fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2308             return Some((tcx.types.usize, ty));
2309         }
2310         _ => {}
2311     }
2312
2313     // Try `IndexMut` first, if preferred.
2314     let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2315         (PreferMutLvalue, Some(trait_did)) => {
2316             method::lookup_in_trait_adjusted(fcx,
2317                                              expr.span,
2318                                              Some(&*base_expr),
2319                                              token::intern("index_mut"),
2320                                              trait_did,
2321                                              autoderefs,
2322                                              unsize,
2323                                              adjusted_ty,
2324                                              Some(vec![input_ty]))
2325         }
2326         _ => None,
2327     };
2328
2329     // Otherwise, fall back to `Index`.
2330     let method = match (method, tcx.lang_items.index_trait()) {
2331         (None, Some(trait_did)) => {
2332             method::lookup_in_trait_adjusted(fcx,
2333                                              expr.span,
2334                                              Some(&*base_expr),
2335                                              token::intern("index"),
2336                                              trait_did,
2337                                              autoderefs,
2338                                              unsize,
2339                                              adjusted_ty,
2340                                              Some(vec![input_ty]))
2341         }
2342         (method, _) => method,
2343     };
2344
2345     // If some lookup succeeds, write callee into table and extract index/element
2346     // type from the method signature.
2347     // If some lookup succeeded, install method in table
2348     method.and_then(|method| {
2349         debug!("try_index_step: success, using overloaded indexing");
2350         make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2351             map(|ret| (input_ty, ret.ty))
2352     })
2353 }
2354
2355 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2356                                          sp: Span,
2357                                          method_fn_ty: Ty<'tcx>,
2358                                          callee_expr: &'tcx hir::Expr,
2359                                          args_no_rcvr: &'tcx [P<hir::Expr>],
2360                                          tuple_arguments: TupleArgumentsFlag,
2361                                          expected: Expectation<'tcx>)
2362                                          -> ty::FnOutput<'tcx> {
2363     if method_fn_ty.references_error() {
2364         let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2365
2366         let err_inputs = match tuple_arguments {
2367             DontTupleArguments => err_inputs,
2368             TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2369         };
2370
2371         check_argument_types(fcx,
2372                              sp,
2373                              &err_inputs[..],
2374                              &[],
2375                              args_no_rcvr,
2376                              false,
2377                              tuple_arguments);
2378         ty::FnConverging(fcx.tcx().types.err)
2379     } else {
2380         match method_fn_ty.sty {
2381             ty::TyBareFn(_, ref fty) => {
2382                 // HACK(eddyb) ignore self in the definition (see above).
2383                 let expected_arg_tys = expected_types_for_fn_args(fcx,
2384                                                                   sp,
2385                                                                   expected,
2386                                                                   fty.sig.0.output,
2387                                                                   &fty.sig.0.inputs[1..]);
2388                 check_argument_types(fcx,
2389                                      sp,
2390                                      &fty.sig.0.inputs[1..],
2391                                      &expected_arg_tys[..],
2392                                      args_no_rcvr,
2393                                      fty.sig.0.variadic,
2394                                      tuple_arguments);
2395                 fty.sig.0.output
2396             }
2397             _ => {
2398                 fcx.tcx().sess.span_bug(callee_expr.span,
2399                                         "method without bare fn type");
2400             }
2401         }
2402     }
2403 }
2404
2405 /// Generic function that factors out common logic from function calls, method calls and overloaded
2406 /// operators.
2407 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2408                                   sp: Span,
2409                                   fn_inputs: &[Ty<'tcx>],
2410                                   expected_arg_tys: &[Ty<'tcx>],
2411                                   args: &'tcx [P<hir::Expr>],
2412                                   variadic: bool,
2413                                   tuple_arguments: TupleArgumentsFlag) {
2414     let tcx = fcx.ccx.tcx;
2415
2416     // Grab the argument types, supplying fresh type variables
2417     // if the wrong number of arguments were supplied
2418     let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2419         args.len()
2420     } else {
2421         1
2422     };
2423
2424     // All the input types from the fn signature must outlive the call
2425     // so as to validate implied bounds.
2426     for &fn_input_ty in fn_inputs {
2427         fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2428     }
2429
2430     let mut expected_arg_tys = expected_arg_tys;
2431     let expected_arg_count = fn_inputs.len();
2432     let formal_tys = if tuple_arguments == TupleArguments {
2433         let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2434         match tuple_type.sty {
2435             ty::TyTuple(ref arg_types) => {
2436                 if arg_types.len() != args.len() {
2437                     span_err!(tcx.sess, sp, E0057,
2438                         "this function takes {} parameter{} but {} parameter{} supplied",
2439                         arg_types.len(),
2440                         if arg_types.len() == 1 {""} else {"s"},
2441                         args.len(),
2442                         if args.len() == 1 {" was"} else {"s were"});
2443                     expected_arg_tys = &[];
2444                     err_args(fcx.tcx(), args.len())
2445                 } else {
2446                     expected_arg_tys = match expected_arg_tys.get(0) {
2447                         Some(&ty) => match ty.sty {
2448                             ty::TyTuple(ref tys) => &**tys,
2449                             _ => &[]
2450                         },
2451                         None => &[]
2452                     };
2453                     (*arg_types).clone()
2454                 }
2455             }
2456             _ => {
2457                 span_err!(tcx.sess, sp, E0059,
2458                     "cannot use call notation; the first type parameter \
2459                      for the function trait is neither a tuple nor unit");
2460                 expected_arg_tys = &[];
2461                 err_args(fcx.tcx(), args.len())
2462             }
2463         }
2464     } else if expected_arg_count == supplied_arg_count {
2465         fn_inputs.to_vec()
2466     } else if variadic {
2467         if supplied_arg_count >= expected_arg_count {
2468             fn_inputs.to_vec()
2469         } else {
2470             span_err!(tcx.sess, sp, E0060,
2471                 "this function takes at least {} parameter{} \
2472                  but {} parameter{} supplied",
2473                 expected_arg_count,
2474                 if expected_arg_count == 1 {""} else {"s"},
2475                 supplied_arg_count,
2476                 if supplied_arg_count == 1 {" was"} else {"s were"});
2477             expected_arg_tys = &[];
2478             err_args(fcx.tcx(), supplied_arg_count)
2479         }
2480     } else {
2481         span_err!(tcx.sess, sp, E0061,
2482             "this function takes {} parameter{} but {} parameter{} supplied",
2483             expected_arg_count,
2484             if expected_arg_count == 1 {""} else {"s"},
2485             supplied_arg_count,
2486             if supplied_arg_count == 1 {" was"} else {"s were"});
2487         expected_arg_tys = &[];
2488         err_args(fcx.tcx(), supplied_arg_count)
2489     };
2490
2491     debug!("check_argument_types: formal_tys={:?}",
2492            formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2493
2494     // Check the arguments.
2495     // We do this in a pretty awful way: first we typecheck any arguments
2496     // that are not anonymous functions, then we typecheck the anonymous
2497     // functions. This is so that we have more information about the types
2498     // of arguments when we typecheck the functions. This isn't really the
2499     // right way to do this.
2500     let xs = [false, true];
2501     for check_blocks in &xs {
2502         let check_blocks = *check_blocks;
2503         debug!("check_blocks={}", check_blocks);
2504
2505         // More awful hacks: before we check argument types, try to do
2506         // an "opportunistic" vtable resolution of any trait bounds on
2507         // the call. This helps coercions.
2508         if check_blocks {
2509             fcx.select_new_obligations();
2510         }
2511
2512         // For variadic functions, we don't have a declared type for all of
2513         // the arguments hence we only do our usual type checking with
2514         // the arguments who's types we do know.
2515         let t = if variadic {
2516             expected_arg_count
2517         } else if tuple_arguments == TupleArguments {
2518             args.len()
2519         } else {
2520             supplied_arg_count
2521         };
2522         for (i, arg) in args.iter().take(t).enumerate() {
2523             let is_block = match arg.node {
2524                 hir::ExprClosure(..) => true,
2525                 _ => false
2526             };
2527
2528             if is_block == check_blocks {
2529                 debug!("checking the argument");
2530                 let formal_ty = formal_tys[i];
2531
2532                 // The special-cased logic below has three functions:
2533                 // 1. Provide as good of an expected type as possible.
2534                 let expected = expected_arg_tys.get(i).map(|&ty| {
2535                     Expectation::rvalue_hint(fcx.tcx(), ty)
2536                 });
2537
2538                 check_expr_with_unifier(fcx,
2539                                         &**arg,
2540                                         expected.unwrap_or(ExpectHasType(formal_ty)),
2541                                         NoPreference, || {
2542                     // 2. Coerce to the most detailed type that could be coerced
2543                     //    to, which is `expected_ty` if `rvalue_hint` returns an
2544                     //    `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2545                     let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2546                     demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2547
2548                     // 3. Relate the expected type and the formal one,
2549                     //    if the expected type was used for the coercion.
2550                     coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2551                 });
2552             }
2553         }
2554     }
2555
2556     // We also need to make sure we at least write the ty of the other
2557     // arguments which we skipped above.
2558     if variadic {
2559         for arg in args.iter().skip(expected_arg_count) {
2560             check_expr(fcx, &**arg);
2561
2562             // There are a few types which get autopromoted when passed via varargs
2563             // in C but we just error out instead and require explicit casts.
2564             let arg_ty = structurally_resolved_type(fcx, arg.span,
2565                                                     fcx.expr_ty(&**arg));
2566             match arg_ty.sty {
2567                 ty::TyFloat(ast::TyF32) => {
2568                     fcx.type_error_message(arg.span,
2569                                            |t| {
2570                         format!("can't pass an {} to variadic \
2571                                  function, cast to c_double", t)
2572                     }, arg_ty, None);
2573                 }
2574                 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2575                     fcx.type_error_message(arg.span, |t| {
2576                         format!("can't pass {} to variadic \
2577                                  function, cast to c_int",
2578                                        t)
2579                     }, arg_ty, None);
2580                 }
2581                 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2582                     fcx.type_error_message(arg.span, |t| {
2583                         format!("can't pass {} to variadic \
2584                                  function, cast to c_uint",
2585                                        t)
2586                     }, arg_ty, None);
2587                 }
2588                 _ => {}
2589             }
2590         }
2591     }
2592 }
2593
2594 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2595 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2596     (0..len).map(|_| tcx.types.err).collect()
2597 }
2598
2599 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2600                         call_expr: &hir::Expr,
2601                         output: ty::FnOutput<'tcx>) {
2602     fcx.write_ty(call_expr.id, match output {
2603         ty::FnConverging(output_ty) => output_ty,
2604         ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2605     });
2606 }
2607
2608 // AST fragment checking
2609 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2610                        lit: &ast::Lit,
2611                        expected: Expectation<'tcx>)
2612                        -> Ty<'tcx>
2613 {
2614     let tcx = fcx.ccx.tcx;
2615
2616     match lit.node {
2617         ast::LitStr(..) => tcx.mk_static_str(),
2618         ast::LitByteStr(ref v) => {
2619             tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2620                             tcx.mk_array(tcx.types.u8, v.len()))
2621         }
2622         ast::LitByte(_) => tcx.types.u8,
2623         ast::LitChar(_) => tcx.types.char,
2624         ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2625         ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2626         ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2627             let opt_ty = expected.to_option(fcx).and_then(|ty| {
2628                 match ty.sty {
2629                     ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2630                     ty::TyChar => Some(tcx.types.u8),
2631                     ty::TyRawPtr(..) => Some(tcx.types.usize),
2632                     ty::TyBareFn(..) => Some(tcx.types.usize),
2633                     _ => None
2634                 }
2635             });
2636             opt_ty.unwrap_or_else(
2637                 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2638         }
2639         ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2640         ast::LitFloatUnsuffixed(_) => {
2641             let opt_ty = expected.to_option(fcx).and_then(|ty| {
2642                 match ty.sty {
2643                     ty::TyFloat(_) => Some(ty),
2644                     _ => None
2645                 }
2646             });
2647             opt_ty.unwrap_or_else(
2648                 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2649         }
2650         ast::LitBool(_) => tcx.types.bool
2651     }
2652 }
2653
2654 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2655                                      expr: &'tcx hir::Expr,
2656                                      expected: Ty<'tcx>) {
2657     check_expr_with_unifier(
2658         fcx, expr, ExpectHasType(expected), NoPreference,
2659         || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2660 }
2661
2662 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2663                                           expr: &'tcx hir::Expr,
2664                                           expected: Ty<'tcx>) {
2665     check_expr_with_unifier(
2666         fcx, expr, ExpectHasType(expected), NoPreference,
2667         || demand::coerce(fcx, expr.span, expected, expr));
2668 }
2669
2670 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2671                                   expected: Ty<'tcx>) {
2672     check_expr_with_unifier(
2673         fcx, expr, ExpectHasType(expected), NoPreference,
2674         || ())
2675 }
2676
2677 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2678                                          expr: &'tcx hir::Expr,
2679                                          expected: Expectation<'tcx>) {
2680     check_expr_with_unifier(
2681         fcx, expr, expected, NoPreference,
2682         || ())
2683 }
2684
2685 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2686                                                          expr: &'tcx hir::Expr,
2687                                                          expected: Expectation<'tcx>,
2688                                                          lvalue_pref: LvaluePreference)
2689 {
2690     check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2691 }
2692
2693 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr)  {
2694     check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2695 }
2696
2697 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2698                                         lvalue_pref: LvaluePreference)  {
2699     check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2700 }
2701
2702 // determine the `self` type, using fresh variables for all variables
2703 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2704 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2705 // variables.
2706 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2707                               span: Span, // (potential) receiver for this impl
2708                               did: DefId)
2709                               -> TypeAndSubsts<'tcx> {
2710     let tcx = fcx.tcx();
2711
2712     let ity = tcx.lookup_item_type(did);
2713     let (tps, rps, raw_ty) =
2714         (ity.generics.types.get_slice(subst::TypeSpace),
2715          ity.generics.regions.get_slice(subst::TypeSpace),
2716          ity.ty);
2717
2718     debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2719
2720     let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2721     let mut substs = subst::Substs::new(
2722         VecPerParamSpace::empty(),
2723         VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2724     fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2725     let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2726
2727     TypeAndSubsts { substs: substs, ty: substd_ty }
2728 }
2729
2730 /// Controls whether the arguments are tupled. This is used for the call
2731 /// operator.
2732 ///
2733 /// Tupling means that all call-side arguments are packed into a tuple and
2734 /// passed as a single parameter. For example, if tupling is enabled, this
2735 /// function:
2736 ///
2737 ///     fn f(x: (isize, isize))
2738 ///
2739 /// Can be called as:
2740 ///
2741 ///     f(1, 2);
2742 ///
2743 /// Instead of:
2744 ///
2745 ///     f((1, 2));
2746 #[derive(Clone, Eq, PartialEq)]
2747 enum TupleArgumentsFlag {
2748     DontTupleArguments,
2749     TupleArguments,
2750 }
2751
2752 /// Unifies the return type with the expected type early, for more coercions
2753 /// and forward type information on the argument expressions.
2754 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2755                                         call_span: Span,
2756                                         expected_ret: Expectation<'tcx>,
2757                                         formal_ret: ty::FnOutput<'tcx>,
2758                                         formal_args: &[Ty<'tcx>])
2759                                         -> Vec<Ty<'tcx>> {
2760     let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2761         if let ty::FnConverging(formal_ret_ty) = formal_ret {
2762             fcx.infcx().commit_regions_if_ok(|| {
2763                 // Attempt to apply a subtyping relationship between the formal
2764                 // return type (likely containing type variables if the function
2765                 // is polymorphic) and the expected return type.
2766                 // No argument expectations are produced if unification fails.
2767                 let origin = infer::Misc(call_span);
2768                 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2769                 // FIXME(#15760) can't use try! here, FromError doesn't default
2770                 // to identity so the resulting type is not constrained.
2771                 if let Err(e) = ures {
2772                     return Err(e);
2773                 }
2774
2775                 // Record all the argument types, with the substitutions
2776                 // produced from the above subtyping unification.
2777                 Ok(formal_args.iter().map(|ty| {
2778                     fcx.infcx().resolve_type_vars_if_possible(ty)
2779                 }).collect())
2780             }).ok()
2781         } else {
2782             None
2783         }
2784     }).unwrap_or(vec![]);
2785     debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2786            formal_args, formal_ret,
2787            expected_args, expected_ret);
2788     expected_args
2789 }
2790
2791 /// Invariant:
2792 /// If an expression has any sub-expressions that result in a type error,
2793 /// inspecting that expression's type with `ty.references_error()` will return
2794 /// true. Likewise, if an expression is known to diverge, inspecting its
2795 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2796 /// strict, _|_ can appear in the type of an expression that does not,
2797 /// itself, diverge: for example, fn() -> _|_.)
2798 /// Note that inspecting a type's structure *directly* may expose the fact
2799 /// that there are actually multiple representations for `TyError`, so avoid
2800 /// that when err needs to be handled differently.
2801 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2802                                         expr: &'tcx hir::Expr,
2803                                         expected: Expectation<'tcx>,
2804                                         lvalue_pref: LvaluePreference,
2805                                         unifier: F) where
2806     F: FnOnce(),
2807 {
2808     debug!(">> typechecking: expr={:?} expected={:?}",
2809            expr, expected);
2810
2811     // Checks a method call.
2812     fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2813                                    expr: &'tcx hir::Expr,
2814                                    method_name: Spanned<ast::Name>,
2815                                    args: &'tcx [P<hir::Expr>],
2816                                    tps: &[P<hir::Ty>],
2817                                    expected: Expectation<'tcx>,
2818                                    lvalue_pref: LvaluePreference) {
2819         let rcvr = &*args[0];
2820         check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2821
2822         // no need to check for bot/err -- callee does that
2823         let expr_t = structurally_resolved_type(fcx,
2824                                                 expr.span,
2825                                                 fcx.expr_ty(&*rcvr));
2826
2827         let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2828         let fn_ty = match method::lookup(fcx,
2829                                          method_name.span,
2830                                          method_name.node,
2831                                          expr_t,
2832                                          tps,
2833                                          expr,
2834                                          rcvr) {
2835             Ok(method) => {
2836                 let method_ty = method.ty;
2837                 let method_call = MethodCall::expr(expr.id);
2838                 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2839                 method_ty
2840             }
2841             Err(error) => {
2842                 method::report_error(fcx, method_name.span, expr_t,
2843                                      method_name.node, Some(rcvr), error);
2844                 fcx.write_error(expr.id);
2845                 fcx.tcx().types.err
2846             }
2847         };
2848
2849         // Call the generic checker.
2850         let ret_ty = check_method_argument_types(fcx,
2851                                                  method_name.span,
2852                                                  fn_ty,
2853                                                  expr,
2854                                                  &args[1..],
2855                                                  DontTupleArguments,
2856                                                  expected);
2857
2858         write_call(fcx, expr, ret_ty);
2859     }
2860
2861     // A generic function for checking the then and else in an if
2862     // or if-else.
2863     fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2864                                  cond_expr: &'tcx hir::Expr,
2865                                  then_blk: &'tcx hir::Block,
2866                                  opt_else_expr: Option<&'tcx hir::Expr>,
2867                                  id: ast::NodeId,
2868                                  sp: Span,
2869                                  expected: Expectation<'tcx>) {
2870         check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2871
2872         let expected = expected.adjust_for_branches(fcx);
2873         check_block_with_expected(fcx, then_blk, expected);
2874         let then_ty = fcx.node_ty(then_blk.id);
2875
2876         let branches_ty = match opt_else_expr {
2877             Some(ref else_expr) => {
2878                 check_expr_with_expectation(fcx, &**else_expr, expected);
2879                 let else_ty = fcx.expr_ty(&**else_expr);
2880                 infer::common_supertype(fcx.infcx(),
2881                                         infer::IfExpression(sp),
2882                                         true,
2883                                         then_ty,
2884                                         else_ty)
2885             }
2886             None => {
2887                 infer::common_supertype(fcx.infcx(),
2888                                         infer::IfExpressionWithNoElse(sp),
2889                                         false,
2890                                         then_ty,
2891                                         fcx.tcx().mk_nil())
2892             }
2893         };
2894
2895         let cond_ty = fcx.expr_ty(cond_expr);
2896         let if_ty = if cond_ty.references_error() {
2897             fcx.tcx().types.err
2898         } else {
2899             branches_ty
2900         };
2901
2902         fcx.write_ty(id, if_ty);
2903     }
2904
2905     // Check field access expressions
2906     fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2907                             expr: &'tcx hir::Expr,
2908                             lvalue_pref: LvaluePreference,
2909                             base: &'tcx hir::Expr,
2910                             field: &Spanned<ast::Name>) {
2911         let tcx = fcx.ccx.tcx;
2912         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2913         let expr_t = structurally_resolved_type(fcx, expr.span,
2914                                                 fcx.expr_ty(base));
2915         // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2916         let (_, autoderefs, field_ty) = autoderef(fcx,
2917                                                   expr.span,
2918                                                   expr_t,
2919                                                   Some(base),
2920                                                   UnresolvedTypeAction::Error,
2921                                                   lvalue_pref,
2922                                                   |base_t, _| {
2923                 match base_t.sty {
2924                     ty::TyStruct(base_def, substs) => {
2925                         debug!("struct named {:?}",  base_t);
2926                         base_def.struct_variant()
2927                                 .find_field_named(field.node)
2928                                 .map(|f| fcx.field_ty(expr.span, f, substs))
2929                     }
2930                     _ => None
2931                 }
2932             });
2933         match field_ty {
2934             Some(field_ty) => {
2935                 fcx.write_ty(expr.id, field_ty);
2936                 fcx.write_autoderef_adjustment(base.id, autoderefs);
2937                 return;
2938             }
2939             None => {}
2940         }
2941
2942         if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2943             fcx.type_error_message(
2944                 field.span,
2945                 |actual| {
2946                     format!("attempted to take value of method `{}` on type \
2947                             `{}`", field.node, actual)
2948                 },
2949                 expr_t, None);
2950
2951             tcx.sess.fileline_help(field.span,
2952                                "maybe a `()` to call it is missing? \
2953                                If not, try an anonymous function");
2954         } else {
2955             fcx.type_error_message(
2956                 expr.span,
2957                 |actual| {
2958                     format!("attempted access of field `{}` on \
2959                             type `{}`, but no field with that \
2960                             name was found",
2961                             field.node,
2962                             actual)
2963                 },
2964                 expr_t, None);
2965             if let ty::TyStruct(def, _) = expr_t.sty {
2966                 suggest_field_names(def.struct_variant(), field, tcx, vec![]);
2967             }
2968         }
2969
2970         fcx.write_error(expr.id);
2971     }
2972
2973     // displays hints about the closest matches in field names
2974     fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
2975                                  field: &Spanned<ast::Name>,
2976                                  tcx: &ty::ctxt<'tcx>,
2977                                  skip : Vec<InternedString>) {
2978         let name = field.node.as_str();
2979         // only find fits with at least one matching letter
2980         let mut best_dist = name.len();
2981         let mut best = None;
2982         for elem in &variant.fields {
2983             let n = elem.name.as_str();
2984             // ignore already set fields
2985             if skip.iter().any(|x| *x == n) {
2986                 continue;
2987             }
2988             // ignore private fields from non-local crates
2989             if variant.did.krate != LOCAL_CRATE && elem.vis != Visibility::Public {
2990                 continue;
2991             }
2992             let dist = lev_distance(&n, &name);
2993             if dist < best_dist {
2994                 best = Some(n);
2995                 best_dist = dist;
2996             }
2997         }
2998         if let Some(n) = best {
2999             tcx.sess.span_help(field.span,
3000                 &format!("did you mean `{}`?", n));
3001         }
3002     }
3003
3004     // Check tuple index expressions
3005     fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3006                                 expr: &'tcx hir::Expr,
3007                                 lvalue_pref: LvaluePreference,
3008                                 base: &'tcx hir::Expr,
3009                                 idx: codemap::Spanned<usize>) {
3010         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3011         let expr_t = structurally_resolved_type(fcx, expr.span,
3012                                                 fcx.expr_ty(base));
3013         let mut tuple_like = false;
3014         // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3015         let (_, autoderefs, field_ty) = autoderef(fcx,
3016                                                   expr.span,
3017                                                   expr_t,
3018                                                   Some(base),
3019                                                   UnresolvedTypeAction::Error,
3020                                                   lvalue_pref,
3021                                                   |base_t, _| {
3022                 match base_t.sty {
3023                     ty::TyStruct(base_def, substs) => {
3024                         tuple_like = base_def.struct_variant().is_tuple_struct();
3025                         if tuple_like {
3026                             debug!("tuple struct named {:?}",  base_t);
3027                             base_def.struct_variant()
3028                                     .fields
3029                                     .get(idx.node)
3030                                     .map(|f| fcx.field_ty(expr.span, f, substs))
3031                         } else {
3032                             None
3033                         }
3034                     }
3035                     ty::TyTuple(ref v) => {
3036                         tuple_like = true;
3037                         if idx.node < v.len() { Some(v[idx.node]) } else { None }
3038                     }
3039                     _ => None
3040                 }
3041             });
3042         match field_ty {
3043             Some(field_ty) => {
3044                 fcx.write_ty(expr.id, field_ty);
3045                 fcx.write_autoderef_adjustment(base.id, autoderefs);
3046                 return;
3047             }
3048             None => {}
3049         }
3050         fcx.type_error_message(
3051             expr.span,
3052             |actual| {
3053                 if tuple_like {
3054                     format!("attempted out-of-bounds tuple index `{}` on \
3055                                     type `{}`",
3056                                    idx.node,
3057                                    actual)
3058                 } else {
3059                     format!("attempted tuple index `{}` on type `{}`, but the \
3060                                      type was not a tuple or tuple struct",
3061                                     idx.node,
3062                                     actual)
3063                 }
3064             },
3065             expr_t, None);
3066
3067         fcx.write_error(expr.id);
3068     }
3069
3070     fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3071                                       ty: Ty<'tcx>,
3072                                       variant: ty::VariantDef<'tcx>,
3073                                       field: &hir::Field,
3074                                       skip_fields: &[hir::Field]) {
3075         fcx.type_error_message(
3076             field.name.span,
3077             |actual| if let ty::TyEnum(..) = ty.sty {
3078                 format!("struct variant `{}::{}` has no field named `{}`",
3079                         actual, variant.name.as_str(), field.name.node)
3080             } else {
3081                 format!("structure `{}` has no field named `{}`",
3082                         actual, field.name.node)
3083             },
3084             ty,
3085             None);
3086         // prevent all specified fields from being suggested
3087         let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3088         suggest_field_names(variant, &field.name, fcx.tcx(), skip_fields.collect());
3089     }
3090
3091     fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3092                                           adt_ty: Ty<'tcx>,
3093                                           span: Span,
3094                                           variant: ty::VariantDef<'tcx>,
3095                                           ast_fields: &'tcx [hir::Field],
3096                                           check_completeness: bool) {
3097         let tcx = fcx.ccx.tcx;
3098         let substs = match adt_ty.sty {
3099             ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3100             _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3101         };
3102
3103         let mut remaining_fields = FnvHashMap();
3104         for field in &variant.fields {
3105             remaining_fields.insert(field.name, field);
3106         }
3107
3108         let mut error_happened = false;
3109
3110         // Typecheck each field.
3111         for field in ast_fields {
3112             let expected_field_type;
3113
3114             if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3115                 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3116             } else {
3117                 error_happened = true;
3118                 expected_field_type = tcx.types.err;
3119                 if let Some(_) = variant.find_field_named(field.name.node) {
3120                     span_err!(fcx.tcx().sess, field.name.span, E0062,
3121                         "field `{}` specified more than once",
3122                         field.name.node);
3123                 } else {
3124                     report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3125                 }
3126             }
3127
3128             // Make sure to give a type to the field even if there's
3129             // an error, so we can continue typechecking
3130             check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3131         }
3132
3133             // Make sure the programmer specified all the fields.
3134         if check_completeness &&
3135             !error_happened &&
3136             !remaining_fields.is_empty()
3137         {
3138             span_err!(tcx.sess, span, E0063,
3139                       "missing field{}: {}",
3140                       if remaining_fields.len() == 1 {""} else {"s"},
3141                       remaining_fields.keys()
3142                                       .map(|n| format!("`{}`", n))
3143                                       .collect::<Vec<_>>()
3144                                       .join(", "));
3145         }
3146
3147     }
3148
3149     fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3150                                              id: ast::NodeId,
3151                                              fields: &'tcx [hir::Field],
3152                                              base_expr: &'tcx Option<P<hir::Expr>>) {
3153         // Make sure to still write the types
3154         // otherwise we might ICE
3155         fcx.write_error(id);
3156         for field in fields {
3157             check_expr(fcx, &*field.expr);
3158         }
3159         match *base_expr {
3160             Some(ref base) => check_expr(fcx, &**base),
3161             None => {}
3162         }
3163     }
3164
3165     fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3166                                    expr: &hir::Expr,
3167                                    path: &hir::Path,
3168                                    fields: &'tcx [hir::Field],
3169                                    base_expr: &'tcx Option<P<hir::Expr>>)
3170     {
3171         let tcx = fcx.tcx();
3172
3173         // Find the relevant variant
3174         let def = lookup_full_def(tcx, path.span, expr.id);
3175         let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3176             Some((adt, variant)) => (adt, variant),
3177             None => {
3178                 span_err!(fcx.tcx().sess, path.span, E0071,
3179                           "`{}` does not name a structure",
3180                           pprust::path_to_string(path));
3181                 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3182                 return;
3183             }
3184         };
3185
3186         let expr_ty = fcx.instantiate_type(def.def_id(), path);
3187         fcx.write_ty(expr.id, expr_ty);
3188
3189         check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3190                                  base_expr.is_none());
3191
3192         if let &Some(ref base_expr) = base_expr {
3193             check_expr_has_type(fcx, base_expr, expr_ty);
3194             if adt.adt_kind() == ty::AdtKind::Enum {
3195                 span_err!(tcx.sess, base_expr.span, E0436,
3196                           "functional record update syntax requires a struct");
3197             }
3198         }
3199     }
3200
3201     type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3202
3203     let tcx = fcx.ccx.tcx;
3204     let id = expr.id;
3205     match expr.node {
3206       hir::ExprBox(ref subexpr) => {
3207         let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3208             match ty.sty {
3209                 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3210                 _ => NoExpectation
3211             }
3212         });
3213         check_expr_with_expectation(fcx, subexpr, expected_inner);
3214         let referent_ty = fcx.expr_ty(&**subexpr);
3215         fcx.write_ty(id, tcx.mk_box(referent_ty));
3216       }
3217
3218       hir::ExprLit(ref lit) => {
3219         let typ = check_lit(fcx, &**lit, expected);
3220         fcx.write_ty(id, typ);
3221       }
3222       hir::ExprBinary(op, ref lhs, ref rhs) => {
3223         op::check_binop(fcx, expr, op, lhs, rhs);
3224       }
3225       hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3226         op::check_binop_assign(fcx, expr, op, lhs, rhs);
3227       }
3228       hir::ExprUnary(unop, ref oprnd) => {
3229         let expected_inner = match unop {
3230             hir::UnNot | hir::UnNeg => {
3231                 expected
3232             }
3233             hir::UnDeref => {
3234                 NoExpectation
3235             }
3236         };
3237         let lvalue_pref = match unop {
3238             hir::UnDeref => lvalue_pref,
3239             _ => NoPreference
3240         };
3241         check_expr_with_expectation_and_lvalue_pref(
3242             fcx, &**oprnd, expected_inner, lvalue_pref);
3243         let mut oprnd_t = fcx.expr_ty(&**oprnd);
3244
3245         if !oprnd_t.references_error() {
3246             match unop {
3247                 hir::UnDeref => {
3248                     oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3249                     oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3250                         Some(mt) => mt.ty,
3251                         None => match try_overloaded_deref(fcx, expr.span,
3252                                                            Some(MethodCall::expr(expr.id)),
3253                                                            Some(&**oprnd), oprnd_t, lvalue_pref) {
3254                             Some(mt) => mt.ty,
3255                             None => {
3256                                 fcx.type_error_message(expr.span, |actual| {
3257                                     format!("type `{}` cannot be \
3258                                             dereferenced", actual)
3259                                 }, oprnd_t, None);
3260                                 tcx.types.err
3261                             }
3262                         }
3263                     };
3264                 }
3265                 hir::UnNot => {
3266                     oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3267                                                          oprnd_t);
3268                     if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3269                         oprnd_t = op::check_user_unop(fcx, "!", "not",
3270                                                       tcx.lang_items.not_trait(),
3271                                                       expr, &**oprnd, oprnd_t, unop);
3272                     }
3273                 }
3274                 hir::UnNeg => {
3275                     oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3276                                                          oprnd_t);
3277                     if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3278                         oprnd_t = op::check_user_unop(fcx, "-", "neg",
3279                                                       tcx.lang_items.neg_trait(),
3280                                                       expr, &**oprnd, oprnd_t, unop);
3281                     }
3282                 }
3283             }
3284         }
3285         fcx.write_ty(id, oprnd_t);
3286       }
3287       hir::ExprAddrOf(mutbl, ref oprnd) => {
3288         let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3289             match ty.sty {
3290                 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3291                     if fcx.tcx().expr_is_lval(&**oprnd) {
3292                         // Lvalues may legitimately have unsized types.
3293                         // For example, dereferences of a fat pointer and
3294                         // the last field of a struct can be unsized.
3295                         ExpectHasType(mt.ty)
3296                     } else {
3297                         Expectation::rvalue_hint(tcx, mt.ty)
3298                     }
3299                 }
3300                 _ => NoExpectation
3301             }
3302         });
3303         let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3304         check_expr_with_expectation_and_lvalue_pref(fcx,
3305                                                     &**oprnd,
3306                                                     hint,
3307                                                     lvalue_pref);
3308
3309         let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3310         let oprnd_t = if tm.ty.references_error() {
3311             tcx.types.err
3312         } else {
3313             // Note: at this point, we cannot say what the best lifetime
3314             // is to use for resulting pointer.  We want to use the
3315             // shortest lifetime possible so as to avoid spurious borrowck
3316             // errors.  Moreover, the longest lifetime will depend on the
3317             // precise details of the value whose address is being taken
3318             // (and how long it is valid), which we don't know yet until type
3319             // inference is complete.
3320             //
3321             // Therefore, here we simply generate a region variable.  The
3322             // region inferencer will then select the ultimate value.
3323             // Finally, borrowck is charged with guaranteeing that the
3324             // value whose address was taken can actually be made to live
3325             // as long as it needs to live.
3326             let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3327             tcx.mk_ref(tcx.mk_region(region), tm)
3328         };
3329         fcx.write_ty(id, oprnd_t);
3330       }
3331       hir::ExprPath(ref maybe_qself, ref path) => {
3332           let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3333               fcx.to_ty(&qself.ty)
3334           });
3335
3336           let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3337               d
3338           } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3339                 // Create some fake resolution that can't possibly be a type.
3340                 def::PathResolution {
3341                     base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3342                     last_private: LastMod(AllPublic),
3343                     depth: path.segments.len()
3344                 }
3345             } else {
3346               tcx.sess.span_bug(expr.span,
3347                                 &format!("unbound path {:?}", expr))
3348           };
3349
3350           if let Some((opt_ty, segments, def)) =
3351                   resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3352                                           expr.span, expr.id) {
3353               let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3354                                                                             expr.span,
3355                                                                             def);
3356               instantiate_path(fcx,
3357                                segments,
3358                                scheme,
3359                                &predicates,
3360                                opt_ty,
3361                                def,
3362                                expr.span,
3363                                id);
3364           }
3365
3366           // We always require that the type provided as the value for
3367           // a type parameter outlives the moment of instantiation.
3368           fcx.opt_node_ty_substs(expr.id, |item_substs| {
3369               fcx.add_wf_bounds(&item_substs.substs, expr);
3370           });
3371       }
3372       hir::ExprInlineAsm(ref ia) => {
3373           for &(_, ref input) in &ia.inputs {
3374               check_expr(fcx, &**input);
3375           }
3376           for &(_, ref out, _) in &ia.outputs {
3377               check_expr(fcx, &**out);
3378           }
3379           fcx.write_nil(id);
3380       }
3381       hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3382       hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3383       hir::ExprRet(ref expr_opt) => {
3384         match fcx.ret_ty {
3385             ty::FnConverging(result_type) => {
3386                 match *expr_opt {
3387                     None =>
3388                         if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3389                                                     result_type, fcx.tcx().mk_nil()) {
3390                             span_err!(tcx.sess, expr.span, E0069,
3391                                 "`return;` in a function whose return type is \
3392                                  not `()`");
3393                         },
3394                     Some(ref e) => {
3395                         check_expr_coercable_to_type(fcx, &**e, result_type);
3396                     }
3397                 }
3398             }
3399             ty::FnDiverging => {
3400                 if let Some(ref e) = *expr_opt {
3401                     check_expr(fcx, &**e);
3402                 }
3403                 span_err!(tcx.sess, expr.span, E0166,
3404                     "`return` in a function declared as diverging");
3405             }
3406         }
3407         fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3408       }
3409       hir::ExprAssign(ref lhs, ref rhs) => {
3410         check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3411
3412         let tcx = fcx.tcx();
3413         if !tcx.expr_is_lval(&**lhs) {
3414             span_err!(tcx.sess, expr.span, E0070,
3415                 "invalid left-hand side expression");
3416         }
3417
3418         let lhs_ty = fcx.expr_ty(&**lhs);
3419         check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3420         let rhs_ty = fcx.expr_ty(&**rhs);
3421
3422         fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3423
3424         if lhs_ty.references_error() || rhs_ty.references_error() {
3425             fcx.write_error(id);
3426         } else {
3427             fcx.write_nil(id);
3428         }
3429       }
3430       hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3431         check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3432                         id, expr.span, expected);
3433       }
3434       hir::ExprWhile(ref cond, ref body, _) => {
3435         check_expr_has_type(fcx, &**cond, tcx.types.bool);
3436         check_block_no_value(fcx, &**body);
3437         let cond_ty = fcx.expr_ty(&**cond);
3438         let body_ty = fcx.node_ty(body.id);
3439         if cond_ty.references_error() || body_ty.references_error() {
3440             fcx.write_error(id);
3441         }
3442         else {
3443             fcx.write_nil(id);
3444         }
3445       }
3446       hir::ExprLoop(ref body, _) => {
3447         check_block_no_value(fcx, &**body);
3448         if !may_break(tcx, expr.id, &**body) {
3449             fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3450         } else {
3451             fcx.write_nil(id);
3452         }
3453       }
3454       hir::ExprMatch(ref discrim, ref arms, match_src) => {
3455         _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3456       }
3457       hir::ExprClosure(capture, ref decl, ref body) => {
3458           closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3459       }
3460       hir::ExprBlock(ref b) => {
3461         check_block_with_expected(fcx, &**b, expected);
3462         fcx.write_ty(id, fcx.node_ty(b.id));
3463       }
3464       hir::ExprCall(ref callee, ref args) => {
3465           callee::check_call(fcx, expr, &**callee, &args[..], expected);
3466
3467           // we must check that return type of called functions is WF:
3468           let ret_ty = fcx.expr_ty(expr);
3469           fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3470       }
3471       hir::ExprMethodCall(name, ref tps, ref args) => {
3472           check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3473           let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3474           let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3475           if args_err {
3476               fcx.write_error(id);
3477           }
3478       }
3479       hir::ExprCast(ref e, ref t) => {
3480         if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3481             check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3482         }
3483
3484         // Find the type of `e`. Supply hints based on the type we are casting to,
3485         // if appropriate.
3486         let t_cast = fcx.to_ty(t);
3487         let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3488         check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3489         let t_expr = fcx.expr_ty(e);
3490
3491         // Eagerly check for some obvious errors.
3492         if t_expr.references_error() {
3493             fcx.write_error(id);
3494         } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3495             report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3496         } else {
3497             // Write a type for the whole expression, assuming everything is going
3498             // to work out Ok.
3499             fcx.write_ty(id, t_cast);
3500
3501             // Defer other checks until we're done type checking.
3502             let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3503             let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3504             deferred_cast_checks.push(cast_check);
3505         }
3506       }
3507       hir::ExprVec(ref args) => {
3508         let uty = expected.to_option(fcx).and_then(|uty| {
3509             match uty.sty {
3510                 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3511                 _ => None
3512             }
3513         });
3514
3515         let typ = match uty {
3516             Some(uty) => {
3517                 for e in args {
3518                     check_expr_coercable_to_type(fcx, &**e, uty);
3519                 }
3520                 uty
3521             }
3522             None => {
3523                 let t: Ty = fcx.infcx().next_ty_var();
3524                 for e in args {
3525                     check_expr_has_type(fcx, &**e, t);
3526                 }
3527                 t
3528             }
3529         };
3530         let typ = tcx.mk_array(typ, args.len());
3531         fcx.write_ty(id, typ);
3532       }
3533       hir::ExprRepeat(ref element, ref count_expr) => {
3534         check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3535         let count = fcx.tcx().eval_repeat_count(&**count_expr);
3536
3537         let uty = match expected {
3538             ExpectHasType(uty) => {
3539                 match uty.sty {
3540                     ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3541                     _ => None
3542                 }
3543             }
3544             _ => None
3545         };
3546
3547         let (element_ty, t) = match uty {
3548             Some(uty) => {
3549                 check_expr_coercable_to_type(fcx, &**element, uty);
3550                 (uty, uty)
3551             }
3552             None => {
3553                 let t: Ty = fcx.infcx().next_ty_var();
3554                 check_expr_has_type(fcx, &**element, t);
3555                 (fcx.expr_ty(&**element), t)
3556             }
3557         };
3558
3559         if count > 1 {
3560             // For [foo, ..n] where n > 1, `foo` must have
3561             // Copy type:
3562             fcx.require_type_meets(
3563                 t,
3564                 expr.span,
3565                 traits::RepeatVec,
3566                 ty::BoundCopy);
3567         }
3568
3569         if element_ty.references_error() {
3570             fcx.write_error(id);
3571         } else {
3572             let t = tcx.mk_array(t, count);
3573             fcx.write_ty(id, t);
3574         }
3575       }
3576       hir::ExprTup(ref elts) => {
3577         let flds = expected.only_has_type(fcx).and_then(|ty| {
3578             match ty.sty {
3579                 ty::TyTuple(ref flds) => Some(&flds[..]),
3580                 _ => None
3581             }
3582         });
3583         let mut err_field = false;
3584
3585         let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3586             let t = match flds {
3587                 Some(ref fs) if i < fs.len() => {
3588                     let ety = fs[i];
3589                     check_expr_coercable_to_type(fcx, &**e, ety);
3590                     ety
3591                 }
3592                 _ => {
3593                     check_expr_with_expectation(fcx, &**e, NoExpectation);
3594                     fcx.expr_ty(&**e)
3595                 }
3596             };
3597             err_field = err_field || t.references_error();
3598             t
3599         }).collect();
3600         if err_field {
3601             fcx.write_error(id);
3602         } else {
3603             let typ = tcx.mk_tup(elt_ts);
3604             fcx.write_ty(id, typ);
3605         }
3606       }
3607       hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3608         check_expr_struct(fcx, expr, path, fields, base_expr);
3609
3610         fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3611       }
3612       hir::ExprField(ref base, ref field) => {
3613         check_field(fcx, expr, lvalue_pref, &**base, field);
3614       }
3615       hir::ExprTupField(ref base, idx) => {
3616         check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3617       }
3618       hir::ExprIndex(ref base, ref idx) => {
3619           check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3620           check_expr(fcx, &**idx);
3621
3622           let base_t = fcx.expr_ty(&**base);
3623           let idx_t = fcx.expr_ty(&**idx);
3624
3625           if base_t.references_error() {
3626               fcx.write_ty(id, base_t);
3627           } else if idx_t.references_error() {
3628               fcx.write_ty(id, idx_t);
3629           } else {
3630               let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3631               match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3632                   Some((index_ty, element_ty)) => {
3633                       let idx_expr_ty = fcx.expr_ty(idx);
3634                       demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3635                       fcx.write_ty(id, element_ty);
3636                   }
3637                   None => {
3638                       check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3639                       fcx.type_error_message(
3640                           expr.span,
3641                           |actual| {
3642                               format!("cannot index a value of type `{}`",
3643                                       actual)
3644                           },
3645                           base_t,
3646                           None);
3647                       fcx.write_ty(id, fcx.tcx().types.err);
3648                   }
3649               }
3650           }
3651        }
3652        hir::ExprRange(ref start, ref end) => {
3653           let t_start = start.as_ref().map(|e| {
3654             check_expr(fcx, &**e);
3655             fcx.expr_ty(&**e)
3656           });
3657           let t_end = end.as_ref().map(|e| {
3658             check_expr(fcx, &**e);
3659             fcx.expr_ty(&**e)
3660           });
3661
3662           let idx_type = match (t_start, t_end) {
3663               (Some(ty), None) | (None, Some(ty)) => {
3664                   Some(ty)
3665               }
3666               (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3667                                                t_end.references_error()) => {
3668                   Some(fcx.tcx().types.err)
3669               }
3670               (Some(t_start), Some(t_end)) => {
3671                   Some(infer::common_supertype(fcx.infcx(),
3672                                                infer::RangeExpression(expr.span),
3673                                                true,
3674                                                t_start,
3675                                                t_end))
3676               }
3677               _ => None
3678           };
3679
3680           // Note that we don't check the type of start/end satisfy any
3681           // bounds because right now the range structs do not have any. If we add
3682           // some bounds, then we'll need to check `t_start` against them here.
3683
3684           let range_type = match idx_type {
3685             Some(idx_type) if idx_type.references_error() => {
3686                 fcx.tcx().types.err
3687             }
3688             Some(idx_type) => {
3689                 // Find the did from the appropriate lang item.
3690                 let did = match (start, end) {
3691                     (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3692                     (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3693                     (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3694                     (&None, &None) => {
3695                         tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3696                     }
3697                 };
3698
3699                 if let Some(did) = did {
3700                     let def = tcx.lookup_adt_def(did);
3701                     let predicates = tcx.lookup_predicates(did);
3702                     let substs = Substs::new_type(vec![idx_type], vec![]);
3703                     let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3704                     fcx.add_obligations_for_parameters(
3705                         traits::ObligationCause::new(expr.span,
3706                                                      fcx.body_id,
3707                                                      traits::ItemObligation(did)),
3708                         &bounds);
3709
3710                     tcx.mk_struct(def, tcx.mk_substs(substs))
3711                 } else {
3712                     span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3713                     fcx.tcx().types.err
3714                 }
3715             }
3716             None => {
3717                 // Neither start nor end => RangeFull
3718                 if let Some(did) = tcx.lang_items.range_full_struct() {
3719                     tcx.mk_struct(
3720                         tcx.lookup_adt_def(did),
3721                         tcx.mk_substs(Substs::empty())
3722                     )
3723                 } else {
3724                     span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3725                     fcx.tcx().types.err
3726                 }
3727             }
3728           };
3729
3730           fcx.write_ty(id, range_type);
3731        }
3732
3733     }
3734
3735     debug!("type of expr({}) {} is...", expr.id,
3736            pprust::expr_to_string(expr));
3737     debug!("... {:?}, expected is {:?}",
3738            fcx.expr_ty(expr),
3739            expected);
3740
3741     unifier();
3742 }
3743
3744 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3745                                              path_res: def::PathResolution,
3746                                              opt_self_ty: Option<Ty<'tcx>>,
3747                                              path: &'a hir::Path,
3748                                              span: Span,
3749                                              node_id: ast::NodeId)
3750                                              -> Option<(Option<Ty<'tcx>>,
3751                                                         &'a [hir::PathSegment],
3752                                                         def::Def)>
3753 {
3754
3755     // Associated constants can't depend on generic types.
3756     fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3757                                                 def: def::Def,
3758                                                 ty: Ty<'tcx>,
3759                                                 span: Span,
3760                                                 node_id: ast::NodeId) -> bool {
3761         match def {
3762             def::DefAssociatedConst(..) => {
3763                 if ty.has_param_types() || ty.has_self_ty() {
3764                     span_err!(fcx.sess(), span, E0329,
3765                               "Associated consts cannot depend \
3766                                on type parameters or Self.");
3767                     fcx.write_error(node_id);
3768                     return true;
3769                 }
3770             }
3771             _ => {}
3772         }
3773         false
3774     }
3775
3776     // If fully resolved already, we don't have to do anything.
3777     if path_res.depth == 0 {
3778         if let Some(ty) = opt_self_ty {
3779             if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3780                                               span, node_id) {
3781                 return None;
3782             }
3783         }
3784         Some((opt_self_ty, &path.segments, path_res.base_def))
3785     } else {
3786         let mut def = path_res.base_def;
3787         let ty_segments = path.segments.split_last().unwrap().1;
3788         let base_ty_end = path.segments.len() - path_res.depth;
3789         let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3790                                                      PathParamMode::Optional,
3791                                                      &mut def,
3792                                                      opt_self_ty,
3793                                                      &ty_segments[..base_ty_end],
3794                                                      &ty_segments[base_ty_end..]);
3795         let item_segment = path.segments.last().unwrap();
3796         let item_name = item_segment.identifier.name;
3797         match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3798             Ok((def, lp)) => {
3799                 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3800                     return None;
3801                 }
3802                 // Write back the new resolution.
3803                 fcx.ccx.tcx.def_map.borrow_mut()
3804                        .insert(node_id, def::PathResolution {
3805                    base_def: def,
3806                    last_private: path_res.last_private.or(lp),
3807                    depth: 0
3808                 });
3809                 Some((Some(ty), slice::ref_slice(item_segment), def))
3810             }
3811             Err(error) => {
3812                 method::report_error(fcx, span, ty,
3813                                      item_name, None, error);
3814                 fcx.write_error(node_id);
3815                 None
3816             }
3817         }
3818     }
3819 }
3820
3821 impl<'tcx> Expectation<'tcx> {
3822     /// Provide an expectation for an rvalue expression given an *optional*
3823     /// hint, which is not required for type safety (the resulting type might
3824     /// be checked higher up, as is the case with `&expr` and `box expr`), but
3825     /// is useful in determining the concrete type.
3826     ///
3827     /// The primary use case is where the expected type is a fat pointer,
3828     /// like `&[isize]`. For example, consider the following statement:
3829     ///
3830     ///    let x: &[isize] = &[1, 2, 3];
3831     ///
3832     /// In this case, the expected type for the `&[1, 2, 3]` expression is
3833     /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3834     /// expectation `ExpectHasType([isize])`, that would be too strong --
3835     /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3836     /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3837     /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3838     /// which still is useful, because it informs integer literals and the like.
3839     /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3840     /// for examples of where this comes up,.
3841     fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3842         match tcx.struct_tail(ty).sty {
3843             ty::TySlice(_) | ty::TyTrait(..) => {
3844                 ExpectRvalueLikeUnsized(ty)
3845             }
3846             _ => ExpectHasType(ty)
3847         }
3848     }
3849
3850     // Resolves `expected` by a single level if it is a variable. If
3851     // there is no expected type or resolution is not possible (e.g.,
3852     // no constraints yet present), just returns `None`.
3853     fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3854         match self {
3855             NoExpectation => {
3856                 NoExpectation
3857             }
3858             ExpectCastableToType(t) => {
3859                 ExpectCastableToType(
3860                     fcx.infcx().resolve_type_vars_if_possible(&t))
3861             }
3862             ExpectHasType(t) => {
3863                 ExpectHasType(
3864                     fcx.infcx().resolve_type_vars_if_possible(&t))
3865             }
3866             ExpectRvalueLikeUnsized(t) => {
3867                 ExpectRvalueLikeUnsized(
3868                     fcx.infcx().resolve_type_vars_if_possible(&t))
3869             }
3870         }
3871     }
3872
3873     fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3874         match self.resolve(fcx) {
3875             NoExpectation => None,
3876             ExpectCastableToType(ty) |
3877             ExpectHasType(ty) |
3878             ExpectRvalueLikeUnsized(ty) => Some(ty),
3879         }
3880     }
3881
3882     fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3883         match self.resolve(fcx) {
3884             ExpectHasType(ty) => Some(ty),
3885             _ => None
3886         }
3887     }
3888 }
3889
3890 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3891                                        local: &'tcx hir::Local,
3892                                        init: &'tcx hir::Expr)
3893 {
3894     let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3895
3896     let local_ty = fcx.local_ty(init.span, local.id);
3897     if let Some(m) = ref_bindings {
3898         // Somewhat subtle: if we have a `ref` binding in the pattern,
3899         // we want to avoid introducing coercions for the RHS. This is
3900         // both because it helps preserve sanity and, in the case of
3901         // ref mut, for soundness (issue #23116). In particular, in
3902         // the latter case, we need to be clear that the type of the
3903         // referent for the reference that results is *equal to* the
3904         // type of the lvalue it is referencing, and not some
3905         // supertype thereof.
3906         check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3907         let init_ty = fcx.expr_ty(init);
3908         demand::eqtype(fcx, init.span, init_ty, local_ty);
3909     } else {
3910         check_expr_coercable_to_type(fcx, init, local_ty)
3911     };
3912 }
3913
3914 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local)  {
3915     let tcx = fcx.ccx.tcx;
3916
3917     let t = fcx.local_ty(local.span, local.id);
3918     fcx.write_ty(local.id, t);
3919
3920     if let Some(ref init) = local.init {
3921         check_decl_initializer(fcx, local, &**init);
3922         let init_ty = fcx.expr_ty(&**init);
3923         if init_ty.references_error() {
3924             fcx.write_ty(local.id, init_ty);
3925         }
3926     }
3927
3928     let pcx = pat_ctxt {
3929         fcx: fcx,
3930         map: pat_id_map(&tcx.def_map, &*local.pat),
3931     };
3932     _match::check_pat(&pcx, &*local.pat, t);
3933     let pat_ty = fcx.node_ty(local.pat.id);
3934     if pat_ty.references_error() {
3935         fcx.write_ty(local.id, pat_ty);
3936     }
3937 }
3938
3939 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt)  {
3940     let node_id;
3941     let mut saw_bot = false;
3942     let mut saw_err = false;
3943     match stmt.node {
3944       hir::StmtDecl(ref decl, id) => {
3945         node_id = id;
3946         match decl.node {
3947           hir::DeclLocal(ref l) => {
3948               check_decl_local(fcx, &**l);
3949               let l_t = fcx.node_ty(l.id);
3950               saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3951               saw_err = saw_err || l_t.references_error();
3952           }
3953           hir::DeclItem(_) => {/* ignore for now */ }
3954         }
3955       }
3956       hir::StmtExpr(ref expr, id) => {
3957         node_id = id;
3958         // Check with expected type of ()
3959         check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3960         let expr_ty = fcx.expr_ty(&**expr);
3961         saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3962         saw_err = saw_err || expr_ty.references_error();
3963       }
3964       hir::StmtSemi(ref expr, id) => {
3965         node_id = id;
3966         check_expr(fcx, &**expr);
3967         let expr_ty = fcx.expr_ty(&**expr);
3968         saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3969         saw_err |= expr_ty.references_error();
3970       }
3971     }
3972     if saw_bot {
3973         fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3974     }
3975     else if saw_err {
3976         fcx.write_error(node_id);
3977     }
3978     else {
3979         fcx.write_nil(node_id)
3980     }
3981 }
3982
3983 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block)  {
3984     check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3985     let blkty = fcx.node_ty(blk.id);
3986     if blkty.references_error() {
3987         fcx.write_error(blk.id);
3988     } else {
3989         let nilty = fcx.tcx().mk_nil();
3990         demand::suptype(fcx, blk.span, nilty, blkty);
3991     }
3992 }
3993
3994 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3995                                        blk: &'tcx hir::Block,
3996                                        expected: Expectation<'tcx>) {
3997     let prev = {
3998         let mut fcx_ps = fcx.ps.borrow_mut();
3999         let unsafety_state = fcx_ps.recurse(blk);
4000         replace(&mut *fcx_ps, unsafety_state)
4001     };
4002
4003     let mut warned = false;
4004     let mut any_diverges = false;
4005     let mut any_err = false;
4006     for s in &blk.stmts {
4007         check_stmt(fcx, &**s);
4008         let s_id = ::rustc_front::util::stmt_id(&**s);
4009         let s_ty = fcx.node_ty(s_id);
4010         if any_diverges && !warned && match s.node {
4011             hir::StmtDecl(ref decl, _) => {
4012                 match decl.node {
4013                     hir::DeclLocal(_) => true,
4014                     _ => false,
4015                 }
4016             }
4017             hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4018         } {
4019             fcx.ccx
4020                 .tcx
4021                 .sess
4022                 .add_lint(lint::builtin::UNREACHABLE_CODE,
4023                           s_id,
4024                           s.span,
4025                           "unreachable statement".to_string());
4026             warned = true;
4027         }
4028         any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4029         any_err = any_err || s_ty.references_error();
4030     }
4031     match blk.expr {
4032         None => if any_err {
4033             fcx.write_error(blk.id);
4034         } else if any_diverges {
4035             fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4036         } else {
4037             fcx.write_nil(blk.id);
4038         },
4039         Some(ref e) => {
4040             if any_diverges && !warned {
4041                 fcx.ccx
4042                     .tcx
4043                     .sess
4044                     .add_lint(lint::builtin::UNREACHABLE_CODE,
4045                               e.id,
4046                               e.span,
4047                               "unreachable expression".to_string());
4048             }
4049             let ety = match expected {
4050                 ExpectHasType(ety) => {
4051                     check_expr_coercable_to_type(fcx, &**e, ety);
4052                     ety
4053                 }
4054                 _ => {
4055                     check_expr_with_expectation(fcx, &**e, expected);
4056                     fcx.expr_ty(&**e)
4057                 }
4058             };
4059
4060             if any_err {
4061                 fcx.write_error(blk.id);
4062             } else if any_diverges {
4063                 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4064             } else {
4065                 fcx.write_ty(blk.id, ety);
4066             }
4067         }
4068     };
4069
4070     *fcx.ps.borrow_mut() = prev;
4071 }
4072
4073 /// Checks a constant appearing in a type. At the moment this is just the
4074 /// length expression in a fixed-length vector, but someday it might be
4075 /// extended to type-level numeric literals.
4076 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4077                                 expr: &'tcx hir::Expr,
4078                                 expected_type: Ty<'tcx>) {
4079     let tables = RefCell::new(ty::Tables::empty());
4080     let inh = static_inherited_fields(ccx, &tables);
4081     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4082     check_const_with_ty(&fcx, expr.span, expr, expected_type);
4083 }
4084
4085 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4086                         sp: Span,
4087                         e: &'tcx hir::Expr,
4088                         id: ast::NodeId) {
4089     let tables = RefCell::new(ty::Tables::empty());
4090     let inh = static_inherited_fields(ccx, &tables);
4091     let rty = ccx.tcx.node_id_to_type(id);
4092     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4093     let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4094     check_const_with_ty(&fcx, sp, e, declty);
4095 }
4096
4097 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4098                                  _: Span,
4099                                  e: &'tcx hir::Expr,
4100                                  declty: Ty<'tcx>) {
4101     // Gather locals in statics (because of block expressions).
4102     // This is technically unnecessary because locals in static items are forbidden,
4103     // but prevents type checking from blowing up before const checking can properly
4104     // emit an error.
4105     GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4106
4107     check_expr_with_hint(fcx, e, declty);
4108     demand::coerce(fcx, e.span, declty, e);
4109
4110     fcx.select_all_obligations_and_apply_defaults();
4111     upvar::closure_analyze_const(&fcx, e);
4112     fcx.select_obligations_where_possible();
4113     fcx.check_casts();
4114     fcx.select_all_obligations_or_error();
4115
4116     regionck::regionck_expr(fcx, e);
4117     writeback::resolve_type_vars_in_expr(fcx, e);
4118 }
4119
4120 /// Checks whether a type can be represented in memory. In particular, it
4121 /// identifies types that contain themselves without indirection through a
4122 /// pointer, which would mean their size is unbounded.
4123 pub fn check_representable(tcx: &ty::ctxt,
4124                            sp: Span,
4125                            item_id: ast::NodeId,
4126                            designation: &str) -> bool {
4127     let rty = tcx.node_id_to_type(item_id);
4128
4129     // Check that it is possible to represent this type. This call identifies
4130     // (1) types that contain themselves and (2) types that contain a different
4131     // recursive type. It is only necessary to throw an error on those that
4132     // contain themselves. For case 2, there must be an inner type that will be
4133     // caught by case 1.
4134     match rty.is_representable(tcx, sp) {
4135         Representability::SelfRecursive => {
4136             span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
4137             tcx.sess.fileline_help(
4138                 sp, "wrap the inner value in a box to make it representable");
4139             return false
4140         }
4141         Representability::Representable | Representability::ContainsRecursive => (),
4142     }
4143     return true
4144 }
4145
4146 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4147     let t = tcx.node_id_to_type(id);
4148     match t.sty {
4149         ty::TyStruct(def, substs) => {
4150             let fields = &def.struct_variant().fields;
4151             if fields.is_empty() {
4152                 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4153                 return;
4154             }
4155             let e = fields[0].ty(tcx, substs);
4156             if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4157                 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4158                 return;
4159             }
4160             match e.sty {
4161                 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4162                 _ if e.is_machine()  => { /* struct(u8, u8, u8, u8) is ok */ }
4163                 _ => {
4164                     span_err!(tcx.sess, sp, E0077,
4165                               "SIMD vector element type should be machine type");
4166                     return;
4167                 }
4168             }
4169         }
4170         _ => ()
4171     }
4172 }
4173
4174 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4175                                     sp: Span,
4176                                     vs: &'tcx [P<hir::Variant>],
4177                                     id: ast::NodeId) {
4178
4179     fn disr_in_range(ccx: &CrateCtxt,
4180                      ty: attr::IntType,
4181                      disr: ty::Disr) -> bool {
4182         fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4183             match ty {
4184                 ast::TyU8 => disr as u8 as Disr == disr,
4185                 ast::TyU16 => disr as u16 as Disr == disr,
4186                 ast::TyU32 => disr as u32 as Disr == disr,
4187                 ast::TyU64 => disr as u64 as Disr == disr,
4188                 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4189             }
4190         }
4191         fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4192             match ty {
4193                 ast::TyI8 => disr as i8 as Disr == disr,
4194                 ast::TyI16 => disr as i16 as Disr == disr,
4195                 ast::TyI32 => disr as i32 as Disr == disr,
4196                 ast::TyI64 => disr as i64 as Disr == disr,
4197                 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4198             }
4199         }
4200         match ty {
4201             attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4202             attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4203         }
4204     }
4205
4206     fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4207                           vs: &'tcx [P<hir::Variant>],
4208                           id: ast::NodeId,
4209                           hint: attr::ReprAttr) {
4210         #![allow(trivial_numeric_casts)]
4211
4212         let rty = ccx.tcx.node_id_to_type(id);
4213         let mut disr_vals: Vec<ty::Disr> = Vec::new();
4214
4215         let tables = RefCell::new(ty::Tables::empty());
4216         let inh = static_inherited_fields(ccx, &tables);
4217         let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4218
4219         let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4220         for v in vs {
4221             if let Some(ref e) = v.node.disr_expr {
4222                 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4223             }
4224         }
4225
4226         let def_id = ccx.tcx.map.local_def_id(id);
4227
4228         let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4229         for (v, variant) in vs.iter().zip(variants.iter()) {
4230             let current_disr_val = variant.disr_val;
4231
4232             // Check for duplicate discriminant values
4233             match disr_vals.iter().position(|&x| x == current_disr_val) {
4234                 Some(i) => {
4235                     span_err!(ccx.tcx.sess, v.span, E0081,
4236                         "discriminant value `{}` already exists", disr_vals[i]);
4237                     let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4238                     span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
4239                         "conflicting discriminant here")
4240                 }
4241                 None => {}
4242             }
4243             // Check for unrepresentable discriminant values
4244             match hint {
4245                 attr::ReprAny | attr::ReprExtern => (),
4246                 attr::ReprInt(sp, ity) => {
4247                     if !disr_in_range(ccx, ity, current_disr_val) {
4248                         span_err!(ccx.tcx.sess, v.span, E0082,
4249                             "discriminant value outside specified type");
4250                         span_note!(ccx.tcx.sess, sp,
4251                             "discriminant type specified here");
4252                     }
4253                 }
4254                 attr::ReprSimd => {
4255                     ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4256                 }
4257                 attr::ReprPacked => {
4258                     ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4259                 }
4260             }
4261             disr_vals.push(current_disr_val);
4262         }
4263     }
4264
4265     let def_id = ccx.tcx.map.local_def_id(id);
4266     let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4267
4268     if hint != attr::ReprAny && vs.len() <= 1 {
4269         if vs.len() == 1 {
4270             span_err!(ccx.tcx.sess, sp, E0083,
4271                 "unsupported representation for univariant enum");
4272         } else {
4273             span_err!(ccx.tcx.sess, sp, E0084,
4274                 "unsupported representation for zero-variant enum");
4275         };
4276     }
4277
4278     do_check(ccx, vs, id, hint);
4279
4280     check_representable(ccx.tcx, sp, id, "enum");
4281 }
4282
4283 // Returns the type parameter count and the type for the given definition.
4284 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4285                                                 sp: Span,
4286                                                 defn: def::Def)
4287                                                 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4288     match defn {
4289         def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4290             let typ = fcx.local_ty(sp, nid);
4291             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4292              ty::GenericPredicates::empty())
4293         }
4294         def::DefFn(id, _) | def::DefMethod(id) |
4295         def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4296         def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4297             (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4298         }
4299         def::DefTrait(_) |
4300         def::DefTy(..) |
4301         def::DefAssociatedTy(..) |
4302         def::DefPrimTy(_) |
4303         def::DefTyParam(..) |
4304         def::DefMod(..) |
4305         def::DefForeignMod(..) |
4306         def::DefUse(..) |
4307         def::DefLabel(..) |
4308         def::DefSelfTy(..) => {
4309             fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4310         }
4311     }
4312 }
4313
4314 // Instantiates the given path, which must refer to an item with the given
4315 // number of type parameters and type.
4316 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4317                                   segments: &[hir::PathSegment],
4318                                   type_scheme: TypeScheme<'tcx>,
4319                                   type_predicates: &ty::GenericPredicates<'tcx>,
4320                                   opt_self_ty: Option<Ty<'tcx>>,
4321                                   def: def::Def,
4322                                   span: Span,
4323                                   node_id: ast::NodeId) {
4324     debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4325            segments,
4326            def,
4327            node_id,
4328            type_scheme);
4329
4330     // We need to extract the type parameters supplied by the user in
4331     // the path `path`. Due to the current setup, this is a bit of a
4332     // tricky-process; the problem is that resolve only tells us the
4333     // end-point of the path resolution, and not the intermediate steps.
4334     // Luckily, we can (at least for now) deduce the intermediate steps
4335     // just from the end-point.
4336     //
4337     // There are basically four cases to consider:
4338     //
4339     // 1. Reference to a *type*, such as a struct or enum:
4340     //
4341     //        mod a { struct Foo<T> { ... } }
4342     //
4343     //    Because we don't allow types to be declared within one
4344     //    another, a path that leads to a type will always look like
4345     //    `a::b::Foo<T>` where `a` and `b` are modules. This implies
4346     //    that only the final segment can have type parameters, and
4347     //    they are located in the TypeSpace.
4348     //
4349     //    *Note:* Generally speaking, references to types don't
4350     //    actually pass through this function, but rather the
4351     //    `ast_ty_to_ty` function in `astconv`. However, in the case
4352     //    of struct patterns (and maybe literals) we do invoke
4353     //    `instantiate_path` to get the general type of an instance of
4354     //    a struct. (In these cases, there are actually no type
4355     //    parameters permitted at present, but perhaps we will allow
4356     //    them in the future.)
4357     //
4358     // 1b. Reference to an enum variant or tuple-like struct:
4359     //
4360     //        struct foo<T>(...)
4361     //        enum E<T> { foo(...) }
4362     //
4363     //    In these cases, the parameters are declared in the type
4364     //    space.
4365     //
4366     // 2. Reference to a *fn item*:
4367     //
4368     //        fn foo<T>() { }
4369     //
4370     //    In this case, the path will again always have the form
4371     //    `a::b::foo::<T>` where only the final segment should have
4372     //    type parameters. However, in this case, those parameters are
4373     //    declared on a value, and hence are in the `FnSpace`.
4374     //
4375     // 3. Reference to a *method*:
4376     //
4377     //        impl<A> SomeStruct<A> {
4378     //            fn foo<B>(...)
4379     //        }
4380     //
4381     //    Here we can have a path like
4382     //    `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4383     //    may appear in two places. The penultimate segment,
4384     //    `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4385     //    final segment, `foo::<B>` contains parameters in fn space.
4386     //
4387     // 4. Reference to an *associated const*:
4388     //
4389     // impl<A> AnotherStruct<A> {
4390     // const FOO: B = BAR;
4391     // }
4392     //
4393     // The path in this case will look like
4394     // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4395     // only will have parameters in TypeSpace.
4396     //
4397     // The first step then is to categorize the segments appropriately.
4398
4399     assert!(!segments.is_empty());
4400
4401     let mut ufcs_associated = None;
4402     let mut segment_spaces: Vec<_>;
4403     match def {
4404         // Case 1 and 1b. Reference to a *type* or *enum variant*.
4405         def::DefSelfTy(..) |
4406         def::DefStruct(..) |
4407         def::DefVariant(..) |
4408         def::DefTy(..) |
4409         def::DefAssociatedTy(..) |
4410         def::DefTrait(..) |
4411         def::DefPrimTy(..) |
4412         def::DefTyParam(..) => {
4413             // Everything but the final segment should have no
4414             // parameters at all.
4415             segment_spaces = vec![None; segments.len() - 1];
4416             segment_spaces.push(Some(subst::TypeSpace));
4417         }
4418
4419         // Case 2. Reference to a top-level value.
4420         def::DefFn(..) |
4421         def::DefConst(..) |
4422         def::DefStatic(..) => {
4423             segment_spaces = vec![None; segments.len() - 1];
4424             segment_spaces.push(Some(subst::FnSpace));
4425         }
4426
4427         // Case 3. Reference to a method.
4428         def::DefMethod(def_id) => {
4429             let container = fcx.tcx().impl_or_trait_item(def_id).container();
4430             match container {
4431                 ty::TraitContainer(trait_did) => {
4432                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4433                 }
4434                 ty::ImplContainer(_) => {}
4435             }
4436
4437             if segments.len() >= 2 {
4438                 segment_spaces = vec![None; segments.len() - 2];
4439                 segment_spaces.push(Some(subst::TypeSpace));
4440                 segment_spaces.push(Some(subst::FnSpace));
4441             } else {
4442                 // `<T>::method` will end up here, and so can `T::method`.
4443                 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4444                 segment_spaces = vec![Some(subst::FnSpace)];
4445                 ufcs_associated = Some((container, self_ty));
4446             }
4447         }
4448
4449         def::DefAssociatedConst(def_id) => {
4450             let container = fcx.tcx().impl_or_trait_item(def_id).container();
4451             match container {
4452                 ty::TraitContainer(trait_did) => {
4453                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4454                 }
4455                 ty::ImplContainer(_) => {}
4456             }
4457
4458             if segments.len() >= 2 {
4459                 segment_spaces = vec![None; segments.len() - 2];
4460                 segment_spaces.push(Some(subst::TypeSpace));
4461                 segment_spaces.push(None);
4462             } else {
4463                 // `<T>::CONST` will end up here, and so can `T::CONST`.
4464                 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4465                 segment_spaces = vec![None];
4466                 ufcs_associated = Some((container, self_ty));
4467             }
4468         }
4469
4470         // Other cases. Various nonsense that really shouldn't show up
4471         // here. If they do, an error will have been reported
4472         // elsewhere. (I hope)
4473         def::DefMod(..) |
4474         def::DefForeignMod(..) |
4475         def::DefLocal(..) |
4476         def::DefUse(..) |
4477         def::DefLabel(..) |
4478         def::DefUpvar(..) => {
4479             segment_spaces = vec![None; segments.len()];
4480         }
4481     }
4482     assert_eq!(segment_spaces.len(), segments.len());
4483
4484     // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4485     // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4486     // type parameters are not mandatory.
4487     let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4488
4489     debug!("segment_spaces={:?}", segment_spaces);
4490
4491     // Next, examine the definition, and determine how many type
4492     // parameters we expect from each space.
4493     let type_defs = &type_scheme.generics.types;
4494     let region_defs = &type_scheme.generics.regions;
4495
4496     // Now that we have categorized what space the parameters for each
4497     // segment belong to, let's sort out the parameters that the user
4498     // provided (if any) into their appropriate spaces. We'll also report
4499     // errors if type parameters are provided in an inappropriate place.
4500     let mut substs = Substs::empty();
4501     for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4502         match *opt_space {
4503             None => {
4504                 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4505             }
4506
4507             Some(space) => {
4508                 push_explicit_parameters_from_segment_to_substs(fcx,
4509                                                                 space,
4510                                                                 span,
4511                                                                 type_defs,
4512                                                                 region_defs,
4513                                                                 segment,
4514                                                                 &mut substs);
4515             }
4516         }
4517     }
4518     if let Some(self_ty) = opt_self_ty {
4519         if type_defs.len(subst::SelfSpace) == 1 {
4520             substs.types.push(subst::SelfSpace, self_ty);
4521         }
4522     }
4523
4524     // Now we have to compare the types that the user *actually*
4525     // provided against the types that were *expected*. If the user
4526     // did not provide any types, then we want to substitute inference
4527     // variables. If the user provided some types, we may still need
4528     // to add defaults. If the user provided *too many* types, that's
4529     // a problem.
4530     for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4531         adjust_type_parameters(fcx, span, space, type_defs,
4532                                require_type_space, &mut substs);
4533         assert_eq!(substs.types.len(space), type_defs.len(space));
4534
4535         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4536         assert_eq!(substs.regions().len(space), region_defs.len(space));
4537     }
4538
4539     // The things we are substituting into the type should not contain
4540     // escaping late-bound regions, and nor should the base type scheme.
4541     assert!(!substs.has_regions_escaping_depth(0));
4542     assert!(!type_scheme.has_escaping_regions());
4543
4544     // Add all the obligations that are required, substituting and
4545     // normalized appropriately.
4546     let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4547     fcx.add_obligations_for_parameters(
4548         traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4549         &bounds);
4550
4551     // Substitute the values for the type parameters into the type of
4552     // the referenced item.
4553     let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4554
4555
4556     if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4557         // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4558         // is inherent, there is no `Self` parameter, instead, the impl needs
4559         // type parameters, which we can infer by unifying the provided `Self`
4560         // with the substituted impl type.
4561         let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4562         assert_eq!(substs.types.len(subst::TypeSpace),
4563                    impl_scheme.generics.types.len(subst::TypeSpace));
4564         assert_eq!(substs.regions().len(subst::TypeSpace),
4565                    impl_scheme.generics.regions.len(subst::TypeSpace));
4566
4567         let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4568         if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4569             fcx.tcx().sess.span_bug(span,
4570             &format!(
4571                 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4572                 self_ty,
4573                 impl_ty));
4574         }
4575     }
4576
4577     debug!("instantiate_path: type of {:?} is {:?}",
4578            node_id,
4579            ty_substituted);
4580     fcx.write_ty(node_id, ty_substituted);
4581     fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4582     return;
4583
4584     /// Finds the parameters that the user provided and adds them to `substs`. If too many
4585     /// parameters are provided, then reports an error and clears the output vector.
4586     ///
4587     /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4588     /// use inference variables. This seems less likely to lead to derived errors.
4589     ///
4590     /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4591     /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4592     /// here because we can easily use the precise span of the N+1'th parameter.
4593     fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4594         fcx: &FnCtxt<'a, 'tcx>,
4595         space: subst::ParamSpace,
4596         span: Span,
4597         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4598         region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4599         segment: &hir::PathSegment,
4600         substs: &mut Substs<'tcx>)
4601     {
4602         match segment.parameters {
4603             hir::AngleBracketedParameters(ref data) => {
4604                 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4605                     fcx, space, type_defs, region_defs, data, substs);
4606             }
4607
4608             hir::ParenthesizedParameters(ref data) => {
4609                 span_err!(fcx.tcx().sess, span, E0238,
4610                     "parenthesized parameters may only be used with a trait");
4611                 push_explicit_parenthesized_parameters_from_segment_to_substs(
4612                     fcx, space, span, type_defs, data, substs);
4613             }
4614         }
4615     }
4616
4617     fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4618         fcx: &FnCtxt<'a, 'tcx>,
4619         space: subst::ParamSpace,
4620         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4621         region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4622         data: &hir::AngleBracketedParameterData,
4623         substs: &mut Substs<'tcx>)
4624     {
4625         {
4626             let type_count = type_defs.len(space);
4627             assert_eq!(substs.types.len(space), 0);
4628             for (i, typ) in data.types.iter().enumerate() {
4629                 let t = fcx.to_ty(&**typ);
4630                 if i < type_count {
4631                     substs.types.push(space, t);
4632                 } else if i == type_count {
4633                     span_err!(fcx.tcx().sess, typ.span, E0087,
4634                         "too many type parameters provided: \
4635                          expected at most {} parameter{}, \
4636                          found {} parameter{}",
4637                          type_count,
4638                          if type_count == 1 {""} else {"s"},
4639                          data.types.len(),
4640                          if data.types.len() == 1 {""} else {"s"});
4641                     substs.types.truncate(space, 0);
4642                     break;
4643                 }
4644             }
4645         }
4646
4647         if !data.bindings.is_empty() {
4648             span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4649                       "unexpected binding of associated item in expression path \
4650                        (only allowed in type paths)");
4651         }
4652
4653         {
4654             let region_count = region_defs.len(space);
4655             assert_eq!(substs.regions().len(space), 0);
4656             for (i, lifetime) in data.lifetimes.iter().enumerate() {
4657                 let r = ast_region_to_region(fcx.tcx(), lifetime);
4658                 if i < region_count {
4659                     substs.mut_regions().push(space, r);
4660                 } else if i == region_count {
4661                     span_err!(fcx.tcx().sess, lifetime.span, E0088,
4662                         "too many lifetime parameters provided: \
4663                          expected {} parameter{}, found {} parameter{}",
4664                         region_count,
4665                         if region_count == 1 {""} else {"s"},
4666                         data.lifetimes.len(),
4667                         if data.lifetimes.len() == 1 {""} else {"s"});
4668                     substs.mut_regions().truncate(space, 0);
4669                     break;
4670                 }
4671             }
4672         }
4673     }
4674
4675     /// As with
4676     /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4677     /// but intended for `Foo(A,B) -> C` form. This expands to
4678     /// roughly the same thing as `Foo<(A,B),C>`. One important
4679     /// difference has to do with the treatment of anonymous
4680     /// regions, which are translated into bound regions (NYI).
4681     fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4682         fcx: &FnCtxt<'a, 'tcx>,
4683         space: subst::ParamSpace,
4684         span: Span,
4685         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4686         data: &hir::ParenthesizedParameterData,
4687         substs: &mut Substs<'tcx>)
4688     {
4689         let type_count = type_defs.len(space);
4690         if type_count < 2 {
4691             span_err!(fcx.tcx().sess, span, E0167,
4692                       "parenthesized form always supplies 2 type parameters, \
4693                       but only {} parameter(s) were expected",
4694                       type_count);
4695         }
4696
4697         let input_tys: Vec<Ty> =
4698             data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4699
4700         let tuple_ty = fcx.tcx().mk_tup(input_tys);
4701
4702         if type_count >= 1 {
4703             substs.types.push(space, tuple_ty);
4704         }
4705
4706         let output_ty: Option<Ty> =
4707             data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4708
4709         let output_ty =
4710             output_ty.unwrap_or(fcx.tcx().mk_nil());
4711
4712         if type_count >= 2 {
4713             substs.types.push(space, output_ty);
4714         }
4715     }
4716
4717     fn adjust_type_parameters<'a, 'tcx>(
4718         fcx: &FnCtxt<'a, 'tcx>,
4719         span: Span,
4720         space: ParamSpace,
4721         defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4722         require_type_space: bool,
4723         substs: &mut Substs<'tcx>)
4724     {
4725         let provided_len = substs.types.len(space);
4726         let desired = defs.get_slice(space);
4727         let required_len = desired.iter()
4728                               .take_while(|d| d.default.is_none())
4729                               .count();
4730
4731         debug!("adjust_type_parameters(space={:?}, \
4732                provided_len={}, \
4733                desired_len={}, \
4734                required_len={})",
4735                space,
4736                provided_len,
4737                desired.len(),
4738                required_len);
4739
4740         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4741         assert!(provided_len <= desired.len());
4742
4743         // Nothing specified at all: supply inference variables for
4744         // everything.
4745         if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4746             substs.types.replace(space, Vec::new());
4747             fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4748             return;
4749         }
4750
4751         // Too few parameters specified: report an error and use Err
4752         // for everything.
4753         if provided_len < required_len {
4754             let qualifier =
4755                 if desired.len() != required_len { "at least " } else { "" };
4756             span_err!(fcx.tcx().sess, span, E0089,
4757                 "too few type parameters provided: expected {}{} parameter{}, \
4758                  found {} parameter{}",
4759                 qualifier, required_len,
4760                 if required_len == 1 {""} else {"s"},
4761                 provided_len,
4762                 if provided_len == 1 {""} else {"s"});
4763             substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4764             return;
4765         }
4766
4767         // Otherwise, add in any optional parameters that the user
4768         // omitted. The case of *too many* parameters is handled
4769         // already by
4770         // push_explicit_parameters_from_segment_to_substs(). Note
4771         // that the *default* type are expressed in terms of all prior
4772         // parameters, so we have to substitute as we go with the
4773         // partial substitution that we have built up.
4774         for i in provided_len..desired.len() {
4775             let default = desired[i].default.unwrap();
4776             let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4777             substs.types.push(space, default);
4778         }
4779         assert_eq!(substs.types.len(space), desired.len());
4780
4781         debug!("Final substs: {:?}", substs);
4782     }
4783
4784     fn adjust_region_parameters(
4785         fcx: &FnCtxt,
4786         span: Span,
4787         space: ParamSpace,
4788         defs: &VecPerParamSpace<ty::RegionParameterDef>,
4789         substs: &mut Substs)
4790     {
4791         let provided_len = substs.mut_regions().len(space);
4792         let desired = defs.get_slice(space);
4793
4794         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4795         assert!(provided_len <= desired.len());
4796
4797         // If nothing was provided, just use inference variables.
4798         if provided_len == 0 {
4799             substs.mut_regions().replace(
4800                 space,
4801                 fcx.infcx().region_vars_for_defs(span, desired));
4802             return;
4803         }
4804
4805         // If just the right number were provided, everybody is happy.
4806         if provided_len == desired.len() {
4807             return;
4808         }
4809
4810         // Otherwise, too few were provided. Report an error and then
4811         // use inference variables.
4812         span_err!(fcx.tcx().sess, span, E0090,
4813             "too few lifetime parameters provided: expected {} parameter{}, \
4814              found {} parameter{}",
4815             desired.len(),
4816             if desired.len() == 1 {""} else {"s"},
4817             provided_len,
4818             if provided_len == 1 {""} else {"s"});
4819
4820         substs.mut_regions().replace(
4821             space,
4822             fcx.infcx().region_vars_for_defs(span, desired));
4823     }
4824 }
4825
4826 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4827                                                   sp: Span,
4828                                                   ty: Ty<'tcx>,
4829                                                   f: F) -> Ty<'tcx>
4830     where F: Fn() -> Ty<'tcx>
4831 {
4832     let mut ty = fcx.resolve_type_vars_if_possible(ty);
4833
4834     if ty.is_ty_var() {
4835         let alternative = f();
4836
4837         // If not, error.
4838         if alternative.is_ty_var() || alternative.references_error() {
4839             fcx.type_error_message(sp, |_actual| {
4840                 "the type of this value must be known in this context".to_string()
4841             }, ty, None);
4842             demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4843             ty = fcx.tcx().types.err;
4844         } else {
4845             demand::suptype(fcx, sp, alternative, ty);
4846             ty = alternative;
4847         }
4848     }
4849
4850     ty
4851 }
4852
4853 // Resolves `typ` by a single level if `typ` is a type variable.  If no
4854 // resolution is possible, then an error is reported.
4855 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4856                                             sp: Span,
4857                                             ty: Ty<'tcx>)
4858                                             -> Ty<'tcx>
4859 {
4860     structurally_resolve_type_or_else(fcx, sp, ty, || {
4861         fcx.tcx().types.err
4862     })
4863 }
4864
4865 // Returns true if b contains a break that can exit from b
4866 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4867     // First: is there an unlabeled break immediately
4868     // inside the loop?
4869     (loop_query(&*b, |e| {
4870         match *e {
4871             hir::ExprBreak(None) => true,
4872             _ => false
4873         }
4874     })) ||
4875     // Second: is there a labeled break with label
4876     // <id> nested anywhere inside the loop?
4877     (block_query(b, |e| {
4878         if let hir::ExprBreak(Some(_)) = e.node {
4879             lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4880         } else {
4881             false
4882         }
4883     }))
4884 }
4885
4886 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4887                                        span: Span,
4888                                        tps: &OwnedSlice<hir::TyParam>,
4889                                        ty: Ty<'tcx>) {
4890     debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4891            tps.len(),  ty);
4892
4893     // make a vector of booleans initially false, set to true when used
4894     if tps.is_empty() { return; }
4895     let mut tps_used = vec![false; tps.len()];
4896
4897     for leaf_ty in ty.walk() {
4898         if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4899             debug!("Found use of ty param num {}", idx);
4900             tps_used[idx as usize] = true;
4901         }
4902     }
4903
4904     for (i, b) in tps_used.iter().enumerate() {
4905         if !*b {
4906             span_err!(ccx.tcx.sess, span, E0091,
4907                 "type parameter `{}` is unused",
4908                 tps[i].name);
4909         }
4910     }
4911 }