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