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