]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/mod.rs
Rollup merge of #30774 - nagisa:mir-fix-constval-adts, r=arielb1
[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     // Associated constants can't depend on generic types.
3789     fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3790                                                 def: def::Def,
3791                                                 ty: Ty<'tcx>,
3792                                                 span: Span,
3793                                                 node_id: ast::NodeId) -> bool {
3794         match def {
3795             def::DefAssociatedConst(..) => {
3796                 if ty.has_param_types() || ty.has_self_ty() {
3797                     span_err!(fcx.sess(), span, E0329,
3798                               "Associated consts cannot depend \
3799                                on type parameters or Self.");
3800                     fcx.write_error(node_id);
3801                     return true;
3802                 }
3803             }
3804             _ => {}
3805         }
3806         false
3807     }
3808
3809     // If fully resolved already, we don't have to do anything.
3810     if path_res.depth == 0 {
3811         if let Some(ty) = opt_self_ty {
3812             if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3813                                               span, node_id) {
3814                 return None;
3815             }
3816         }
3817         Some((opt_self_ty, &path.segments, path_res.base_def))
3818     } else {
3819         let mut def = path_res.base_def;
3820         let ty_segments = path.segments.split_last().unwrap().1;
3821         let base_ty_end = path.segments.len() - path_res.depth;
3822         let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3823                                                      PathParamMode::Optional,
3824                                                      &mut def,
3825                                                      opt_self_ty,
3826                                                      &ty_segments[..base_ty_end],
3827                                                      &ty_segments[base_ty_end..]);
3828         let item_segment = path.segments.last().unwrap();
3829         let item_name = item_segment.identifier.name;
3830         match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3831             Ok((def, lp)) => {
3832                 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3833                     return None;
3834                 }
3835                 // Write back the new resolution.
3836                 fcx.ccx.tcx.def_map.borrow_mut()
3837                        .insert(node_id, def::PathResolution {
3838                    base_def: def,
3839                    last_private: path_res.last_private.or(lp),
3840                    depth: 0
3841                 });
3842                 Some((Some(ty), slice::ref_slice(item_segment), def))
3843             }
3844             Err(error) => {
3845                 method::report_error(fcx, span, ty,
3846                                      item_name, None, error);
3847                 fcx.write_error(node_id);
3848                 None
3849             }
3850         }
3851     }
3852 }
3853
3854 impl<'tcx> Expectation<'tcx> {
3855     /// Provide an expectation for an rvalue expression given an *optional*
3856     /// hint, which is not required for type safety (the resulting type might
3857     /// be checked higher up, as is the case with `&expr` and `box expr`), but
3858     /// is useful in determining the concrete type.
3859     ///
3860     /// The primary use case is where the expected type is a fat pointer,
3861     /// like `&[isize]`. For example, consider the following statement:
3862     ///
3863     ///    let x: &[isize] = &[1, 2, 3];
3864     ///
3865     /// In this case, the expected type for the `&[1, 2, 3]` expression is
3866     /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3867     /// expectation `ExpectHasType([isize])`, that would be too strong --
3868     /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3869     /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3870     /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3871     /// which still is useful, because it informs integer literals and the like.
3872     /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3873     /// for examples of where this comes up,.
3874     fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3875         match tcx.struct_tail(ty).sty {
3876             ty::TySlice(_) | ty::TyTrait(..) => {
3877                 ExpectRvalueLikeUnsized(ty)
3878             }
3879             _ => ExpectHasType(ty)
3880         }
3881     }
3882
3883     // Resolves `expected` by a single level if it is a variable. If
3884     // there is no expected type or resolution is not possible (e.g.,
3885     // no constraints yet present), just returns `None`.
3886     fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3887         match self {
3888             NoExpectation => {
3889                 NoExpectation
3890             }
3891             ExpectCastableToType(t) => {
3892                 ExpectCastableToType(
3893                     fcx.infcx().resolve_type_vars_if_possible(&t))
3894             }
3895             ExpectHasType(t) => {
3896                 ExpectHasType(
3897                     fcx.infcx().resolve_type_vars_if_possible(&t))
3898             }
3899             ExpectRvalueLikeUnsized(t) => {
3900                 ExpectRvalueLikeUnsized(
3901                     fcx.infcx().resolve_type_vars_if_possible(&t))
3902             }
3903         }
3904     }
3905
3906     fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3907         match self.resolve(fcx) {
3908             NoExpectation => None,
3909             ExpectCastableToType(ty) |
3910             ExpectHasType(ty) |
3911             ExpectRvalueLikeUnsized(ty) => Some(ty),
3912         }
3913     }
3914
3915     fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3916         match self.resolve(fcx) {
3917             ExpectHasType(ty) => Some(ty),
3918             _ => None
3919         }
3920     }
3921 }
3922
3923 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3924                                        local: &'tcx hir::Local,
3925                                        init: &'tcx hir::Expr)
3926 {
3927     let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3928
3929     let local_ty = fcx.local_ty(init.span, local.id);
3930     if let Some(m) = ref_bindings {
3931         // Somewhat subtle: if we have a `ref` binding in the pattern,
3932         // we want to avoid introducing coercions for the RHS. This is
3933         // both because it helps preserve sanity and, in the case of
3934         // ref mut, for soundness (issue #23116). In particular, in
3935         // the latter case, we need to be clear that the type of the
3936         // referent for the reference that results is *equal to* the
3937         // type of the lvalue it is referencing, and not some
3938         // supertype thereof.
3939         check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3940         let init_ty = fcx.expr_ty(init);
3941         demand::eqtype(fcx, init.span, init_ty, local_ty);
3942     } else {
3943         check_expr_coercable_to_type(fcx, init, local_ty)
3944     };
3945 }
3946
3947 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local)  {
3948     let tcx = fcx.ccx.tcx;
3949
3950     let t = fcx.local_ty(local.span, local.id);
3951     fcx.write_ty(local.id, t);
3952
3953     if let Some(ref init) = local.init {
3954         check_decl_initializer(fcx, local, &**init);
3955         let init_ty = fcx.expr_ty(&**init);
3956         if init_ty.references_error() {
3957             fcx.write_ty(local.id, init_ty);
3958         }
3959     }
3960
3961     let pcx = pat_ctxt {
3962         fcx: fcx,
3963         map: pat_id_map(&tcx.def_map, &*local.pat),
3964     };
3965     _match::check_pat(&pcx, &*local.pat, t);
3966     let pat_ty = fcx.node_ty(local.pat.id);
3967     if pat_ty.references_error() {
3968         fcx.write_ty(local.id, pat_ty);
3969     }
3970 }
3971
3972 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt)  {
3973     let node_id;
3974     let mut saw_bot = false;
3975     let mut saw_err = false;
3976     match stmt.node {
3977       hir::StmtDecl(ref decl, id) => {
3978         node_id = id;
3979         match decl.node {
3980           hir::DeclLocal(ref l) => {
3981               check_decl_local(fcx, &**l);
3982               let l_t = fcx.node_ty(l.id);
3983               saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3984               saw_err = saw_err || l_t.references_error();
3985           }
3986           hir::DeclItem(_) => {/* ignore for now */ }
3987         }
3988       }
3989       hir::StmtExpr(ref expr, id) => {
3990         node_id = id;
3991         // Check with expected type of ()
3992         check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3993         let expr_ty = fcx.expr_ty(&**expr);
3994         saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3995         saw_err = saw_err || expr_ty.references_error();
3996       }
3997       hir::StmtSemi(ref expr, id) => {
3998         node_id = id;
3999         check_expr(fcx, &**expr);
4000         let expr_ty = fcx.expr_ty(&**expr);
4001         saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
4002         saw_err |= expr_ty.references_error();
4003       }
4004     }
4005     if saw_bot {
4006         fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
4007     }
4008     else if saw_err {
4009         fcx.write_error(node_id);
4010     }
4011     else {
4012         fcx.write_nil(node_id)
4013     }
4014 }
4015
4016 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block)  {
4017     check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
4018     let blkty = fcx.node_ty(blk.id);
4019     if blkty.references_error() {
4020         fcx.write_error(blk.id);
4021     } else {
4022         let nilty = fcx.tcx().mk_nil();
4023         demand::suptype(fcx, blk.span, nilty, blkty);
4024     }
4025 }
4026
4027 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4028                                        blk: &'tcx hir::Block,
4029                                        expected: Expectation<'tcx>) {
4030     let prev = {
4031         let mut fcx_ps = fcx.ps.borrow_mut();
4032         let unsafety_state = fcx_ps.recurse(blk);
4033         replace(&mut *fcx_ps, unsafety_state)
4034     };
4035
4036     let mut warned = false;
4037     let mut any_diverges = false;
4038     let mut any_err = false;
4039     for s in &blk.stmts {
4040         check_stmt(fcx, s);
4041         let s_id = ::rustc_front::util::stmt_id(s);
4042         let s_ty = fcx.node_ty(s_id);
4043         if any_diverges && !warned && match s.node {
4044             hir::StmtDecl(ref decl, _) => {
4045                 match decl.node {
4046                     hir::DeclLocal(_) => true,
4047                     _ => false,
4048                 }
4049             }
4050             hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4051         } {
4052             fcx.ccx
4053                 .tcx
4054                 .sess
4055                 .add_lint(lint::builtin::UNREACHABLE_CODE,
4056                           s_id,
4057                           s.span,
4058                           "unreachable statement".to_string());
4059             warned = true;
4060         }
4061         any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4062         any_err = any_err || s_ty.references_error();
4063     }
4064     match blk.expr {
4065         None => if any_err {
4066             fcx.write_error(blk.id);
4067         } else if any_diverges {
4068             fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4069         } else {
4070             fcx.write_nil(blk.id);
4071         },
4072         Some(ref e) => {
4073             if any_diverges && !warned {
4074                 fcx.ccx
4075                     .tcx
4076                     .sess
4077                     .add_lint(lint::builtin::UNREACHABLE_CODE,
4078                               e.id,
4079                               e.span,
4080                               "unreachable expression".to_string());
4081             }
4082             let ety = match expected {
4083                 ExpectHasType(ety) => {
4084                     check_expr_coercable_to_type(fcx, &**e, ety);
4085                     ety
4086                 }
4087                 _ => {
4088                     check_expr_with_expectation(fcx, &**e, expected);
4089                     fcx.expr_ty(&**e)
4090                 }
4091             };
4092
4093             if any_err {
4094                 fcx.write_error(blk.id);
4095             } else if any_diverges {
4096                 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4097             } else {
4098                 fcx.write_ty(blk.id, ety);
4099             }
4100         }
4101     };
4102
4103     *fcx.ps.borrow_mut() = prev;
4104 }
4105
4106 /// Checks a constant appearing in a type. At the moment this is just the
4107 /// length expression in a fixed-length vector, but someday it might be
4108 /// extended to type-level numeric literals.
4109 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4110                                 expr: &'tcx hir::Expr,
4111                                 expected_type: Ty<'tcx>) {
4112     let tables = RefCell::new(ty::Tables::empty());
4113     let inh = static_inherited_fields(ccx, &tables);
4114     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4115     check_const_with_ty(&fcx, expr.span, expr, expected_type);
4116 }
4117
4118 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4119                         sp: Span,
4120                         e: &'tcx hir::Expr,
4121                         id: ast::NodeId) {
4122     let tables = RefCell::new(ty::Tables::empty());
4123     let inh = static_inherited_fields(ccx, &tables);
4124     let rty = ccx.tcx.node_id_to_type(id);
4125     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4126     let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4127     check_const_with_ty(&fcx, sp, e, declty);
4128 }
4129
4130 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4131                                  _: Span,
4132                                  e: &'tcx hir::Expr,
4133                                  declty: Ty<'tcx>) {
4134     // Gather locals in statics (because of block expressions).
4135     // This is technically unnecessary because locals in static items are forbidden,
4136     // but prevents type checking from blowing up before const checking can properly
4137     // emit an error.
4138     GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4139
4140     check_expr_with_hint(fcx, e, declty);
4141     demand::coerce(fcx, e.span, declty, e);
4142
4143     fcx.select_all_obligations_and_apply_defaults();
4144     upvar::closure_analyze_const(&fcx, e);
4145     fcx.select_obligations_where_possible();
4146     fcx.check_casts();
4147     fcx.select_all_obligations_or_error();
4148
4149     regionck::regionck_expr(fcx, e);
4150     writeback::resolve_type_vars_in_expr(fcx, e);
4151 }
4152
4153 /// Checks whether a type can be represented in memory. In particular, it
4154 /// identifies types that contain themselves without indirection through a
4155 /// pointer, which would mean their size is unbounded.
4156 pub fn check_representable(tcx: &ty::ctxt,
4157                            sp: Span,
4158                            item_id: ast::NodeId,
4159                            designation: &str) -> bool {
4160     let rty = tcx.node_id_to_type(item_id);
4161
4162     // Check that it is possible to represent this type. This call identifies
4163     // (1) types that contain themselves and (2) types that contain a different
4164     // recursive type. It is only necessary to throw an error on those that
4165     // contain themselves. For case 2, there must be an inner type that will be
4166     // caught by case 1.
4167     match rty.is_representable(tcx, sp) {
4168         Representability::SelfRecursive => {
4169             struct_span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation)
4170                 .fileline_help(sp, "wrap the inner value in a box to make it representable")
4171                 .emit();
4172             return false
4173         }
4174         Representability::Representable | Representability::ContainsRecursive => (),
4175     }
4176     return true
4177 }
4178
4179 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4180     let t = tcx.node_id_to_type(id);
4181     match t.sty {
4182         ty::TyStruct(def, substs) => {
4183             let fields = &def.struct_variant().fields;
4184             if fields.is_empty() {
4185                 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4186                 return;
4187             }
4188             let e = fields[0].ty(tcx, substs);
4189             if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4190                 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4191                 return;
4192             }
4193             match e.sty {
4194                 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4195                 _ if e.is_machine()  => { /* struct(u8, u8, u8, u8) is ok */ }
4196                 _ => {
4197                     span_err!(tcx.sess, sp, E0077,
4198                               "SIMD vector element type should be machine type");
4199                     return;
4200                 }
4201             }
4202         }
4203         _ => ()
4204     }
4205 }
4206
4207 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4208                                     sp: Span,
4209                                     vs: &'tcx [hir::Variant],
4210                                     id: ast::NodeId) {
4211
4212     fn disr_in_range(ccx: &CrateCtxt,
4213                      ty: attr::IntType,
4214                      disr: ty::Disr) -> bool {
4215         fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4216             match ty {
4217                 ast::TyU8 => disr as u8 as Disr == disr,
4218                 ast::TyU16 => disr as u16 as Disr == disr,
4219                 ast::TyU32 => disr as u32 as Disr == disr,
4220                 ast::TyU64 => disr as u64 as Disr == disr,
4221                 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4222             }
4223         }
4224         fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4225             match ty {
4226                 ast::TyI8 => disr as i8 as Disr == disr,
4227                 ast::TyI16 => disr as i16 as Disr == disr,
4228                 ast::TyI32 => disr as i32 as Disr == disr,
4229                 ast::TyI64 => disr as i64 as Disr == disr,
4230                 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4231             }
4232         }
4233         match ty {
4234             attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4235             attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4236         }
4237     }
4238
4239     fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4240                           vs: &'tcx [hir::Variant],
4241                           id: ast::NodeId,
4242                           hint: attr::ReprAttr) {
4243         #![allow(trivial_numeric_casts)]
4244
4245         let rty = ccx.tcx.node_id_to_type(id);
4246         let mut disr_vals: Vec<ty::Disr> = Vec::new();
4247
4248         let tables = RefCell::new(ty::Tables::empty());
4249         let inh = static_inherited_fields(ccx, &tables);
4250         let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4251
4252         let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4253         for v in vs {
4254             if let Some(ref e) = v.node.disr_expr {
4255                 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4256             }
4257         }
4258
4259         let def_id = ccx.tcx.map.local_def_id(id);
4260
4261         let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4262         for (v, variant) in vs.iter().zip(variants.iter()) {
4263             let current_disr_val = variant.disr_val;
4264
4265             // Check for duplicate discriminant values
4266             match disr_vals.iter().position(|&x| x == current_disr_val) {
4267                 Some(i) => {
4268                     let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4269                         "discriminant value `{}` already exists", disr_vals[i]);
4270                     let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4271                     span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4272                         "conflicting discriminant here");
4273                     err.emit();
4274                 }
4275                 None => {}
4276             }
4277             // Check for unrepresentable discriminant values
4278             match hint {
4279                 attr::ReprAny | attr::ReprExtern => (),
4280                 attr::ReprInt(sp, ity) => {
4281                     if !disr_in_range(ccx, ity, current_disr_val) {
4282                         let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4283                             "discriminant value outside specified type");
4284                         span_note!(&mut err, sp,
4285                             "discriminant type specified here");
4286                         err.emit();
4287                     }
4288                 }
4289                 attr::ReprSimd => {
4290                     ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4291                 }
4292                 attr::ReprPacked => {
4293                     ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4294                 }
4295             }
4296             disr_vals.push(current_disr_val);
4297         }
4298     }
4299
4300     let def_id = ccx.tcx.map.local_def_id(id);
4301     let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4302
4303     if hint != attr::ReprAny && vs.len() <= 1 {
4304         if vs.len() == 1 {
4305             span_err!(ccx.tcx.sess, sp, E0083,
4306                 "unsupported representation for univariant enum");
4307         } else {
4308             span_err!(ccx.tcx.sess, sp, E0084,
4309                 "unsupported representation for zero-variant enum");
4310         };
4311     }
4312
4313     do_check(ccx, vs, id, hint);
4314
4315     check_representable(ccx.tcx, sp, id, "enum");
4316 }
4317
4318 // Returns the type parameter count and the type for the given definition.
4319 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4320                                                 sp: Span,
4321                                                 defn: def::Def)
4322                                                 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4323     match defn {
4324         def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4325             let typ = fcx.local_ty(sp, nid);
4326             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4327              ty::GenericPredicates::empty())
4328         }
4329         def::DefFn(id, _) | def::DefMethod(id) |
4330         def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4331         def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4332             (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4333         }
4334         def::DefTrait(_) |
4335         def::DefTy(..) |
4336         def::DefAssociatedTy(..) |
4337         def::DefPrimTy(_) |
4338         def::DefTyParam(..) |
4339         def::DefMod(..) |
4340         def::DefForeignMod(..) |
4341         def::DefLabel(..) |
4342         def::DefSelfTy(..) |
4343         def::DefErr => {
4344             fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4345         }
4346     }
4347 }
4348
4349 // Instantiates the given path, which must refer to an item with the given
4350 // number of type parameters and type.
4351 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4352                                   segments: &[hir::PathSegment],
4353                                   type_scheme: TypeScheme<'tcx>,
4354                                   type_predicates: &ty::GenericPredicates<'tcx>,
4355                                   opt_self_ty: Option<Ty<'tcx>>,
4356                                   def: def::Def,
4357                                   span: Span,
4358                                   node_id: ast::NodeId) {
4359     debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4360            segments,
4361            def,
4362            node_id,
4363            type_scheme);
4364
4365     // We need to extract the type parameters supplied by the user in
4366     // the path `path`. Due to the current setup, this is a bit of a
4367     // tricky-process; the problem is that resolve only tells us the
4368     // end-point of the path resolution, and not the intermediate steps.
4369     // Luckily, we can (at least for now) deduce the intermediate steps
4370     // just from the end-point.
4371     //
4372     // There are basically four cases to consider:
4373     //
4374     // 1. Reference to a *type*, such as a struct or enum:
4375     //
4376     //        mod a { struct Foo<T> { ... } }
4377     //
4378     //    Because we don't allow types to be declared within one
4379     //    another, a path that leads to a type will always look like
4380     //    `a::b::Foo<T>` where `a` and `b` are modules. This implies
4381     //    that only the final segment can have type parameters, and
4382     //    they are located in the TypeSpace.
4383     //
4384     //    *Note:* Generally speaking, references to types don't
4385     //    actually pass through this function, but rather the
4386     //    `ast_ty_to_ty` function in `astconv`. However, in the case
4387     //    of struct patterns (and maybe literals) we do invoke
4388     //    `instantiate_path` to get the general type of an instance of
4389     //    a struct. (In these cases, there are actually no type
4390     //    parameters permitted at present, but perhaps we will allow
4391     //    them in the future.)
4392     //
4393     // 1b. Reference to an enum variant or tuple-like struct:
4394     //
4395     //        struct foo<T>(...)
4396     //        enum E<T> { foo(...) }
4397     //
4398     //    In these cases, the parameters are declared in the type
4399     //    space.
4400     //
4401     // 2. Reference to a *fn item*:
4402     //
4403     //        fn foo<T>() { }
4404     //
4405     //    In this case, the path will again always have the form
4406     //    `a::b::foo::<T>` where only the final segment should have
4407     //    type parameters. However, in this case, those parameters are
4408     //    declared on a value, and hence are in the `FnSpace`.
4409     //
4410     // 3. Reference to a *method*:
4411     //
4412     //        impl<A> SomeStruct<A> {
4413     //            fn foo<B>(...)
4414     //        }
4415     //
4416     //    Here we can have a path like
4417     //    `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4418     //    may appear in two places. The penultimate segment,
4419     //    `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4420     //    final segment, `foo::<B>` contains parameters in fn space.
4421     //
4422     // 4. Reference to an *associated const*:
4423     //
4424     // impl<A> AnotherStruct<A> {
4425     // const FOO: B = BAR;
4426     // }
4427     //
4428     // The path in this case will look like
4429     // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4430     // only will have parameters in TypeSpace.
4431     //
4432     // The first step then is to categorize the segments appropriately.
4433
4434     assert!(!segments.is_empty());
4435
4436     let mut ufcs_associated = None;
4437     let mut segment_spaces: Vec<_>;
4438     match def {
4439         // Case 1 and 1b. Reference to a *type* or *enum variant*.
4440         def::DefSelfTy(..) |
4441         def::DefStruct(..) |
4442         def::DefVariant(..) |
4443         def::DefTy(..) |
4444         def::DefAssociatedTy(..) |
4445         def::DefTrait(..) |
4446         def::DefPrimTy(..) |
4447         def::DefTyParam(..) => {
4448             // Everything but the final segment should have no
4449             // parameters at all.
4450             segment_spaces = vec![None; segments.len() - 1];
4451             segment_spaces.push(Some(subst::TypeSpace));
4452         }
4453
4454         // Case 2. Reference to a top-level value.
4455         def::DefFn(..) |
4456         def::DefConst(..) |
4457         def::DefStatic(..) => {
4458             segment_spaces = vec![None; segments.len() - 1];
4459             segment_spaces.push(Some(subst::FnSpace));
4460         }
4461
4462         // Case 3. Reference to a method.
4463         def::DefMethod(def_id) => {
4464             let container = fcx.tcx().impl_or_trait_item(def_id).container();
4465             match container {
4466                 ty::TraitContainer(trait_did) => {
4467                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4468                 }
4469                 ty::ImplContainer(_) => {}
4470             }
4471
4472             if segments.len() >= 2 {
4473                 segment_spaces = vec![None; segments.len() - 2];
4474                 segment_spaces.push(Some(subst::TypeSpace));
4475                 segment_spaces.push(Some(subst::FnSpace));
4476             } else {
4477                 // `<T>::method` will end up here, and so can `T::method`.
4478                 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4479                 segment_spaces = vec![Some(subst::FnSpace)];
4480                 ufcs_associated = Some((container, self_ty));
4481             }
4482         }
4483
4484         def::DefAssociatedConst(def_id) => {
4485             let container = fcx.tcx().impl_or_trait_item(def_id).container();
4486             match container {
4487                 ty::TraitContainer(trait_did) => {
4488                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4489                 }
4490                 ty::ImplContainer(_) => {}
4491             }
4492
4493             if segments.len() >= 2 {
4494                 segment_spaces = vec![None; segments.len() - 2];
4495                 segment_spaces.push(Some(subst::TypeSpace));
4496                 segment_spaces.push(None);
4497             } else {
4498                 // `<T>::CONST` will end up here, and so can `T::CONST`.
4499                 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4500                 segment_spaces = vec![None];
4501                 ufcs_associated = Some((container, self_ty));
4502             }
4503         }
4504
4505         // Other cases. Various nonsense that really shouldn't show up
4506         // here. If they do, an error will have been reported
4507         // elsewhere. (I hope)
4508         def::DefMod(..) |
4509         def::DefForeignMod(..) |
4510         def::DefLocal(..) |
4511         def::DefLabel(..) |
4512         def::DefUpvar(..) |
4513         def::DefErr => {
4514             segment_spaces = vec![None; segments.len()];
4515         }
4516     }
4517     assert_eq!(segment_spaces.len(), segments.len());
4518
4519     // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4520     // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4521     // type parameters are not mandatory.
4522     let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4523
4524     debug!("segment_spaces={:?}", segment_spaces);
4525
4526     // Next, examine the definition, and determine how many type
4527     // parameters we expect from each space.
4528     let type_defs = &type_scheme.generics.types;
4529     let region_defs = &type_scheme.generics.regions;
4530
4531     // Now that we have categorized what space the parameters for each
4532     // segment belong to, let's sort out the parameters that the user
4533     // provided (if any) into their appropriate spaces. We'll also report
4534     // errors if type parameters are provided in an inappropriate place.
4535     let mut substs = Substs::empty();
4536     for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4537         match *opt_space {
4538             None => {
4539                 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4540             }
4541
4542             Some(space) => {
4543                 push_explicit_parameters_from_segment_to_substs(fcx,
4544                                                                 space,
4545                                                                 span,
4546                                                                 type_defs,
4547                                                                 region_defs,
4548                                                                 segment,
4549                                                                 &mut substs);
4550             }
4551         }
4552     }
4553     if let Some(self_ty) = opt_self_ty {
4554         if type_defs.len(subst::SelfSpace) == 1 {
4555             substs.types.push(subst::SelfSpace, self_ty);
4556         }
4557     }
4558
4559     // Now we have to compare the types that the user *actually*
4560     // provided against the types that were *expected*. If the user
4561     // did not provide any types, then we want to substitute inference
4562     // variables. If the user provided some types, we may still need
4563     // to add defaults. If the user provided *too many* types, that's
4564     // a problem.
4565     for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4566         adjust_type_parameters(fcx, span, space, type_defs,
4567                                require_type_space, &mut substs);
4568         assert_eq!(substs.types.len(space), type_defs.len(space));
4569
4570         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4571         assert_eq!(substs.regions().len(space), region_defs.len(space));
4572     }
4573
4574     // The things we are substituting into the type should not contain
4575     // escaping late-bound regions, and nor should the base type scheme.
4576     assert!(!substs.has_regions_escaping_depth(0));
4577     assert!(!type_scheme.has_escaping_regions());
4578
4579     // Add all the obligations that are required, substituting and
4580     // normalized appropriately.
4581     let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4582     fcx.add_obligations_for_parameters(
4583         traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4584         &bounds);
4585
4586     // Substitute the values for the type parameters into the type of
4587     // the referenced item.
4588     let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4589
4590
4591     if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4592         // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4593         // is inherent, there is no `Self` parameter, instead, the impl needs
4594         // type parameters, which we can infer by unifying the provided `Self`
4595         // with the substituted impl type.
4596         let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4597         assert_eq!(substs.types.len(subst::TypeSpace),
4598                    impl_scheme.generics.types.len(subst::TypeSpace));
4599         assert_eq!(substs.regions().len(subst::TypeSpace),
4600                    impl_scheme.generics.regions.len(subst::TypeSpace));
4601
4602         let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4603         if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4604             fcx.tcx().sess.span_bug(span,
4605             &format!(
4606                 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4607                 self_ty,
4608                 impl_ty));
4609         }
4610     }
4611
4612     debug!("instantiate_path: type of {:?} is {:?}",
4613            node_id,
4614            ty_substituted);
4615     fcx.write_ty(node_id, ty_substituted);
4616     fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4617     return;
4618
4619     /// Finds the parameters that the user provided and adds them to `substs`. If too many
4620     /// parameters are provided, then reports an error and clears the output vector.
4621     ///
4622     /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4623     /// use inference variables. This seems less likely to lead to derived errors.
4624     ///
4625     /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4626     /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4627     /// here because we can easily use the precise span of the N+1'th parameter.
4628     fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4629         fcx: &FnCtxt<'a, 'tcx>,
4630         space: subst::ParamSpace,
4631         span: Span,
4632         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4633         region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4634         segment: &hir::PathSegment,
4635         substs: &mut Substs<'tcx>)
4636     {
4637         match segment.parameters {
4638             hir::AngleBracketedParameters(ref data) => {
4639                 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4640                     fcx, space, type_defs, region_defs, data, substs);
4641             }
4642
4643             hir::ParenthesizedParameters(ref data) => {
4644                 span_err!(fcx.tcx().sess, span, E0238,
4645                     "parenthesized parameters may only be used with a trait");
4646                 push_explicit_parenthesized_parameters_from_segment_to_substs(
4647                     fcx, space, span, type_defs, data, substs);
4648             }
4649         }
4650     }
4651
4652     fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4653         fcx: &FnCtxt<'a, 'tcx>,
4654         space: subst::ParamSpace,
4655         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4656         region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4657         data: &hir::AngleBracketedParameterData,
4658         substs: &mut Substs<'tcx>)
4659     {
4660         {
4661             let type_count = type_defs.len(space);
4662             assert_eq!(substs.types.len(space), 0);
4663             for (i, typ) in data.types.iter().enumerate() {
4664                 let t = fcx.to_ty(&**typ);
4665                 if i < type_count {
4666                     substs.types.push(space, t);
4667                 } else if i == type_count {
4668                     span_err!(fcx.tcx().sess, typ.span, E0087,
4669                         "too many type parameters provided: \
4670                          expected at most {} parameter{}, \
4671                          found {} parameter{}",
4672                          type_count,
4673                          if type_count == 1 {""} else {"s"},
4674                          data.types.len(),
4675                          if data.types.len() == 1 {""} else {"s"});
4676                     substs.types.truncate(space, 0);
4677                     break;
4678                 }
4679             }
4680         }
4681
4682         if !data.bindings.is_empty() {
4683             span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4684                       "unexpected binding of associated item in expression path \
4685                        (only allowed in type paths)");
4686         }
4687
4688         {
4689             let region_count = region_defs.len(space);
4690             assert_eq!(substs.regions().len(space), 0);
4691             for (i, lifetime) in data.lifetimes.iter().enumerate() {
4692                 let r = ast_region_to_region(fcx.tcx(), lifetime);
4693                 if i < region_count {
4694                     substs.mut_regions().push(space, r);
4695                 } else if i == region_count {
4696                     span_err!(fcx.tcx().sess, lifetime.span, E0088,
4697                         "too many lifetime parameters provided: \
4698                          expected {} parameter{}, found {} parameter{}",
4699                         region_count,
4700                         if region_count == 1 {""} else {"s"},
4701                         data.lifetimes.len(),
4702                         if data.lifetimes.len() == 1 {""} else {"s"});
4703                     substs.mut_regions().truncate(space, 0);
4704                     break;
4705                 }
4706             }
4707         }
4708     }
4709
4710     /// As with
4711     /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4712     /// but intended for `Foo(A,B) -> C` form. This expands to
4713     /// roughly the same thing as `Foo<(A,B),C>`. One important
4714     /// difference has to do with the treatment of anonymous
4715     /// regions, which are translated into bound regions (NYI).
4716     fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4717         fcx: &FnCtxt<'a, 'tcx>,
4718         space: subst::ParamSpace,
4719         span: Span,
4720         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4721         data: &hir::ParenthesizedParameterData,
4722         substs: &mut Substs<'tcx>)
4723     {
4724         let type_count = type_defs.len(space);
4725         if type_count < 2 {
4726             span_err!(fcx.tcx().sess, span, E0167,
4727                       "parenthesized form always supplies 2 type parameters, \
4728                       but only {} parameter(s) were expected",
4729                       type_count);
4730         }
4731
4732         let input_tys: Vec<Ty> =
4733             data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4734
4735         let tuple_ty = fcx.tcx().mk_tup(input_tys);
4736
4737         if type_count >= 1 {
4738             substs.types.push(space, tuple_ty);
4739         }
4740
4741         let output_ty: Option<Ty> =
4742             data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4743
4744         let output_ty =
4745             output_ty.unwrap_or(fcx.tcx().mk_nil());
4746
4747         if type_count >= 2 {
4748             substs.types.push(space, output_ty);
4749         }
4750     }
4751
4752     fn adjust_type_parameters<'a, 'tcx>(
4753         fcx: &FnCtxt<'a, 'tcx>,
4754         span: Span,
4755         space: ParamSpace,
4756         defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4757         require_type_space: bool,
4758         substs: &mut Substs<'tcx>)
4759     {
4760         let provided_len = substs.types.len(space);
4761         let desired = defs.get_slice(space);
4762         let required_len = desired.iter()
4763                               .take_while(|d| d.default.is_none())
4764                               .count();
4765
4766         debug!("adjust_type_parameters(space={:?}, \
4767                provided_len={}, \
4768                desired_len={}, \
4769                required_len={})",
4770                space,
4771                provided_len,
4772                desired.len(),
4773                required_len);
4774
4775         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4776         assert!(provided_len <= desired.len());
4777
4778         // Nothing specified at all: supply inference variables for
4779         // everything.
4780         if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4781             substs.types.replace(space, Vec::new());
4782             fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4783             return;
4784         }
4785
4786         // Too few parameters specified: report an error and use Err
4787         // for everything.
4788         if provided_len < required_len {
4789             let qualifier =
4790                 if desired.len() != required_len { "at least " } else { "" };
4791             span_err!(fcx.tcx().sess, span, E0089,
4792                 "too few type parameters provided: expected {}{} parameter{}, \
4793                  found {} parameter{}",
4794                 qualifier, required_len,
4795                 if required_len == 1 {""} else {"s"},
4796                 provided_len,
4797                 if provided_len == 1 {""} else {"s"});
4798             substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4799             return;
4800         }
4801
4802         // Otherwise, add in any optional parameters that the user
4803         // omitted. The case of *too many* parameters is handled
4804         // already by
4805         // push_explicit_parameters_from_segment_to_substs(). Note
4806         // that the *default* type are expressed in terms of all prior
4807         // parameters, so we have to substitute as we go with the
4808         // partial substitution that we have built up.
4809         for i in provided_len..desired.len() {
4810             let default = desired[i].default.unwrap();
4811             let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4812             substs.types.push(space, default);
4813         }
4814         assert_eq!(substs.types.len(space), desired.len());
4815
4816         debug!("Final substs: {:?}", substs);
4817     }
4818
4819     fn adjust_region_parameters(
4820         fcx: &FnCtxt,
4821         span: Span,
4822         space: ParamSpace,
4823         defs: &VecPerParamSpace<ty::RegionParameterDef>,
4824         substs: &mut Substs)
4825     {
4826         let provided_len = substs.mut_regions().len(space);
4827         let desired = defs.get_slice(space);
4828
4829         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4830         assert!(provided_len <= desired.len());
4831
4832         // If nothing was provided, just use inference variables.
4833         if provided_len == 0 {
4834             substs.mut_regions().replace(
4835                 space,
4836                 fcx.infcx().region_vars_for_defs(span, desired));
4837             return;
4838         }
4839
4840         // If just the right number were provided, everybody is happy.
4841         if provided_len == desired.len() {
4842             return;
4843         }
4844
4845         // Otherwise, too few were provided. Report an error and then
4846         // use inference variables.
4847         span_err!(fcx.tcx().sess, span, E0090,
4848             "too few lifetime parameters provided: expected {} parameter{}, \
4849              found {} parameter{}",
4850             desired.len(),
4851             if desired.len() == 1 {""} else {"s"},
4852             provided_len,
4853             if provided_len == 1 {""} else {"s"});
4854
4855         substs.mut_regions().replace(
4856             space,
4857             fcx.infcx().region_vars_for_defs(span, desired));
4858     }
4859 }
4860
4861 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4862                                                   sp: Span,
4863                                                   ty: Ty<'tcx>,
4864                                                   f: F) -> Ty<'tcx>
4865     where F: Fn() -> Ty<'tcx>
4866 {
4867     let mut ty = fcx.resolve_type_vars_if_possible(ty);
4868
4869     if ty.is_ty_var() {
4870         let alternative = f();
4871
4872         // If not, error.
4873         if alternative.is_ty_var() || alternative.references_error() {
4874             fcx.type_error_message(sp, |_actual| {
4875                 "the type of this value must be known in this context".to_string()
4876             }, ty, None);
4877             demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4878             ty = fcx.tcx().types.err;
4879         } else {
4880             demand::suptype(fcx, sp, alternative, ty);
4881             ty = alternative;
4882         }
4883     }
4884
4885     ty
4886 }
4887
4888 // Resolves `typ` by a single level if `typ` is a type variable.  If no
4889 // resolution is possible, then an error is reported.
4890 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4891                                             sp: Span,
4892                                             ty: Ty<'tcx>)
4893                                             -> Ty<'tcx>
4894 {
4895     structurally_resolve_type_or_else(fcx, sp, ty, || {
4896         fcx.tcx().types.err
4897     })
4898 }
4899
4900 // Returns true if b contains a break that can exit from b
4901 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4902     // First: is there an unlabeled break immediately
4903     // inside the loop?
4904     (loop_query(&*b, |e| {
4905         match *e {
4906             hir::ExprBreak(None) => true,
4907             _ => false
4908         }
4909     })) ||
4910     // Second: is there a labeled break with label
4911     // <id> nested anywhere inside the loop?
4912     (block_query(b, |e| {
4913         if let hir::ExprBreak(Some(_)) = e.node {
4914             lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4915         } else {
4916             false
4917         }
4918     }))
4919 }
4920
4921 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4922                                        tps: &[hir::TyParam],
4923                                        ty: Ty<'tcx>) {
4924     debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4925            tps.len(),  ty);
4926
4927     // make a vector of booleans initially false, set to true when used
4928     if tps.is_empty() { return; }
4929     let mut tps_used = vec![false; tps.len()];
4930
4931     for leaf_ty in ty.walk() {
4932         if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4933             debug!("Found use of ty param num {}", idx);
4934             tps_used[idx as usize] = true;
4935         }
4936     }
4937
4938     for (i, b) in tps_used.iter().enumerate() {
4939         if !*b {
4940             span_err!(ccx.tcx.sess, tps[i].span, E0091,
4941                 "type parameter `{}` is unused",
4942                 tps[i].name);
4943         }
4944     }
4945 }