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