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