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