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