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