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