]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/mod.rs
Auto merge of #32048 - bluss:overloaded-assign-op, r=eddyb
[rust.git] / src / librustc_typeck / check / mod.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*
12
13 # check.rs
14
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function).  Inference is used to supply types wherever they are
18 unknown.
19
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
22
23 - gather: creates type variables to represent the type of each local
24   variable and pattern binding.
25
26 - main: the main pass does the lion's share of the work: it
27   determines the types of all expressions, resolves
28   methods, checks for most invalid conditions, and so forth.  In
29   some cases, where a type is unknown, it may create a type or region
30   variable and use that as the type of an expression.
31
32   In the process of checking, various constraints will be placed on
33   these type variables through the subtyping relationships requested
34   through the `demand` module.  The `infer` module is in charge
35   of resolving those constraints.
36
37 - regionck: after main is complete, the regionck pass goes over all
38   types looking for regions and making sure that they did not escape
39   into places they are not in scope.  This may also influence the
40   final assignments of the various region variables if there is some
41   flexibility.
42
43 - vtable: find and records the impls to use for each trait bound that
44   appears on a type parameter.
45
46 - writeback: writes the final types within a function body, replacing
47   type variables with their final inferred types.  These final types
48   are written into the `tcx.node_types` table, which should *never* contain
49   any reference to a type variable.
50
51 ## Intermediate types
52
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.item_substs`.  These types
56 may contain unresolved type variables.  After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `ccx.tcx`.
60
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
64
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
67
68 n.b.: A type variable is not the same thing as a type parameter.  A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract.  When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`.  This variable will
74 eventually be resolved to some concrete type (which might itself be
75 type parameter).
76
77 */
78
79 pub use self::Expectation::*;
80 pub use self::compare_method::{compare_impl_method, compare_const_impl};
81 use self::TupleArgumentsFlag::*;
82
83 use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
84 use check::_match::pat_ctxt;
85 use dep_graph::DepNode;
86 use fmt_macros::{Parser, Piece, Position};
87 use middle::astconv_util::prohibit_type_params;
88 use middle::cstore::LOCAL_CRATE;
89 use middle::def::{self, Def};
90 use middle::def_id::DefId;
91 use middle::infer;
92 use middle::infer::{TypeOrigin, type_variable};
93 use middle::pat_util::{self, pat_id_map};
94 use middle::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, TyCtxt};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::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 TyCtxt<'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) -> &TyCtxt<'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) -> &TyCtxt<'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              Some((adt, variant))
1444          } else {
1445              None
1446          }
1447     }
1448
1449     pub fn write_nil(&self, node_id: ast::NodeId) {
1450         self.write_ty(node_id, self.tcx().mk_nil());
1451     }
1452     pub fn write_error(&self, node_id: ast::NodeId) {
1453         self.write_ty(node_id, self.tcx().types.err);
1454     }
1455
1456     pub fn require_type_meets(&self,
1457                               ty: Ty<'tcx>,
1458                               span: Span,
1459                               code: traits::ObligationCauseCode<'tcx>,
1460                               bound: ty::BuiltinBound)
1461     {
1462         self.register_builtin_bound(
1463             ty,
1464             bound,
1465             traits::ObligationCause::new(span, self.body_id, code));
1466     }
1467
1468     pub fn require_type_is_sized(&self,
1469                                  ty: Ty<'tcx>,
1470                                  span: Span,
1471                                  code: traits::ObligationCauseCode<'tcx>)
1472     {
1473         self.require_type_meets(ty, span, code, ty::BoundSized);
1474     }
1475
1476     pub fn require_expr_have_sized_type(&self,
1477                                         expr: &hir::Expr,
1478                                         code: traits::ObligationCauseCode<'tcx>)
1479     {
1480         self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1481     }
1482
1483     pub fn type_is_known_to_be_sized(&self,
1484                                      ty: Ty<'tcx>,
1485                                      span: Span)
1486                                      -> bool
1487     {
1488         traits::type_known_to_meet_builtin_bound(self.infcx(),
1489                                                  ty,
1490                                                  ty::BoundSized,
1491                                                  span)
1492     }
1493
1494     pub fn register_builtin_bound(&self,
1495                                   ty: Ty<'tcx>,
1496                                   builtin_bound: ty::BuiltinBound,
1497                                   cause: traits::ObligationCause<'tcx>)
1498     {
1499         self.inh.fulfillment_cx.borrow_mut()
1500             .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1501     }
1502
1503     pub fn register_predicate(&self,
1504                               obligation: traits::PredicateObligation<'tcx>)
1505     {
1506         debug!("register_predicate({:?})",
1507                obligation);
1508         self.inh.fulfillment_cx
1509             .borrow_mut()
1510             .register_predicate_obligation(self.infcx(), obligation);
1511     }
1512
1513     pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1514         let t = ast_ty_to_ty(self, self, ast_t);
1515         self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1516         t
1517     }
1518
1519     pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1520         match self.inh.tables.borrow().node_types.get(&ex.id) {
1521             Some(&t) => t,
1522             None => {
1523                 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1524                                             self.tag()));
1525             }
1526         }
1527     }
1528
1529     /// Apply `adjustment` to the type of `expr`
1530     pub fn adjust_expr_ty(&self,
1531                           expr: &hir::Expr,
1532                           adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1533                           -> Ty<'tcx>
1534     {
1535         let raw_ty = self.expr_ty(expr);
1536         let raw_ty = self.infcx().shallow_resolve(raw_ty);
1537         let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1538         raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1539             self.inh.tables.borrow().method_map.get(&method_call)
1540                                         .map(|method| resolve_ty(method.ty))
1541         })
1542     }
1543
1544     pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1545         match self.inh.tables.borrow().node_types.get(&id) {
1546             Some(&t) => t,
1547             None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1548             None => {
1549                 self.tcx().sess.bug(
1550                     &format!("no type for node {}: {} in fcx {}",
1551                             id, self.tcx().map.node_to_string(id),
1552                             self.tag()));
1553             }
1554         }
1555     }
1556
1557     pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1558         // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1559         // it changes when we upgrade the snapshot compiler
1560         fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1561                                         -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1562             &tables.item_substs
1563         }
1564
1565         Ref::map(self.inh.tables.borrow(), project_item_susbts)
1566     }
1567
1568     pub fn opt_node_ty_substs<F>(&self,
1569                                  id: ast::NodeId,
1570                                  f: F) where
1571         F: FnOnce(&ty::ItemSubsts<'tcx>),
1572     {
1573         match self.inh.tables.borrow().item_substs.get(&id) {
1574             Some(s) => { f(s) }
1575             None => { }
1576         }
1577     }
1578
1579     pub fn mk_subty(&self,
1580                     a_is_expected: bool,
1581                     origin: TypeOrigin,
1582                     sub: Ty<'tcx>,
1583                     sup: Ty<'tcx>)
1584                     -> Result<(), TypeError<'tcx>> {
1585         infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1586     }
1587
1588     pub fn mk_eqty(&self,
1589                    a_is_expected: bool,
1590                    origin: TypeOrigin,
1591                    sub: Ty<'tcx>,
1592                    sup: Ty<'tcx>)
1593                    -> Result<(), TypeError<'tcx>> {
1594         infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1595     }
1596
1597     pub fn mk_subr(&self,
1598                    origin: infer::SubregionOrigin<'tcx>,
1599                    sub: ty::Region,
1600                    sup: ty::Region) {
1601         infer::mk_subr(self.infcx(), origin, sub, sup)
1602     }
1603
1604     pub fn type_error_message<M>(&self,
1605                                  sp: Span,
1606                                  mk_msg: M,
1607                                  actual_ty: Ty<'tcx>,
1608                                  err: Option<&TypeError<'tcx>>)
1609         where M: FnOnce(String) -> String,
1610     {
1611         self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1612     }
1613
1614     pub fn type_error_struct<M>(&self,
1615                                 sp: Span,
1616                                 mk_msg: M,
1617                                 actual_ty: Ty<'tcx>,
1618                                 err: Option<&TypeError<'tcx>>)
1619                                 -> DiagnosticBuilder<'tcx>
1620         where M: FnOnce(String) -> String,
1621     {
1622         self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1623     }
1624
1625     pub fn report_mismatched_types(&self,
1626                                    sp: Span,
1627                                    e: Ty<'tcx>,
1628                                    a: Ty<'tcx>,
1629                                    err: &TypeError<'tcx>) {
1630         self.infcx().report_mismatched_types(sp, e, a, err)
1631     }
1632
1633     /// Registers an obligation for checking later, during regionck, that the type `ty` must
1634     /// outlive the region `r`.
1635     pub fn register_region_obligation(&self,
1636                                       ty: Ty<'tcx>,
1637                                       region: ty::Region,
1638                                       cause: traits::ObligationCause<'tcx>)
1639     {
1640         let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1641         fulfillment_cx.register_region_obligation(ty, region, cause);
1642     }
1643
1644     /// Registers an obligation for checking later, during regionck, that the type `ty` must
1645     /// outlive the region `r`.
1646     pub fn register_wf_obligation(&self,
1647                                   ty: Ty<'tcx>,
1648                                   span: Span,
1649                                   code: traits::ObligationCauseCode<'tcx>)
1650     {
1651         // WF obligations never themselves fail, so no real need to give a detailed cause:
1652         let cause = traits::ObligationCause::new(span, self.body_id, code);
1653         self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1654     }
1655
1656     pub fn register_old_wf_obligation(&self,
1657                                       ty: Ty<'tcx>,
1658                                       span: Span,
1659                                       code: traits::ObligationCauseCode<'tcx>)
1660     {
1661         // Registers an "old-style" WF obligation that uses the
1662         // implicator code.  This is basically a buggy version of
1663         // `register_wf_obligation` that is being kept around
1664         // temporarily just to help with phasing in the newer rules.
1665         //
1666         // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1667         let cause = traits::ObligationCause::new(span, self.body_id, code);
1668         self.register_region_obligation(ty, ty::ReEmpty, cause);
1669     }
1670
1671     /// Registers obligations that all types appearing in `substs` are well-formed.
1672     pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1673     {
1674         for &ty in &substs.types {
1675             self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1676         }
1677     }
1678
1679     /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1680     /// type/region parameter was instantiated (`substs`), creates and registers suitable
1681     /// trait/region obligations.
1682     ///
1683     /// For example, if there is a function:
1684     ///
1685     /// ```
1686     /// fn foo<'a,T:'a>(...)
1687     /// ```
1688     ///
1689     /// and a reference:
1690     ///
1691     /// ```
1692     /// let f = foo;
1693     /// ```
1694     ///
1695     /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1696     /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1697     pub fn add_obligations_for_parameters(&self,
1698                                           cause: traits::ObligationCause<'tcx>,
1699                                           predicates: &ty::InstantiatedPredicates<'tcx>)
1700     {
1701         assert!(!predicates.has_escaping_regions());
1702
1703         debug!("add_obligations_for_parameters(predicates={:?})",
1704                predicates);
1705
1706         for obligation in traits::predicates_for_generics(cause, predicates) {
1707             self.register_predicate(obligation);
1708         }
1709     }
1710
1711     // FIXME(arielb1): use this instead of field.ty everywhere
1712     pub fn field_ty(&self,
1713                     span: Span,
1714                     field: ty::FieldDef<'tcx>,
1715                     substs: &Substs<'tcx>)
1716                     -> Ty<'tcx>
1717     {
1718         self.normalize_associated_types_in(span,
1719                                            &field.ty(self.tcx(), substs))
1720     }
1721
1722     // Only for fields! Returns <none> for methods>
1723     // Indifferent to privacy flags
1724     fn check_casts(&self) {
1725         let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1726         for cast in deferred_cast_checks.drain(..) {
1727             cast.check(self);
1728         }
1729     }
1730
1731     /// Apply "fallbacks" to some types
1732     /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1733     fn default_type_parameters(&self) {
1734         use middle::ty::error::UnconstrainedNumeric::Neither;
1735         use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1736         for ty in &self.infcx().unsolved_variables() {
1737             let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1738             if self.infcx().type_var_diverges(resolved) {
1739                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1740             } else {
1741                 match self.infcx().type_is_unconstrained_numeric(resolved) {
1742                     UnconstrainedInt => {
1743                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1744                     },
1745                     UnconstrainedFloat => {
1746                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1747                     }
1748                     Neither => { }
1749                 }
1750             }
1751         }
1752     }
1753
1754     fn select_all_obligations_and_apply_defaults(&self) {
1755         if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1756             self.new_select_all_obligations_and_apply_defaults();
1757         } else {
1758             self.old_select_all_obligations_and_apply_defaults();
1759         }
1760     }
1761
1762     // Implements old type inference fallback algorithm
1763     fn old_select_all_obligations_and_apply_defaults(&self) {
1764         self.select_obligations_where_possible();
1765         self.default_type_parameters();
1766         self.select_obligations_where_possible();
1767     }
1768
1769     fn new_select_all_obligations_and_apply_defaults(&self) {
1770         use middle::ty::error::UnconstrainedNumeric::Neither;
1771         use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1772
1773         // For the time being this errs on the side of being memory wasteful but provides better
1774         // error reporting.
1775         // let type_variables = self.infcx().type_variables.clone();
1776
1777         // There is a possibility that this algorithm will have to run an arbitrary number of times
1778         // to terminate so we bound it by the compiler's recursion limit.
1779         for _ in 0..self.tcx().sess.recursion_limit.get() {
1780             // First we try to solve all obligations, it is possible that the last iteration
1781             // has made it possible to make more progress.
1782             self.select_obligations_where_possible();
1783
1784             let mut conflicts = Vec::new();
1785
1786             // Collect all unsolved type, integral and floating point variables.
1787             let unsolved_variables = self.inh.infcx.unsolved_variables();
1788
1789             // We must collect the defaults *before* we do any unification. Because we have
1790             // directly attached defaults to the type variables any unification that occurs
1791             // will erase defaults causing conflicting defaults to be completely ignored.
1792             let default_map: FnvHashMap<_, _> =
1793                 unsolved_variables
1794                     .iter()
1795                     .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1796                     .collect();
1797
1798             let mut unbound_tyvars = HashSet::new();
1799
1800             debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1801
1802             // We loop over the unsolved variables, resolving them and if they are
1803             // and unconstrainted numeric type we add them to the set of unbound
1804             // variables. We do this so we only apply literal fallback to type
1805             // variables without defaults.
1806             for ty in &unsolved_variables {
1807                 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1808                 if self.infcx().type_var_diverges(resolved) {
1809                     demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1810                 } else {
1811                     match self.infcx().type_is_unconstrained_numeric(resolved) {
1812                         UnconstrainedInt | UnconstrainedFloat => {
1813                             unbound_tyvars.insert(resolved);
1814                         },
1815                         Neither => {}
1816                     }
1817                 }
1818             }
1819
1820             // We now remove any numeric types that also have defaults, and instead insert
1821             // the type variable with a defined fallback.
1822             for ty in &unsolved_variables {
1823                 if let Some(_default) = default_map.get(ty) {
1824                     let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1825
1826                     debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1827                              ty, _default);
1828
1829                     match resolved.sty {
1830                         ty::TyInfer(ty::TyVar(_)) => {
1831                             unbound_tyvars.insert(ty);
1832                         }
1833
1834                         ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1835                             unbound_tyvars.insert(ty);
1836                             if unbound_tyvars.contains(resolved) {
1837                                 unbound_tyvars.remove(resolved);
1838                             }
1839                         }
1840
1841                         _ => {}
1842                     }
1843                 }
1844             }
1845
1846             // If there are no more fallbacks to apply at this point we have applied all possible
1847             // defaults and type inference will proceed as normal.
1848             if unbound_tyvars.is_empty() {
1849                 break;
1850             }
1851
1852             // Finally we go through each of the unbound type variables and unify them with
1853             // the proper fallback, reporting a conflicting default error if any of the
1854             // unifications fail. We know it must be a conflicting default because the
1855             // variable would only be in `unbound_tyvars` and have a concrete value if
1856             // it had been solved by previously applying a default.
1857
1858             // We wrap this in a transaction for error reporting, if we detect a conflict
1859             // we will rollback the inference context to its prior state so we can probe
1860             // for conflicts and correctly report them.
1861
1862
1863             let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1864                 for ty in &unbound_tyvars {
1865                     if self.infcx().type_var_diverges(ty) {
1866                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1867                     } else {
1868                         match self.infcx().type_is_unconstrained_numeric(ty) {
1869                             UnconstrainedInt => {
1870                                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1871                             },
1872                             UnconstrainedFloat => {
1873                                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1874                             }
1875                             Neither => {
1876                                 if let Some(default) = default_map.get(ty) {
1877                                     let default = default.clone();
1878                                     match infer::mk_eqty(self.infcx(), false,
1879                                                          TypeOrigin::Misc(default.origin_span),
1880                                                          ty, default.ty) {
1881                                         Ok(()) => {}
1882                                         Err(_) => {
1883                                             conflicts.push((*ty, default));
1884                                         }
1885                                     }
1886                                 }
1887                             }
1888                         }
1889                     }
1890                 }
1891
1892                 // If there are conflicts we rollback, otherwise commit
1893                 if conflicts.len() > 0 {
1894                     Err(())
1895                 } else {
1896                     Ok(())
1897                 }
1898             });
1899
1900             if conflicts.len() > 0 {
1901                 // Loop through each conflicting default, figuring out the default that caused
1902                 // a unification failure and then report an error for each.
1903                 for (conflict, default) in conflicts {
1904                     let conflicting_default =
1905                         self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1906                             .unwrap_or(type_variable::Default {
1907                                 ty: self.infcx().next_ty_var(),
1908                                 origin_span: codemap::DUMMY_SP,
1909                                 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1910                             });
1911
1912                     // This is to ensure that we elimnate any non-determinism from the error
1913                     // reporting by fixing an order, it doesn't matter what order we choose
1914                     // just that it is consistent.
1915                     let (first_default, second_default) =
1916                         if default.def_id < conflicting_default.def_id {
1917                             (default, conflicting_default)
1918                         } else {
1919                             (conflicting_default, default)
1920                         };
1921
1922
1923                     self.infcx().report_conflicting_default_types(
1924                         first_default.origin_span,
1925                         first_default,
1926                         second_default)
1927                 }
1928             }
1929         }
1930
1931         self.select_obligations_where_possible();
1932     }
1933
1934     // For use in error handling related to default type parameter fallback. We explicitly
1935     // apply the default that caused conflict first to a local version of the type variable
1936     // table then apply defaults until we find a conflict. That default must be the one
1937     // that caused conflict earlier.
1938     fn find_conflicting_default(&self,
1939                                 unbound_vars: &HashSet<Ty<'tcx>>,
1940                                 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1941                                 conflict: Ty<'tcx>)
1942                                 -> Option<type_variable::Default<'tcx>> {
1943         use middle::ty::error::UnconstrainedNumeric::Neither;
1944         use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1945
1946         // Ensure that we apply the conflicting default first
1947         let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1948         unbound_tyvars.push(conflict);
1949         unbound_tyvars.extend(unbound_vars.iter());
1950
1951         let mut result = None;
1952         // We run the same code as above applying defaults in order, this time when
1953         // we find the conflict we just return it for error reporting above.
1954
1955         // We also run this inside snapshot that never commits so we can do error
1956         // reporting for more then one conflict.
1957         for ty in &unbound_tyvars {
1958             if self.infcx().type_var_diverges(ty) {
1959                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1960             } else {
1961                 match self.infcx().type_is_unconstrained_numeric(ty) {
1962                     UnconstrainedInt => {
1963                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1964                     },
1965                     UnconstrainedFloat => {
1966                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1967                     },
1968                     Neither => {
1969                         if let Some(default) = default_map.get(ty) {
1970                             let default = default.clone();
1971                             match infer::mk_eqty(self.infcx(), false,
1972                                                  TypeOrigin::Misc(default.origin_span),
1973                                                  ty, default.ty) {
1974                                 Ok(()) => {}
1975                                 Err(_) => {
1976                                     result = Some(default);
1977                                 }
1978                             }
1979                         }
1980                     }
1981                 }
1982             }
1983         }
1984
1985         return result;
1986     }
1987
1988     fn select_all_obligations_or_error(&self) {
1989         debug!("select_all_obligations_or_error");
1990
1991         // upvar inference should have ensured that all deferred call
1992         // resolutions are handled by now.
1993         assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1994
1995         self.select_all_obligations_and_apply_defaults();
1996
1997         let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1998         match fulfillment_cx.select_all_or_error(self.infcx()) {
1999             Ok(()) => { }
2000             Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2001         }
2002     }
2003
2004     /// Select as many obligations as we can at present.
2005     fn select_obligations_where_possible(&self) {
2006         match
2007             self.inh.fulfillment_cx
2008             .borrow_mut()
2009             .select_where_possible(self.infcx())
2010         {
2011             Ok(()) => { }
2012             Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2013         }
2014     }
2015
2016     fn private_item_is_visible(&self, def_id: DefId) -> bool {
2017         match self.tcx().map.as_local_node_id(def_id) {
2018             Some(node_id) => self.tcx().map.private_item_is_visible_from(node_id, self.body_id),
2019             None => false, // Private items from other crates are never visible
2020         }
2021     }
2022 }
2023
2024 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2025     fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2026         Some(self.base_object_lifetime_default(span))
2027     }
2028
2029     fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2030         // RFC #599 specifies that object lifetime defaults take
2031         // precedence over other defaults. But within a fn body we
2032         // don't have a *default* region, rather we use inference to
2033         // find the *correct* region, which is strictly more general
2034         // (and anyway, within a fn body the right region may not even
2035         // be something the user can write explicitly, since it might
2036         // be some expression).
2037         self.infcx().next_region_var(infer::MiscVariable(span))
2038     }
2039
2040     fn anon_regions(&self, span: Span, count: usize)
2041                     -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2042         Ok((0..count).map(|_| {
2043             self.infcx().next_region_var(infer::MiscVariable(span))
2044         }).collect())
2045     }
2046 }
2047
2048 /// Whether `autoderef` requires types to resolve.
2049 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2050 pub enum UnresolvedTypeAction {
2051     /// Produce an error and return `TyError` whenever a type cannot
2052     /// be resolved (i.e. it is `TyInfer`).
2053     Error,
2054     /// Go on without emitting any errors, and return the unresolved
2055     /// type. Useful for probing, e.g. in coercions.
2056     Ignore
2057 }
2058
2059 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2060 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2061 ///
2062 /// Note: this method does not modify the adjustments table. The caller is responsible for
2063 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2064 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2065                                  sp: Span,
2066                                  base_ty: Ty<'tcx>,
2067                                  opt_expr: Option<&hir::Expr>,
2068                                  unresolved_type_action: UnresolvedTypeAction,
2069                                  mut lvalue_pref: LvaluePreference,
2070                                  mut should_stop: F)
2071                                  -> (Ty<'tcx>, usize, Option<T>)
2072     where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2073 {
2074     debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2075            base_ty,
2076            opt_expr,
2077            lvalue_pref);
2078
2079     let mut t = base_ty;
2080     for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2081         let resolved_t = match unresolved_type_action {
2082             UnresolvedTypeAction::Error => {
2083                 structurally_resolved_type(fcx, sp, t)
2084             }
2085             UnresolvedTypeAction::Ignore => {
2086                 // We can continue even when the type cannot be resolved
2087                 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2088                 // and `try_overloaded_deref` both simply return `None`
2089                 // in such a case without producing spurious errors.
2090                 fcx.resolve_type_vars_if_possible(t)
2091             }
2092         };
2093         if resolved_t.references_error() {
2094             return (resolved_t, autoderefs, None);
2095         }
2096
2097         match should_stop(resolved_t, autoderefs) {
2098             Some(x) => return (resolved_t, autoderefs, Some(x)),
2099             None => {}
2100         }
2101
2102         // Otherwise, deref if type is derefable:
2103         let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2104             Some(mt) => Some(mt),
2105             None => {
2106                 let method_call =
2107                     opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2108
2109                 // Super subtle: it might seem as though we should
2110                 // pass `opt_expr` to `try_overloaded_deref`, so that
2111                 // the (implicit) autoref of using an overloaded deref
2112                 // would get added to the adjustment table. However we
2113                 // do not do that, because it's kind of a
2114                 // "meta-adjustment" -- instead, we just leave it
2115                 // unrecorded and know that there "will be" an
2116                 // autoref. regionck and other bits of the code base,
2117                 // when they encounter an overloaded autoderef, have
2118                 // to do some reconstructive surgery. This is a pretty
2119                 // complex mess that is begging for a proper MIR.
2120                 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2121             }
2122         };
2123         match mt {
2124             Some(mt) => {
2125                 t = mt.ty;
2126                 if mt.mutbl == hir::MutImmutable {
2127                     lvalue_pref = NoPreference;
2128                 }
2129             }
2130             None => return (resolved_t, autoderefs, None)
2131         }
2132     }
2133
2134     // We've reached the recursion limit, error gracefully.
2135     span_err!(fcx.tcx().sess, sp, E0055,
2136         "reached the recursion limit while auto-dereferencing {:?}",
2137         base_ty);
2138     (fcx.tcx().types.err, 0, None)
2139 }
2140
2141 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2142                                   span: Span,
2143                                   method_call: Option<MethodCall>,
2144                                   base_expr: Option<&hir::Expr>,
2145                                   base_ty: Ty<'tcx>,
2146                                   lvalue_pref: LvaluePreference)
2147                                   -> Option<ty::TypeAndMut<'tcx>>
2148 {
2149     // Try DerefMut first, if preferred.
2150     let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2151         (PreferMutLvalue, Some(trait_did)) => {
2152             method::lookup_in_trait(fcx, span, base_expr,
2153                                     token::intern("deref_mut"), trait_did,
2154                                     base_ty, None)
2155         }
2156         _ => None
2157     };
2158
2159     // Otherwise, fall back to Deref.
2160     let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2161         (None, Some(trait_did)) => {
2162             method::lookup_in_trait(fcx, span, base_expr,
2163                                     token::intern("deref"), trait_did,
2164                                     base_ty, None)
2165         }
2166         (method, _) => method
2167     };
2168
2169     make_overloaded_lvalue_return_type(fcx, method_call, method)
2170 }
2171
2172 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2173 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2174 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2175 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2176                                                 method_call: Option<MethodCall>,
2177                                                 method: Option<MethodCallee<'tcx>>)
2178                                                 -> Option<ty::TypeAndMut<'tcx>>
2179 {
2180     match method {
2181         Some(method) => {
2182             // extract method return type, which will be &T;
2183             // all LB regions should have been instantiated during method lookup
2184             let ret_ty = method.ty.fn_ret();
2185             let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2186
2187             if let Some(method_call) = method_call {
2188                 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2189             }
2190
2191             // method returns &T, but the type as visible to user is T, so deref
2192             ret_ty.builtin_deref(true, NoPreference)
2193         }
2194         None => None,
2195     }
2196 }
2197
2198 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2199                              expr: &hir::Expr,
2200                              base_expr: &'tcx hir::Expr,
2201                              base_ty: Ty<'tcx>,
2202                              idx_ty: Ty<'tcx>,
2203                              lvalue_pref: LvaluePreference)
2204                              -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2205 {
2206     // FIXME(#18741) -- this is almost but not quite the same as the
2207     // autoderef that normal method probing does. They could likely be
2208     // consolidated.
2209
2210     let (ty, autoderefs, final_mt) = autoderef(fcx,
2211                                                base_expr.span,
2212                                                base_ty,
2213                                                Some(base_expr),
2214                                                UnresolvedTypeAction::Error,
2215                                                lvalue_pref,
2216                                                |adj_ty, idx| {
2217         try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2218                        adj_ty, idx, false, lvalue_pref, idx_ty)
2219     });
2220
2221     if final_mt.is_some() {
2222         return final_mt;
2223     }
2224
2225     // After we have fully autoderef'd, if the resulting type is [T; n], then
2226     // do a final unsized coercion to yield [T].
2227     if let ty::TyArray(element_ty, _) = ty.sty {
2228         let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2229         try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2230                        adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2231     } else {
2232         None
2233     }
2234 }
2235
2236 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2237 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2238 /// This loop implements one step in that search; the autoderef loop is implemented by
2239 /// `lookup_indexing`.
2240 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2241                             method_call: MethodCall,
2242                             expr: &hir::Expr,
2243                             base_expr: &'tcx hir::Expr,
2244                             adjusted_ty: Ty<'tcx>,
2245                             autoderefs: usize,
2246                             unsize: bool,
2247                             lvalue_pref: LvaluePreference,
2248                             index_ty: Ty<'tcx>)
2249                             -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2250 {
2251     let tcx = fcx.tcx();
2252     debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2253                            autoderefs={}, unsize={}, index_ty={:?})",
2254            expr,
2255            base_expr,
2256            adjusted_ty,
2257            autoderefs,
2258            unsize,
2259            index_ty);
2260
2261     let input_ty = fcx.infcx().next_ty_var();
2262
2263     // First, try built-in indexing.
2264     match (adjusted_ty.builtin_index(), &index_ty.sty) {
2265         (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2266             debug!("try_index_step: success, using built-in indexing");
2267             // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2268             assert!(!unsize);
2269             fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2270             return Some((tcx.types.usize, ty));
2271         }
2272         _ => {}
2273     }
2274
2275     // Try `IndexMut` first, if preferred.
2276     let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2277         (PreferMutLvalue, Some(trait_did)) => {
2278             method::lookup_in_trait_adjusted(fcx,
2279                                              expr.span,
2280                                              Some(&base_expr),
2281                                              token::intern("index_mut"),
2282                                              trait_did,
2283                                              autoderefs,
2284                                              unsize,
2285                                              adjusted_ty,
2286                                              Some(vec![input_ty]))
2287         }
2288         _ => None,
2289     };
2290
2291     // Otherwise, fall back to `Index`.
2292     let method = match (method, tcx.lang_items.index_trait()) {
2293         (None, Some(trait_did)) => {
2294             method::lookup_in_trait_adjusted(fcx,
2295                                              expr.span,
2296                                              Some(&base_expr),
2297                                              token::intern("index"),
2298                                              trait_did,
2299                                              autoderefs,
2300                                              unsize,
2301                                              adjusted_ty,
2302                                              Some(vec![input_ty]))
2303         }
2304         (method, _) => method,
2305     };
2306
2307     // If some lookup succeeds, write callee into table and extract index/element
2308     // type from the method signature.
2309     // If some lookup succeeded, install method in table
2310     method.and_then(|method| {
2311         debug!("try_index_step: success, using overloaded indexing");
2312         make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2313             map(|ret| (input_ty, ret.ty))
2314     })
2315 }
2316
2317 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2318                                          sp: Span,
2319                                          method_fn_ty: Ty<'tcx>,
2320                                          callee_expr: &'tcx hir::Expr,
2321                                          args_no_rcvr: &'tcx [P<hir::Expr>],
2322                                          tuple_arguments: TupleArgumentsFlag,
2323                                          expected: Expectation<'tcx>)
2324                                          -> ty::FnOutput<'tcx> {
2325     if method_fn_ty.references_error() {
2326         let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2327
2328         let err_inputs = match tuple_arguments {
2329             DontTupleArguments => err_inputs,
2330             TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2331         };
2332
2333         check_argument_types(fcx,
2334                              sp,
2335                              &err_inputs[..],
2336                              &[],
2337                              args_no_rcvr,
2338                              false,
2339                              tuple_arguments);
2340         ty::FnConverging(fcx.tcx().types.err)
2341     } else {
2342         match method_fn_ty.sty {
2343             ty::TyBareFn(_, ref fty) => {
2344                 // HACK(eddyb) ignore self in the definition (see above).
2345                 let expected_arg_tys = expected_types_for_fn_args(fcx,
2346                                                                   sp,
2347                                                                   expected,
2348                                                                   fty.sig.0.output,
2349                                                                   &fty.sig.0.inputs[1..]);
2350                 check_argument_types(fcx,
2351                                      sp,
2352                                      &fty.sig.0.inputs[1..],
2353                                      &expected_arg_tys[..],
2354                                      args_no_rcvr,
2355                                      fty.sig.0.variadic,
2356                                      tuple_arguments);
2357                 fty.sig.0.output
2358             }
2359             _ => {
2360                 fcx.tcx().sess.span_bug(callee_expr.span,
2361                                         "method without bare fn type");
2362             }
2363         }
2364     }
2365 }
2366
2367 /// Generic function that factors out common logic from function calls, method calls and overloaded
2368 /// operators.
2369 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2370                                   sp: Span,
2371                                   fn_inputs: &[Ty<'tcx>],
2372                                   expected_arg_tys: &[Ty<'tcx>],
2373                                   args: &'tcx [P<hir::Expr>],
2374                                   variadic: bool,
2375                                   tuple_arguments: TupleArgumentsFlag) {
2376     let tcx = fcx.ccx.tcx;
2377
2378     // Grab the argument types, supplying fresh type variables
2379     // if the wrong number of arguments were supplied
2380     let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2381         args.len()
2382     } else {
2383         1
2384     };
2385
2386     // All the input types from the fn signature must outlive the call
2387     // so as to validate implied bounds.
2388     for &fn_input_ty in fn_inputs {
2389         fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2390     }
2391
2392     let mut expected_arg_tys = expected_arg_tys;
2393     let expected_arg_count = fn_inputs.len();
2394     let formal_tys = if tuple_arguments == TupleArguments {
2395         let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2396         match tuple_type.sty {
2397             ty::TyTuple(ref arg_types) => {
2398                 if arg_types.len() != args.len() {
2399                     span_err!(tcx.sess, sp, E0057,
2400                         "this function takes {} parameter{} but {} parameter{} supplied",
2401                         arg_types.len(),
2402                         if arg_types.len() == 1 {""} else {"s"},
2403                         args.len(),
2404                         if args.len() == 1 {" was"} else {"s were"});
2405                     expected_arg_tys = &[];
2406                     err_args(fcx.tcx(), args.len())
2407                 } else {
2408                     expected_arg_tys = match expected_arg_tys.get(0) {
2409                         Some(&ty) => match ty.sty {
2410                             ty::TyTuple(ref tys) => &tys,
2411                             _ => &[]
2412                         },
2413                         None => &[]
2414                     };
2415                     (*arg_types).clone()
2416                 }
2417             }
2418             _ => {
2419                 span_err!(tcx.sess, sp, E0059,
2420                     "cannot use call notation; the first type parameter \
2421                      for the function trait is neither a tuple nor unit");
2422                 expected_arg_tys = &[];
2423                 err_args(fcx.tcx(), args.len())
2424             }
2425         }
2426     } else if expected_arg_count == supplied_arg_count {
2427         fn_inputs.to_vec()
2428     } else if variadic {
2429         if supplied_arg_count >= expected_arg_count {
2430             fn_inputs.to_vec()
2431         } else {
2432             span_err!(tcx.sess, sp, E0060,
2433                 "this function takes at least {} parameter{} \
2434                  but {} parameter{} supplied",
2435                 expected_arg_count,
2436                 if expected_arg_count == 1 {""} else {"s"},
2437                 supplied_arg_count,
2438                 if supplied_arg_count == 1 {" was"} else {"s were"});
2439             expected_arg_tys = &[];
2440             err_args(fcx.tcx(), supplied_arg_count)
2441         }
2442     } else {
2443         span_err!(tcx.sess, sp, E0061,
2444             "this function takes {} parameter{} but {} parameter{} supplied",
2445             expected_arg_count,
2446             if expected_arg_count == 1 {""} else {"s"},
2447             supplied_arg_count,
2448             if supplied_arg_count == 1 {" was"} else {"s were"});
2449         expected_arg_tys = &[];
2450         err_args(fcx.tcx(), supplied_arg_count)
2451     };
2452
2453     debug!("check_argument_types: formal_tys={:?}",
2454            formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2455
2456     // Check the arguments.
2457     // We do this in a pretty awful way: first we typecheck any arguments
2458     // that are not anonymous functions, then we typecheck the anonymous
2459     // functions. This is so that we have more information about the types
2460     // of arguments when we typecheck the functions. This isn't really the
2461     // right way to do this.
2462     let xs = [false, true];
2463     let mut any_diverges = false; // has any of the arguments diverged?
2464     let mut warned = false; // have we already warned about unreachable code?
2465     for check_blocks in &xs {
2466         let check_blocks = *check_blocks;
2467         debug!("check_blocks={}", check_blocks);
2468
2469         // More awful hacks: before we check argument types, try to do
2470         // an "opportunistic" vtable resolution of any trait bounds on
2471         // the call. This helps coercions.
2472         if check_blocks {
2473             fcx.select_obligations_where_possible();
2474         }
2475
2476         // For variadic functions, we don't have a declared type for all of
2477         // the arguments hence we only do our usual type checking with
2478         // the arguments who's types we do know.
2479         let t = if variadic {
2480             expected_arg_count
2481         } else if tuple_arguments == TupleArguments {
2482             args.len()
2483         } else {
2484             supplied_arg_count
2485         };
2486         for (i, arg) in args.iter().take(t).enumerate() {
2487             if any_diverges && !warned {
2488                 fcx.ccx
2489                     .tcx
2490                     .sess
2491                     .add_lint(lint::builtin::UNREACHABLE_CODE,
2492                               arg.id,
2493                               arg.span,
2494                               "unreachable expression".to_string());
2495                 warned = true;
2496             }
2497             let is_block = match arg.node {
2498                 hir::ExprClosure(..) => true,
2499                 _ => false
2500             };
2501
2502             if is_block == check_blocks {
2503                 debug!("checking the argument");
2504                 let formal_ty = formal_tys[i];
2505
2506                 // The special-cased logic below has three functions:
2507                 // 1. Provide as good of an expected type as possible.
2508                 let expected = expected_arg_tys.get(i).map(|&ty| {
2509                     Expectation::rvalue_hint(fcx.tcx(), ty)
2510                 });
2511
2512                 check_expr_with_unifier(fcx,
2513                                         &arg,
2514                                         expected.unwrap_or(ExpectHasType(formal_ty)),
2515                                         NoPreference, || {
2516                     // 2. Coerce to the most detailed type that could be coerced
2517                     //    to, which is `expected_ty` if `rvalue_hint` returns an
2518                     //    `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2519                     let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2520                     demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2521
2522                     // 3. Relate the expected type and the formal one,
2523                     //    if the expected type was used for the coercion.
2524                     coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2525                 });
2526             }
2527
2528             if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2529                 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2530             }
2531         }
2532         if any_diverges && !warned {
2533             let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2534             fcx.ccx
2535                 .tcx
2536                 .sess
2537                 .add_lint(lint::builtin::UNREACHABLE_CODE,
2538                           parent,
2539                           sp,
2540                           "unreachable call".to_string());
2541             warned = true;
2542         }
2543
2544     }
2545
2546     // We also need to make sure we at least write the ty of the other
2547     // arguments which we skipped above.
2548     if variadic {
2549         for arg in args.iter().skip(expected_arg_count) {
2550             check_expr(fcx, &arg);
2551
2552             // There are a few types which get autopromoted when passed via varargs
2553             // in C but we just error out instead and require explicit casts.
2554             let arg_ty = structurally_resolved_type(fcx, arg.span,
2555                                                     fcx.expr_ty(&arg));
2556             match arg_ty.sty {
2557                 ty::TyFloat(ast::FloatTy::F32) => {
2558                     fcx.type_error_message(arg.span,
2559                                            |t| {
2560                         format!("can't pass an {} to variadic \
2561                                  function, cast to c_double", t)
2562                     }, arg_ty, None);
2563                 }
2564                 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2565                     fcx.type_error_message(arg.span, |t| {
2566                         format!("can't pass {} to variadic \
2567                                  function, cast to c_int",
2568                                        t)
2569                     }, arg_ty, None);
2570                 }
2571                 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2572                     fcx.type_error_message(arg.span, |t| {
2573                         format!("can't pass {} to variadic \
2574                                  function, cast to c_uint",
2575                                        t)
2576                     }, arg_ty, None);
2577                 }
2578                 _ => {}
2579             }
2580         }
2581     }
2582 }
2583
2584 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2585 fn err_args<'tcx>(tcx: &TyCtxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2586     (0..len).map(|_| tcx.types.err).collect()
2587 }
2588
2589 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2590                         call_expr: &hir::Expr,
2591                         output: ty::FnOutput<'tcx>) {
2592     fcx.write_ty(call_expr.id, match output {
2593         ty::FnConverging(output_ty) => output_ty,
2594         ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2595     });
2596 }
2597
2598 // AST fragment checking
2599 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2600                        lit: &ast::Lit,
2601                        expected: Expectation<'tcx>)
2602                        -> Ty<'tcx>
2603 {
2604     let tcx = fcx.ccx.tcx;
2605
2606     match lit.node {
2607         ast::LitKind::Str(..) => tcx.mk_static_str(),
2608         ast::LitKind::ByteStr(ref v) => {
2609             tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2610                             tcx.mk_array(tcx.types.u8, v.len()))
2611         }
2612         ast::LitKind::Byte(_) => tcx.types.u8,
2613         ast::LitKind::Char(_) => tcx.types.char,
2614         ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2615         ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2616         ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2617             let opt_ty = expected.to_option(fcx).and_then(|ty| {
2618                 match ty.sty {
2619                     ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2620                     ty::TyChar => Some(tcx.types.u8),
2621                     ty::TyRawPtr(..) => Some(tcx.types.usize),
2622                     ty::TyBareFn(..) => Some(tcx.types.usize),
2623                     _ => None
2624                 }
2625             });
2626             opt_ty.unwrap_or_else(
2627                 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2628         }
2629         ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2630         ast::LitKind::FloatUnsuffixed(_) => {
2631             let opt_ty = expected.to_option(fcx).and_then(|ty| {
2632                 match ty.sty {
2633                     ty::TyFloat(_) => Some(ty),
2634                     _ => None
2635                 }
2636             });
2637             opt_ty.unwrap_or_else(
2638                 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2639         }
2640         ast::LitKind::Bool(_) => tcx.types.bool
2641     }
2642 }
2643
2644 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2645                                 expr: &'tcx hir::Expr,
2646                                 expected: Ty<'tcx>) {
2647     check_expr_with_unifier(
2648         fcx, expr, ExpectHasType(expected), NoPreference,
2649         || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2650 }
2651
2652 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2653                                      expr: &'tcx hir::Expr,
2654                                      expected: Ty<'tcx>) {
2655     check_expr_with_unifier(
2656         fcx, expr, ExpectHasType(expected), NoPreference,
2657         || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2658 }
2659
2660 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2661                                           expr: &'tcx hir::Expr,
2662                                           expected: Ty<'tcx>) {
2663     check_expr_with_unifier(
2664         fcx, expr, ExpectHasType(expected), NoPreference,
2665         || demand::coerce(fcx, expr.span, expected, expr));
2666 }
2667
2668 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2669                                   expected: Ty<'tcx>) {
2670     check_expr_with_unifier(
2671         fcx, expr, ExpectHasType(expected), NoPreference,
2672         || ())
2673 }
2674
2675 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2676                                          expr: &'tcx hir::Expr,
2677                                          expected: Expectation<'tcx>) {
2678     check_expr_with_unifier(
2679         fcx, expr, expected, NoPreference,
2680         || ())
2681 }
2682
2683 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2684                                                          expr: &'tcx hir::Expr,
2685                                                          expected: Expectation<'tcx>,
2686                                                          lvalue_pref: LvaluePreference)
2687 {
2688     check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2689 }
2690
2691 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr)  {
2692     check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2693 }
2694
2695 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2696                                         lvalue_pref: LvaluePreference)  {
2697     check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2698 }
2699
2700 // determine the `self` type, using fresh variables for all variables
2701 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2702 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2703 // variables.
2704 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2705                               span: Span, // (potential) receiver for this impl
2706                               did: DefId)
2707                               -> TypeAndSubsts<'tcx> {
2708     let tcx = fcx.tcx();
2709
2710     let ity = tcx.lookup_item_type(did);
2711     let (tps, rps, raw_ty) =
2712         (ity.generics.types.get_slice(subst::TypeSpace),
2713          ity.generics.regions.get_slice(subst::TypeSpace),
2714          ity.ty);
2715
2716     debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2717
2718     let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2719     let mut substs = subst::Substs::new(
2720         VecPerParamSpace::empty(),
2721         VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2722     fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2723     let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2724
2725     TypeAndSubsts { substs: substs, ty: substd_ty }
2726 }
2727
2728 /// Controls whether the arguments are tupled. This is used for the call
2729 /// operator.
2730 ///
2731 /// Tupling means that all call-side arguments are packed into a tuple and
2732 /// passed as a single parameter. For example, if tupling is enabled, this
2733 /// function:
2734 ///
2735 ///     fn f(x: (isize, isize))
2736 ///
2737 /// Can be called as:
2738 ///
2739 ///     f(1, 2);
2740 ///
2741 /// Instead of:
2742 ///
2743 ///     f((1, 2));
2744 #[derive(Clone, Eq, PartialEq)]
2745 enum TupleArgumentsFlag {
2746     DontTupleArguments,
2747     TupleArguments,
2748 }
2749
2750 /// Unifies the return type with the expected type early, for more coercions
2751 /// and forward type information on the argument expressions.
2752 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2753                                         call_span: Span,
2754                                         expected_ret: Expectation<'tcx>,
2755                                         formal_ret: ty::FnOutput<'tcx>,
2756                                         formal_args: &[Ty<'tcx>])
2757                                         -> Vec<Ty<'tcx>> {
2758     let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2759         if let ty::FnConverging(formal_ret_ty) = formal_ret {
2760             fcx.infcx().commit_regions_if_ok(|| {
2761                 // Attempt to apply a subtyping relationship between the formal
2762                 // return type (likely containing type variables if the function
2763                 // is polymorphic) and the expected return type.
2764                 // No argument expectations are produced if unification fails.
2765                 let origin = TypeOrigin::Misc(call_span);
2766                 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2767                 // FIXME(#15760) can't use try! here, FromError doesn't default
2768                 // to identity so the resulting type is not constrained.
2769                 if let Err(e) = ures {
2770                     return Err(e);
2771                 }
2772
2773                 // Record all the argument types, with the substitutions
2774                 // produced from the above subtyping unification.
2775                 Ok(formal_args.iter().map(|ty| {
2776                     fcx.infcx().resolve_type_vars_if_possible(ty)
2777                 }).collect())
2778             }).ok()
2779         } else {
2780             None
2781         }
2782     }).unwrap_or(vec![]);
2783     debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2784            formal_args, formal_ret,
2785            expected_args, expected_ret);
2786     expected_args
2787 }
2788
2789 /// Invariant:
2790 /// If an expression has any sub-expressions that result in a type error,
2791 /// inspecting that expression's type with `ty.references_error()` will return
2792 /// true. Likewise, if an expression is known to diverge, inspecting its
2793 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2794 /// strict, _|_ can appear in the type of an expression that does not,
2795 /// itself, diverge: for example, fn() -> _|_.)
2796 /// Note that inspecting a type's structure *directly* may expose the fact
2797 /// that there are actually multiple representations for `TyError`, so avoid
2798 /// that when err needs to be handled differently.
2799 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2800                                         expr: &'tcx hir::Expr,
2801                                         expected: Expectation<'tcx>,
2802                                         lvalue_pref: LvaluePreference,
2803                                         unifier: F) where
2804     F: FnOnce(),
2805 {
2806     debug!(">> typechecking: expr={:?} expected={:?}",
2807            expr, expected);
2808
2809     // Checks a method call.
2810     fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2811                                    expr: &'tcx hir::Expr,
2812                                    method_name: Spanned<ast::Name>,
2813                                    args: &'tcx [P<hir::Expr>],
2814                                    tps: &[P<hir::Ty>],
2815                                    expected: Expectation<'tcx>,
2816                                    lvalue_pref: LvaluePreference) {
2817         let rcvr = &args[0];
2818         check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2819
2820         // no need to check for bot/err -- callee does that
2821         let expr_t = structurally_resolved_type(fcx,
2822                                                 expr.span,
2823                                                 fcx.expr_ty(&rcvr));
2824
2825         let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2826         let fn_ty = match method::lookup(fcx,
2827                                          method_name.span,
2828                                          method_name.node,
2829                                          expr_t,
2830                                          tps,
2831                                          expr,
2832                                          rcvr) {
2833             Ok(method) => {
2834                 let method_ty = method.ty;
2835                 let method_call = MethodCall::expr(expr.id);
2836                 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2837                 method_ty
2838             }
2839             Err(error) => {
2840                 if method_name.node != special_idents::invalid.name {
2841                     method::report_error(fcx, method_name.span, expr_t,
2842                                          method_name.node, Some(rcvr), error);
2843                 }
2844                 fcx.write_error(expr.id);
2845                 fcx.tcx().types.err
2846             }
2847         };
2848
2849         // Call the generic checker.
2850         let ret_ty = check_method_argument_types(fcx,
2851                                                  method_name.span,
2852                                                  fn_ty,
2853                                                  expr,
2854                                                  &args[1..],
2855                                                  DontTupleArguments,
2856                                                  expected);
2857
2858         write_call(fcx, expr, ret_ty);
2859     }
2860
2861     // A generic function for checking the then and else in an if
2862     // or if-else.
2863     fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2864                                  cond_expr: &'tcx hir::Expr,
2865                                  then_blk: &'tcx hir::Block,
2866                                  opt_else_expr: Option<&'tcx hir::Expr>,
2867                                  id: ast::NodeId,
2868                                  sp: Span,
2869                                  expected: Expectation<'tcx>) {
2870         check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2871
2872         let expected = expected.adjust_for_branches(fcx);
2873         check_block_with_expected(fcx, then_blk, expected);
2874         let then_ty = fcx.node_ty(then_blk.id);
2875
2876         let branches_ty = match opt_else_expr {
2877             Some(ref else_expr) => {
2878                 check_expr_with_expectation(fcx, &else_expr, expected);
2879                 let else_ty = fcx.expr_ty(&else_expr);
2880                 infer::common_supertype(fcx.infcx(),
2881                                         TypeOrigin::IfExpression(sp),
2882                                         true,
2883                                         then_ty,
2884                                         else_ty)
2885             }
2886             None => {
2887                 infer::common_supertype(fcx.infcx(),
2888                                         TypeOrigin::IfExpressionWithNoElse(sp),
2889                                         false,
2890                                         then_ty,
2891                                         fcx.tcx().mk_nil())
2892             }
2893         };
2894
2895         let cond_ty = fcx.expr_ty(cond_expr);
2896         let if_ty = if cond_ty.references_error() {
2897             fcx.tcx().types.err
2898         } else {
2899             branches_ty
2900         };
2901
2902         fcx.write_ty(id, if_ty);
2903     }
2904
2905     // Check field access expressions
2906     fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2907                             expr: &'tcx hir::Expr,
2908                             lvalue_pref: LvaluePreference,
2909                             base: &'tcx hir::Expr,
2910                             field: &Spanned<ast::Name>) {
2911         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2912         let expr_t = structurally_resolved_type(fcx, expr.span,
2913                                                 fcx.expr_ty(base));
2914         // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2915         let (_, autoderefs, field_ty) = autoderef(fcx,
2916                                                   expr.span,
2917                                                   expr_t,
2918                                                   Some(base),
2919                                                   UnresolvedTypeAction::Error,
2920                                                   lvalue_pref,
2921                                                   |base_t, _| {
2922                 match base_t.sty {
2923                     ty::TyStruct(base_def, substs) => {
2924                         debug!("struct named {:?}",  base_t);
2925                         base_def.struct_variant()
2926                                 .find_field_named(field.node)
2927                                 .map(|f| fcx.field_ty(expr.span, f, substs))
2928                     }
2929                     _ => None
2930                 }
2931             });
2932         match field_ty {
2933             Some(field_ty) => {
2934                 fcx.write_ty(expr.id, field_ty);
2935                 fcx.write_autoderef_adjustment(base.id, autoderefs);
2936                 return;
2937             }
2938             None => {}
2939         }
2940
2941         if field.node == special_idents::invalid.name {
2942             fcx.write_error(expr.id);
2943             return;
2944         }
2945
2946         if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2947             fcx.type_error_struct(field.span,
2948                                   |actual| {
2949                                        format!("attempted to take value of method `{}` on type \
2950                                                `{}`", field.node, actual)
2951                                    },
2952                                    expr_t, None)
2953                 .fileline_help(field.span,
2954                                "maybe a `()` to call it is missing? \
2955                                If not, try an anonymous function")
2956                 .emit();
2957         } else {
2958             let mut err = fcx.type_error_struct(
2959                 expr.span,
2960                 |actual| {
2961                     format!("attempted access of field `{}` on \
2962                             type `{}`, but no field with that \
2963                             name was found",
2964                             field.node,
2965                             actual)
2966                 },
2967                 expr_t, None);
2968             if let ty::TyStruct(def, _) = expr_t.sty {
2969                 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2970             }
2971             err.emit();
2972         }
2973
2974         fcx.write_error(expr.id);
2975     }
2976
2977     // displays hints about the closest matches in field names
2978     fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2979                                  variant: ty::VariantDef<'tcx>,
2980                                  field: &Spanned<ast::Name>,
2981                                  skip : Vec<InternedString>) {
2982         let name = field.node.as_str();
2983         let names = variant.fields
2984                     .iter()
2985                     .filter_map(|ref field| {
2986                         // ignore already set fields and private fields from non-local crates
2987                         if skip.iter().any(|x| *x == field.name.as_str()) ||
2988                            (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2989                                None
2990                         } else {
2991                             Some(&field.name)
2992                         }
2993                     });
2994
2995         // only find fits with at least one matching letter
2996         if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2997             err.span_help(field.span,
2998                           &format!("did you mean `{}`?", name));
2999         }
3000     }
3001
3002     // Check tuple index expressions
3003     fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3004                                 expr: &'tcx hir::Expr,
3005                                 lvalue_pref: LvaluePreference,
3006                                 base: &'tcx hir::Expr,
3007                                 idx: codemap::Spanned<usize>) {
3008         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3009         let expr_t = structurally_resolved_type(fcx, expr.span,
3010                                                 fcx.expr_ty(base));
3011         let mut tuple_like = false;
3012         // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3013         let (_, autoderefs, field_ty) = autoderef(fcx,
3014                                                   expr.span,
3015                                                   expr_t,
3016                                                   Some(base),
3017                                                   UnresolvedTypeAction::Error,
3018                                                   lvalue_pref,
3019                                                   |base_t, _| {
3020                 match base_t.sty {
3021                     ty::TyStruct(base_def, substs) => {
3022                         tuple_like = base_def.struct_variant().is_tuple_struct();
3023                         if tuple_like {
3024                             debug!("tuple struct named {:?}",  base_t);
3025                             base_def.struct_variant()
3026                                     .fields
3027                                     .get(idx.node)
3028                                     .map(|f| fcx.field_ty(expr.span, f, substs))
3029                         } else {
3030                             None
3031                         }
3032                     }
3033                     ty::TyTuple(ref v) => {
3034                         tuple_like = true;
3035                         if idx.node < v.len() { Some(v[idx.node]) } else { None }
3036                     }
3037                     _ => None
3038                 }
3039             });
3040         match field_ty {
3041             Some(field_ty) => {
3042                 fcx.write_ty(expr.id, field_ty);
3043                 fcx.write_autoderef_adjustment(base.id, autoderefs);
3044                 return;
3045             }
3046             None => {}
3047         }
3048         fcx.type_error_message(
3049             expr.span,
3050             |actual| {
3051                 if tuple_like {
3052                     format!("attempted out-of-bounds tuple index `{}` on \
3053                                     type `{}`",
3054                                    idx.node,
3055                                    actual)
3056                 } else {
3057                     format!("attempted tuple index `{}` on type `{}`, but the \
3058                                      type was not a tuple or tuple struct",
3059                                     idx.node,
3060                                     actual)
3061                 }
3062             },
3063             expr_t, None);
3064
3065         fcx.write_error(expr.id);
3066     }
3067
3068     fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3069                                       ty: Ty<'tcx>,
3070                                       variant: ty::VariantDef<'tcx>,
3071                                       field: &hir::Field,
3072                                       skip_fields: &[hir::Field]) {
3073         let mut err = fcx.type_error_struct(
3074             field.name.span,
3075             |actual| if let ty::TyEnum(..) = ty.sty {
3076                 format!("struct variant `{}::{}` has no field named `{}`",
3077                         actual, variant.name.as_str(), field.name.node)
3078             } else {
3079                 format!("structure `{}` has no field named `{}`",
3080                         actual, field.name.node)
3081             },
3082             ty,
3083             None);
3084         // prevent all specified fields from being suggested
3085         let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3086         suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3087         err.emit();
3088     }
3089
3090     fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3091                                           adt_ty: Ty<'tcx>,
3092                                           span: Span,
3093                                           variant: ty::VariantDef<'tcx>,
3094                                           ast_fields: &'tcx [hir::Field],
3095                                           check_completeness: bool) {
3096         let tcx = fcx.ccx.tcx;
3097         let substs = match adt_ty.sty {
3098             ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3099             _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3100         };
3101
3102         let mut remaining_fields = FnvHashMap();
3103         for field in &variant.fields {
3104             remaining_fields.insert(field.name, field);
3105         }
3106
3107         let mut error_happened = false;
3108
3109         // Typecheck each field.
3110         for field in ast_fields {
3111             let expected_field_type;
3112
3113             if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3114                 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3115             } else {
3116                 error_happened = true;
3117                 expected_field_type = tcx.types.err;
3118                 if let Some(_) = variant.find_field_named(field.name.node) {
3119                     span_err!(fcx.tcx().sess, field.name.span, E0062,
3120                         "field `{}` specified more than once",
3121                         field.name.node);
3122                 } else {
3123                     report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3124                 }
3125             }
3126
3127             // Make sure to give a type to the field even if there's
3128             // an error, so we can continue typechecking
3129             check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3130         }
3131
3132             // Make sure the programmer specified all the fields.
3133         if check_completeness &&
3134             !error_happened &&
3135             !remaining_fields.is_empty()
3136         {
3137             span_err!(tcx.sess, span, E0063,
3138                       "missing field{} {} in initializer of `{}`",
3139                       if remaining_fields.len() == 1 {""} else {"s"},
3140                       remaining_fields.keys()
3141                                       .map(|n| format!("`{}`", n))
3142                                       .collect::<Vec<_>>()
3143                                       .join(", "),
3144                       adt_ty);
3145         }
3146
3147     }
3148
3149     fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3150                                              id: ast::NodeId,
3151                                              fields: &'tcx [hir::Field],
3152                                              base_expr: &'tcx Option<P<hir::Expr>>) {
3153         // Make sure to still write the types
3154         // otherwise we might ICE
3155         fcx.write_error(id);
3156         for field in fields {
3157             check_expr(fcx, &field.expr);
3158         }
3159         match *base_expr {
3160             Some(ref base) => check_expr(fcx, &base),
3161             None => {}
3162         }
3163     }
3164
3165     fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3166                                    expr: &hir::Expr,
3167                                    path: &hir::Path,
3168                                    fields: &'tcx [hir::Field],
3169                                    base_expr: &'tcx Option<P<hir::Expr>>)
3170     {
3171         let tcx = fcx.tcx();
3172
3173         // Find the relevant variant
3174         let def = lookup_full_def(tcx, path.span, expr.id);
3175         if def == Def::Err {
3176             check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3177             return;
3178         }
3179         let variant = match fcx.def_struct_variant(def, path.span) {
3180             Some((_, variant)) => variant,
3181             None => {
3182                 span_err!(fcx.tcx().sess, path.span, E0071,
3183                           "`{}` does not name a structure",
3184                           pprust::path_to_string(path));
3185                 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3186                 return;
3187             }
3188         };
3189
3190         let expr_ty = fcx.instantiate_type(def.def_id(), path);
3191         fcx.write_ty(expr.id, expr_ty);
3192
3193         check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3194                                  base_expr.is_none());
3195         if let &Some(ref base_expr) = base_expr {
3196             check_expr_has_type(fcx, base_expr, expr_ty);
3197             match expr_ty.sty {
3198                 ty::TyStruct(adt, substs) => {
3199                     fcx.inh.tables.borrow_mut().fru_field_types.insert(
3200                         expr.id,
3201                         adt.struct_variant().fields.iter().map(|f| {
3202                             fcx.normalize_associated_types_in(
3203                                 expr.span, &f.ty(tcx, substs)
3204                             )
3205                         }).collect()
3206                     );
3207                 }
3208                 _ => {
3209                     span_err!(tcx.sess, base_expr.span, E0436,
3210                               "functional record update syntax requires a struct");
3211                 }
3212             }
3213         }
3214     }
3215
3216     type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3217
3218     let tcx = fcx.ccx.tcx;
3219     let id = expr.id;
3220     match expr.node {
3221       hir::ExprBox(ref subexpr) => {
3222         let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3223             match ty.sty {
3224                 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3225                 _ => NoExpectation
3226             }
3227         });
3228         check_expr_with_expectation(fcx, subexpr, expected_inner);
3229         let referent_ty = fcx.expr_ty(&subexpr);
3230         fcx.write_ty(id, tcx.mk_box(referent_ty));
3231       }
3232
3233       hir::ExprLit(ref lit) => {
3234         let typ = check_lit(fcx, &lit, expected);
3235         fcx.write_ty(id, typ);
3236       }
3237       hir::ExprBinary(op, ref lhs, ref rhs) => {
3238         op::check_binop(fcx, expr, op, lhs, rhs);
3239       }
3240       hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3241         op::check_binop_assign(fcx, expr, op, lhs, rhs);
3242       }
3243       hir::ExprUnary(unop, ref oprnd) => {
3244         let expected_inner = match unop {
3245             hir::UnNot | hir::UnNeg => {
3246                 expected
3247             }
3248             hir::UnDeref => {
3249                 NoExpectation
3250             }
3251         };
3252         let lvalue_pref = match unop {
3253             hir::UnDeref => lvalue_pref,
3254             _ => NoPreference
3255         };
3256         check_expr_with_expectation_and_lvalue_pref(
3257             fcx, &oprnd, expected_inner, lvalue_pref);
3258         let mut oprnd_t = fcx.expr_ty(&oprnd);
3259
3260         if !oprnd_t.references_error() {
3261             match unop {
3262                 hir::UnDeref => {
3263                     oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3264                     oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3265                         Some(mt) => mt.ty,
3266                         None => match try_overloaded_deref(fcx, expr.span,
3267                                                            Some(MethodCall::expr(expr.id)),
3268                                                            Some(&oprnd), oprnd_t, lvalue_pref) {
3269                             Some(mt) => mt.ty,
3270                             None => {
3271                                 fcx.type_error_message(expr.span, |actual| {
3272                                     format!("type `{}` cannot be \
3273                                             dereferenced", actual)
3274                                 }, oprnd_t, None);
3275                                 tcx.types.err
3276                             }
3277                         }
3278                     };
3279                 }
3280                 hir::UnNot => {
3281                     oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3282                                                          oprnd_t);
3283                     if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3284                         oprnd_t = op::check_user_unop(fcx, "!", "not",
3285                                                       tcx.lang_items.not_trait(),
3286                                                       expr, &oprnd, oprnd_t, unop);
3287                     }
3288                 }
3289                 hir::UnNeg => {
3290                     oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3291                                                          oprnd_t);
3292                     if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3293                         oprnd_t = op::check_user_unop(fcx, "-", "neg",
3294                                                       tcx.lang_items.neg_trait(),
3295                                                       expr, &oprnd, oprnd_t, unop);
3296                     }
3297                 }
3298             }
3299         }
3300         fcx.write_ty(id, oprnd_t);
3301       }
3302       hir::ExprAddrOf(mutbl, ref oprnd) => {
3303         let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3304             match ty.sty {
3305                 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3306                     if fcx.tcx().expr_is_lval(&oprnd) {
3307                         // Lvalues may legitimately have unsized types.
3308                         // For example, dereferences of a fat pointer and
3309                         // the last field of a struct can be unsized.
3310                         ExpectHasType(mt.ty)
3311                     } else {
3312                         Expectation::rvalue_hint(tcx, mt.ty)
3313                     }
3314                 }
3315                 _ => NoExpectation
3316             }
3317         });
3318         let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3319         check_expr_with_expectation_and_lvalue_pref(fcx,
3320                                                     &oprnd,
3321                                                     hint,
3322                                                     lvalue_pref);
3323
3324         let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3325         let oprnd_t = if tm.ty.references_error() {
3326             tcx.types.err
3327         } else {
3328             // Note: at this point, we cannot say what the best lifetime
3329             // is to use for resulting pointer.  We want to use the
3330             // shortest lifetime possible so as to avoid spurious borrowck
3331             // errors.  Moreover, the longest lifetime will depend on the
3332             // precise details of the value whose address is being taken
3333             // (and how long it is valid), which we don't know yet until type
3334             // inference is complete.
3335             //
3336             // Therefore, here we simply generate a region variable.  The
3337             // region inferencer will then select the ultimate value.
3338             // Finally, borrowck is charged with guaranteeing that the
3339             // value whose address was taken can actually be made to live
3340             // as long as it needs to live.
3341             let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3342             tcx.mk_ref(tcx.mk_region(region), tm)
3343         };
3344         fcx.write_ty(id, oprnd_t);
3345       }
3346       hir::ExprPath(ref maybe_qself, ref path) => {
3347           let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3348               fcx.to_ty(&qself.ty)
3349           });
3350
3351           let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3352               d
3353           } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3354                 // Create some fake resolution that can't possibly be a type.
3355                 def::PathResolution {
3356                     base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3357                     depth: path.segments.len()
3358                 }
3359             } else {
3360               tcx.sess.span_bug(expr.span,
3361                                 &format!("unbound path {:?}", expr))
3362           };
3363
3364           if let Some((opt_ty, segments, def)) =
3365                   resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3366                                           expr.span, expr.id) {
3367               if def != Def::Err {
3368                   let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3369                                                                                 expr.span,
3370                                                                                 def);
3371                   instantiate_path(fcx,
3372                                    segments,
3373                                    scheme,
3374                                    &predicates,
3375                                    opt_ty,
3376                                    def,
3377                                    expr.span,
3378                                    id);
3379               } else {
3380                   fcx.write_ty(id, fcx.tcx().types.err);
3381               }
3382           }
3383
3384           // We always require that the type provided as the value for
3385           // a type parameter outlives the moment of instantiation.
3386           fcx.opt_node_ty_substs(expr.id, |item_substs| {
3387               fcx.add_wf_bounds(&item_substs.substs, expr);
3388           });
3389       }
3390       hir::ExprInlineAsm(ref ia) => {
3391           for &(_, ref input) in &ia.inputs {
3392               check_expr(fcx, &input);
3393           }
3394           for out in &ia.outputs {
3395               check_expr(fcx, &out.expr);
3396           }
3397           fcx.write_nil(id);
3398       }
3399       hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3400       hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3401       hir::ExprRet(ref expr_opt) => {
3402         match fcx.ret_ty {
3403             ty::FnConverging(result_type) => {
3404                 match *expr_opt {
3405                     None =>
3406                         if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3407                                                     result_type, fcx.tcx().mk_nil()) {
3408                             span_err!(tcx.sess, expr.span, E0069,
3409                                 "`return;` in a function whose return type is \
3410                                  not `()`");
3411                         },
3412                     Some(ref e) => {
3413                         check_expr_coercable_to_type(fcx, &e, result_type);
3414                     }
3415                 }
3416             }
3417             ty::FnDiverging => {
3418                 if let Some(ref e) = *expr_opt {
3419                     check_expr(fcx, &e);
3420                 }
3421                 span_err!(tcx.sess, expr.span, E0166,
3422                     "`return` in a function declared as diverging");
3423             }
3424         }
3425         fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3426       }
3427       hir::ExprAssign(ref lhs, ref rhs) => {
3428         check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3429
3430         let tcx = fcx.tcx();
3431         if !tcx.expr_is_lval(&lhs) {
3432             span_err!(tcx.sess, expr.span, E0070,
3433                 "invalid left-hand side expression");
3434         }
3435
3436         let lhs_ty = fcx.expr_ty(&lhs);
3437         check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3438         let rhs_ty = fcx.expr_ty(&rhs);
3439
3440         fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3441
3442         if lhs_ty.references_error() || rhs_ty.references_error() {
3443             fcx.write_error(id);
3444         } else {
3445             fcx.write_nil(id);
3446         }
3447       }
3448       hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3449         check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3450                         id, expr.span, expected);
3451       }
3452       hir::ExprWhile(ref cond, ref body, _) => {
3453         check_expr_has_type(fcx, &cond, tcx.types.bool);
3454         check_block_no_value(fcx, &body);
3455         let cond_ty = fcx.expr_ty(&cond);
3456         let body_ty = fcx.node_ty(body.id);
3457         if cond_ty.references_error() || body_ty.references_error() {
3458             fcx.write_error(id);
3459         }
3460         else {
3461             fcx.write_nil(id);
3462         }
3463       }
3464       hir::ExprLoop(ref body, _) => {
3465         check_block_no_value(fcx, &body);
3466         if !may_break(tcx, expr.id, &body) {
3467             fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3468         } else {
3469             fcx.write_nil(id);
3470         }
3471       }
3472       hir::ExprMatch(ref discrim, ref arms, match_src) => {
3473         _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3474       }
3475       hir::ExprClosure(capture, ref decl, ref body) => {
3476           closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3477       }
3478       hir::ExprBlock(ref b) => {
3479         check_block_with_expected(fcx, &b, expected);
3480         fcx.write_ty(id, fcx.node_ty(b.id));
3481       }
3482       hir::ExprCall(ref callee, ref args) => {
3483           callee::check_call(fcx, expr, &callee, &args[..], expected);
3484
3485           // we must check that return type of called functions is WF:
3486           let ret_ty = fcx.expr_ty(expr);
3487           fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3488       }
3489       hir::ExprMethodCall(name, ref tps, ref args) => {
3490           check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3491           let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3492           let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3493           if args_err {
3494               fcx.write_error(id);
3495           }
3496       }
3497       hir::ExprCast(ref e, ref t) => {
3498         if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3499             check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3500         }
3501
3502         // Find the type of `e`. Supply hints based on the type we are casting to,
3503         // if appropriate.
3504         let t_cast = fcx.to_ty(t);
3505         let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3506         check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3507         let t_expr = fcx.expr_ty(e);
3508         let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3509
3510         // Eagerly check for some obvious errors.
3511         if t_expr.references_error() || t_cast.references_error() {
3512             fcx.write_error(id);
3513         } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3514             report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3515         } else {
3516             // Write a type for the whole expression, assuming everything is going
3517             // to work out Ok.
3518             fcx.write_ty(id, t_cast);
3519
3520             // Defer other checks until we're done type checking.
3521             let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3522             let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3523             deferred_cast_checks.push(cast_check);
3524         }
3525       }
3526       hir::ExprType(ref e, ref t) => {
3527         let typ = fcx.to_ty(&t);
3528         check_expr_eq_type(fcx, &e, typ);
3529         fcx.write_ty(id, typ);
3530       }
3531       hir::ExprVec(ref args) => {
3532         let uty = expected.to_option(fcx).and_then(|uty| {
3533             match uty.sty {
3534                 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3535                 _ => None
3536             }
3537         });
3538
3539         let typ = match uty {
3540             Some(uty) => {
3541                 for e in args {
3542                     check_expr_coercable_to_type(fcx, &e, uty);
3543                 }
3544                 uty
3545             }
3546             None => {
3547                 let t: Ty = fcx.infcx().next_ty_var();
3548                 for e in args {
3549                     check_expr_has_type(fcx, &e, t);
3550                 }
3551                 t
3552             }
3553         };
3554         let typ = tcx.mk_array(typ, args.len());
3555         fcx.write_ty(id, typ);
3556       }
3557       hir::ExprRepeat(ref element, ref count_expr) => {
3558         check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3559         let count = fcx.tcx().eval_repeat_count(&count_expr);
3560
3561         let uty = match expected {
3562             ExpectHasType(uty) => {
3563                 match uty.sty {
3564                     ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3565                     _ => None
3566                 }
3567             }
3568             _ => None
3569         };
3570
3571         let (element_ty, t) = match uty {
3572             Some(uty) => {
3573                 check_expr_coercable_to_type(fcx, &element, uty);
3574                 (uty, uty)
3575             }
3576             None => {
3577                 let t: Ty = fcx.infcx().next_ty_var();
3578                 check_expr_has_type(fcx, &element, t);
3579                 (fcx.expr_ty(&element), t)
3580             }
3581         };
3582
3583         if count > 1 {
3584             // For [foo, ..n] where n > 1, `foo` must have
3585             // Copy type:
3586             fcx.require_type_meets(
3587                 t,
3588                 expr.span,
3589                 traits::RepeatVec,
3590                 ty::BoundCopy);
3591         }
3592
3593         if element_ty.references_error() {
3594             fcx.write_error(id);
3595         } else {
3596             let t = tcx.mk_array(t, count);
3597             fcx.write_ty(id, t);
3598         }
3599       }
3600       hir::ExprTup(ref elts) => {
3601         let flds = expected.only_has_type(fcx).and_then(|ty| {
3602             match ty.sty {
3603                 ty::TyTuple(ref flds) => Some(&flds[..]),
3604                 _ => None
3605             }
3606         });
3607         let mut err_field = false;
3608
3609         let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3610             let t = match flds {
3611                 Some(ref fs) if i < fs.len() => {
3612                     let ety = fs[i];
3613                     check_expr_coercable_to_type(fcx, &e, ety);
3614                     ety
3615                 }
3616                 _ => {
3617                     check_expr_with_expectation(fcx, &e, NoExpectation);
3618                     fcx.expr_ty(&e)
3619                 }
3620             };
3621             err_field = err_field || t.references_error();
3622             t
3623         }).collect();
3624         if err_field {
3625             fcx.write_error(id);
3626         } else {
3627             let typ = tcx.mk_tup(elt_ts);
3628             fcx.write_ty(id, typ);
3629         }
3630       }
3631       hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3632         check_expr_struct(fcx, expr, path, fields, base_expr);
3633
3634         fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3635       }
3636       hir::ExprField(ref base, ref field) => {
3637         check_field(fcx, expr, lvalue_pref, &base, field);
3638       }
3639       hir::ExprTupField(ref base, idx) => {
3640         check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3641       }
3642       hir::ExprIndex(ref base, ref idx) => {
3643           check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3644           check_expr(fcx, &idx);
3645
3646           let base_t = fcx.expr_ty(&base);
3647           let idx_t = fcx.expr_ty(&idx);
3648
3649           if base_t.references_error() {
3650               fcx.write_ty(id, base_t);
3651           } else if idx_t.references_error() {
3652               fcx.write_ty(id, idx_t);
3653           } else {
3654               let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3655               match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3656                   Some((index_ty, element_ty)) => {
3657                       let idx_expr_ty = fcx.expr_ty(idx);
3658                       demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3659                       fcx.write_ty(id, element_ty);
3660                   }
3661                   None => {
3662                       check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3663                       fcx.type_error_message(
3664                           expr.span,
3665                           |actual| {
3666                               format!("cannot index a value of type `{}`",
3667                                       actual)
3668                           },
3669                           base_t,
3670                           None);
3671                       fcx.write_ty(id, fcx.tcx().types.err);
3672                   }
3673               }
3674           }
3675        }
3676     }
3677
3678     debug!("type of expr({}) {} is...", expr.id,
3679            pprust::expr_to_string(expr));
3680     debug!("... {:?}, expected is {:?}",
3681            fcx.expr_ty(expr),
3682            expected);
3683
3684     unifier();
3685 }
3686
3687 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3688                                              path_res: def::PathResolution,
3689                                              opt_self_ty: Option<Ty<'tcx>>,
3690                                              path: &'a hir::Path,
3691                                              span: Span,
3692                                              node_id: ast::NodeId)
3693                                              -> Option<(Option<Ty<'tcx>>,
3694                                                         &'a [hir::PathSegment],
3695                                                         Def)>
3696 {
3697
3698     // If fully resolved already, we don't have to do anything.
3699     if path_res.depth == 0 {
3700         Some((opt_self_ty, &path.segments, path_res.base_def))
3701     } else {
3702         let mut def = path_res.base_def;
3703         let ty_segments = path.segments.split_last().unwrap().1;
3704         let base_ty_end = path.segments.len() - path_res.depth;
3705         let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3706                                                      PathParamMode::Optional,
3707                                                      &mut def,
3708                                                      opt_self_ty,
3709                                                      &ty_segments[..base_ty_end],
3710                                                      &ty_segments[base_ty_end..]);
3711         let item_segment = path.segments.last().unwrap();
3712         let item_name = item_segment.identifier.name;
3713         match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3714             Ok(def) => {
3715                 // Write back the new resolution.
3716                 fcx.ccx.tcx.def_map.borrow_mut()
3717                        .insert(node_id, def::PathResolution {
3718                    base_def: def,
3719                    depth: 0
3720                 });
3721                 Some((Some(ty), slice::ref_slice(item_segment), def))
3722             }
3723             Err(error) => {
3724                 if item_name != special_idents::invalid.name {
3725                     method::report_error(fcx, span, ty, item_name, None, error);
3726                 }
3727                 fcx.write_error(node_id);
3728                 None
3729             }
3730         }
3731     }
3732 }
3733
3734 impl<'tcx> Expectation<'tcx> {
3735     /// Provide an expectation for an rvalue expression given an *optional*
3736     /// hint, which is not required for type safety (the resulting type might
3737     /// be checked higher up, as is the case with `&expr` and `box expr`), but
3738     /// is useful in determining the concrete type.
3739     ///
3740     /// The primary use case is where the expected type is a fat pointer,
3741     /// like `&[isize]`. For example, consider the following statement:
3742     ///
3743     ///    let x: &[isize] = &[1, 2, 3];
3744     ///
3745     /// In this case, the expected type for the `&[1, 2, 3]` expression is
3746     /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3747     /// expectation `ExpectHasType([isize])`, that would be too strong --
3748     /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3749     /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3750     /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3751     /// which still is useful, because it informs integer literals and the like.
3752     /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3753     /// for examples of where this comes up,.
3754     fn rvalue_hint(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3755         match tcx.struct_tail(ty).sty {
3756             ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3757                 ExpectRvalueLikeUnsized(ty)
3758             }
3759             _ => ExpectHasType(ty)
3760         }
3761     }
3762
3763     // Resolves `expected` by a single level if it is a variable. If
3764     // there is no expected type or resolution is not possible (e.g.,
3765     // no constraints yet present), just returns `None`.
3766     fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3767         match self {
3768             NoExpectation => {
3769                 NoExpectation
3770             }
3771             ExpectCastableToType(t) => {
3772                 ExpectCastableToType(
3773                     fcx.infcx().resolve_type_vars_if_possible(&t))
3774             }
3775             ExpectHasType(t) => {
3776                 ExpectHasType(
3777                     fcx.infcx().resolve_type_vars_if_possible(&t))
3778             }
3779             ExpectRvalueLikeUnsized(t) => {
3780                 ExpectRvalueLikeUnsized(
3781                     fcx.infcx().resolve_type_vars_if_possible(&t))
3782             }
3783         }
3784     }
3785
3786     fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3787         match self.resolve(fcx) {
3788             NoExpectation => None,
3789             ExpectCastableToType(ty) |
3790             ExpectHasType(ty) |
3791             ExpectRvalueLikeUnsized(ty) => Some(ty),
3792         }
3793     }
3794
3795     fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3796         match self.resolve(fcx) {
3797             ExpectHasType(ty) => Some(ty),
3798             _ => None
3799         }
3800     }
3801 }
3802
3803 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3804                                        local: &'tcx hir::Local,
3805                                        init: &'tcx hir::Expr)
3806 {
3807     let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3808
3809     let local_ty = fcx.local_ty(init.span, local.id);
3810     if let Some(m) = ref_bindings {
3811         // Somewhat subtle: if we have a `ref` binding in the pattern,
3812         // we want to avoid introducing coercions for the RHS. This is
3813         // both because it helps preserve sanity and, in the case of
3814         // ref mut, for soundness (issue #23116). In particular, in
3815         // the latter case, we need to be clear that the type of the
3816         // referent for the reference that results is *equal to* the
3817         // type of the lvalue it is referencing, and not some
3818         // supertype thereof.
3819         check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3820         let init_ty = fcx.expr_ty(init);
3821         demand::eqtype(fcx, init.span, init_ty, local_ty);
3822     } else {
3823         check_expr_coercable_to_type(fcx, init, local_ty)
3824     };
3825 }
3826
3827 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local)  {
3828     let tcx = fcx.ccx.tcx;
3829
3830     let t = fcx.local_ty(local.span, local.id);
3831     fcx.write_ty(local.id, t);
3832
3833     if let Some(ref init) = local.init {
3834         check_decl_initializer(fcx, local, &init);
3835         let init_ty = fcx.expr_ty(&init);
3836         if init_ty.references_error() {
3837             fcx.write_ty(local.id, init_ty);
3838         }
3839     }
3840
3841     let pcx = pat_ctxt {
3842         fcx: fcx,
3843         map: pat_id_map(&tcx.def_map, &local.pat),
3844     };
3845     _match::check_pat(&pcx, &local.pat, t);
3846     let pat_ty = fcx.node_ty(local.pat.id);
3847     if pat_ty.references_error() {
3848         fcx.write_ty(local.id, pat_ty);
3849     }
3850 }
3851
3852 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt)  {
3853     let node_id;
3854     let mut saw_bot = false;
3855     let mut saw_err = false;
3856     match stmt.node {
3857       hir::StmtDecl(ref decl, id) => {
3858         node_id = id;
3859         match decl.node {
3860           hir::DeclLocal(ref l) => {
3861               check_decl_local(fcx, &l);
3862               let l_t = fcx.node_ty(l.id);
3863               saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3864               saw_err = saw_err || l_t.references_error();
3865           }
3866           hir::DeclItem(_) => {/* ignore for now */ }
3867         }
3868       }
3869       hir::StmtExpr(ref expr, id) => {
3870         node_id = id;
3871         // Check with expected type of ()
3872         check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3873         let expr_ty = fcx.expr_ty(&expr);
3874         saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3875         saw_err = saw_err || expr_ty.references_error();
3876       }
3877       hir::StmtSemi(ref expr, id) => {
3878         node_id = id;
3879         check_expr(fcx, &expr);
3880         let expr_ty = fcx.expr_ty(&expr);
3881         saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3882         saw_err |= expr_ty.references_error();
3883       }
3884     }
3885     if saw_bot {
3886         fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3887     }
3888     else if saw_err {
3889         fcx.write_error(node_id);
3890     }
3891     else {
3892         fcx.write_nil(node_id)
3893     }
3894 }
3895
3896 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block)  {
3897     check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3898     let blkty = fcx.node_ty(blk.id);
3899     if blkty.references_error() {
3900         fcx.write_error(blk.id);
3901     } else {
3902         let nilty = fcx.tcx().mk_nil();
3903         demand::suptype(fcx, blk.span, nilty, blkty);
3904     }
3905 }
3906
3907 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3908                                        blk: &'tcx hir::Block,
3909                                        expected: Expectation<'tcx>) {
3910     let prev = {
3911         let mut fcx_ps = fcx.ps.borrow_mut();
3912         let unsafety_state = fcx_ps.recurse(blk);
3913         replace(&mut *fcx_ps, unsafety_state)
3914     };
3915
3916     let mut warned = false;
3917     let mut any_diverges = false;
3918     let mut any_err = false;
3919     for s in &blk.stmts {
3920         check_stmt(fcx, s);
3921         let s_id = ::rustc_front::util::stmt_id(s);
3922         let s_ty = fcx.node_ty(s_id);
3923         if any_diverges && !warned && match s.node {
3924             hir::StmtDecl(ref decl, _) => {
3925                 match decl.node {
3926                     hir::DeclLocal(_) => true,
3927                     _ => false,
3928                 }
3929             }
3930             hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3931         } {
3932             fcx.ccx
3933                 .tcx
3934                 .sess
3935                 .add_lint(lint::builtin::UNREACHABLE_CODE,
3936                           s_id,
3937                           s.span,
3938                           "unreachable statement".to_string());
3939             warned = true;
3940         }
3941         any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3942         any_err = any_err || s_ty.references_error();
3943     }
3944     match blk.expr {
3945         None => if any_err {
3946             fcx.write_error(blk.id);
3947         } else if any_diverges {
3948             fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3949         } else {
3950             fcx.write_nil(blk.id);
3951         },
3952         Some(ref e) => {
3953             if any_diverges && !warned {
3954                 fcx.ccx
3955                     .tcx
3956                     .sess
3957                     .add_lint(lint::builtin::UNREACHABLE_CODE,
3958                               e.id,
3959                               e.span,
3960                               "unreachable expression".to_string());
3961             }
3962             let ety = match expected {
3963                 ExpectHasType(ety) => {
3964                     check_expr_coercable_to_type(fcx, &e, ety);
3965                     ety
3966                 }
3967                 _ => {
3968                     check_expr_with_expectation(fcx, &e, expected);
3969                     fcx.expr_ty(&e)
3970                 }
3971             };
3972
3973             if any_err {
3974                 fcx.write_error(blk.id);
3975             } else if any_diverges {
3976                 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3977             } else {
3978                 fcx.write_ty(blk.id, ety);
3979             }
3980         }
3981     };
3982
3983     *fcx.ps.borrow_mut() = prev;
3984 }
3985
3986 /// Checks a constant appearing in a type. At the moment this is just the
3987 /// length expression in a fixed-length vector, but someday it might be
3988 /// extended to type-level numeric literals.
3989 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3990                                 expr: &'tcx hir::Expr,
3991                                 expected_type: Ty<'tcx>) {
3992     let tables = RefCell::new(ty::Tables::empty());
3993     let inh = static_inherited_fields(ccx, &tables);
3994     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3995     check_const_with_ty(&fcx, expr.span, expr, expected_type);
3996 }
3997
3998 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3999                         sp: Span,
4000                         e: &'tcx hir::Expr,
4001                         id: ast::NodeId) {
4002     let tables = RefCell::new(ty::Tables::empty());
4003     let inh = static_inherited_fields(ccx, &tables);
4004     let rty = ccx.tcx.node_id_to_type(id);
4005     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4006     let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4007     check_const_with_ty(&fcx, sp, e, declty);
4008 }
4009
4010 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4011                                  _: Span,
4012                                  e: &'tcx hir::Expr,
4013                                  declty: Ty<'tcx>) {
4014     // Gather locals in statics (because of block expressions).
4015     // This is technically unnecessary because locals in static items are forbidden,
4016     // but prevents type checking from blowing up before const checking can properly
4017     // emit an error.
4018     GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4019
4020     check_expr_with_hint(fcx, e, declty);
4021     demand::coerce(fcx, e.span, declty, e);
4022
4023     fcx.select_all_obligations_and_apply_defaults();
4024     upvar::closure_analyze_const(&fcx, e);
4025     fcx.select_obligations_where_possible();
4026     fcx.check_casts();
4027     fcx.select_all_obligations_or_error();
4028
4029     regionck::regionck_expr(fcx, e);
4030     writeback::resolve_type_vars_in_expr(fcx, e);
4031 }
4032
4033 /// Checks whether a type can be represented in memory. In particular, it
4034 /// identifies types that contain themselves without indirection through a
4035 /// pointer, which would mean their size is unbounded.
4036 pub fn check_representable(tcx: &TyCtxt,
4037                            sp: Span,
4038                            item_id: ast::NodeId,
4039                            _designation: &str) -> bool {
4040     let rty = tcx.node_id_to_type(item_id);
4041
4042     // Check that it is possible to represent this type. This call identifies
4043     // (1) types that contain themselves and (2) types that contain a different
4044     // recursive type. It is only necessary to throw an error on those that
4045     // contain themselves. For case 2, there must be an inner type that will be
4046     // caught by case 1.
4047     match rty.is_representable(tcx, sp) {
4048         Representability::SelfRecursive => {
4049             let item_def_id = tcx.map.local_def_id(item_id);
4050             traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4051             return false
4052         }
4053         Representability::Representable | Representability::ContainsRecursive => (),
4054     }
4055     return true
4056 }
4057
4058 pub fn check_simd(tcx: &TyCtxt, sp: Span, id: ast::NodeId) {
4059     let t = tcx.node_id_to_type(id);
4060     match t.sty {
4061         ty::TyStruct(def, substs) => {
4062             let fields = &def.struct_variant().fields;
4063             if fields.is_empty() {
4064                 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4065                 return;
4066             }
4067             let e = fields[0].ty(tcx, substs);
4068             if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4069                 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4070                 return;
4071             }
4072             match e.sty {
4073                 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4074                 _ if e.is_machine()  => { /* struct(u8, u8, u8, u8) is ok */ }
4075                 _ => {
4076                     span_err!(tcx.sess, sp, E0077,
4077                               "SIMD vector element type should be machine type");
4078                     return;
4079                 }
4080             }
4081         }
4082         _ => ()
4083     }
4084 }
4085
4086 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4087                                     sp: Span,
4088                                     vs: &'tcx [hir::Variant],
4089                                     id: ast::NodeId) {
4090     // disr_in_range should be removed once we have forced type hints for consts
4091     fn disr_in_range(ccx: &CrateCtxt,
4092                      ty: attr::IntType,
4093                      disr: ty::Disr) -> bool {
4094         fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4095             match ty {
4096                 ast::UintTy::U8 => disr as u8 as Disr == disr,
4097                 ast::UintTy::U16 => disr as u16 as Disr == disr,
4098                 ast::UintTy::U32 => disr as u32 as Disr == disr,
4099                 ast::UintTy::U64 => disr as u64 as Disr == disr,
4100                 ast::UintTy::Us => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4101             }
4102         }
4103         fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4104             match ty {
4105                 ast::IntTy::I8 => disr as i8 as Disr == disr,
4106                 ast::IntTy::I16 => disr as i16 as Disr == disr,
4107                 ast::IntTy::I32 => disr as i32 as Disr == disr,
4108                 ast::IntTy::I64 => disr as i64 as Disr == disr,
4109                 ast::IntTy::Is => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4110             }
4111         }
4112         match ty {
4113             attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4114             attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4115         }
4116     }
4117
4118     fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4119                           vs: &'tcx [hir::Variant],
4120                           id: ast::NodeId,
4121                           hint: attr::ReprAttr) {
4122         #![allow(trivial_numeric_casts)]
4123
4124         let rty = ccx.tcx.node_id_to_type(id);
4125         let mut disr_vals: Vec<ty::Disr> = Vec::new();
4126
4127         let tables = RefCell::new(ty::Tables::empty());
4128         let inh = static_inherited_fields(ccx, &tables);
4129         let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4130
4131         let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4132         for v in vs {
4133             if let Some(ref e) = v.node.disr_expr {
4134                 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4135             }
4136         }
4137
4138         let def_id = ccx.tcx.map.local_def_id(id);
4139
4140         let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4141         for (v, variant) in vs.iter().zip(variants.iter()) {
4142             let current_disr_val = variant.disr_val;
4143
4144             // Check for duplicate discriminant values
4145             match disr_vals.iter().position(|&x| x == current_disr_val) {
4146                 Some(i) => {
4147                     let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4148                         "discriminant value `{}` already exists", disr_vals[i]);
4149                     let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4150                     span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4151                         "conflicting discriminant here");
4152                     err.emit();
4153                 }
4154                 None => {}
4155             }
4156             // Check for unrepresentable discriminant values
4157             match hint {
4158                 attr::ReprAny | attr::ReprExtern => {
4159                     disr_vals.push(current_disr_val);
4160                 }
4161                 attr::ReprInt(sp, ity) => {
4162                     if !disr_in_range(ccx, ity, current_disr_val) {
4163                         let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4164                             "discriminant value outside specified type");
4165                         span_note!(&mut err, sp,
4166                             "discriminant type specified here");
4167                         err.emit();
4168                     }
4169                 }
4170                 // Error reported elsewhere.
4171                 attr::ReprSimd | attr::ReprPacked => {}
4172             }
4173         }
4174     }
4175
4176     let def_id = ccx.tcx.map.local_def_id(id);
4177     let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4178
4179     if hint != attr::ReprAny && vs.is_empty() {
4180         span_err!(ccx.tcx.sess, sp, E0084,
4181             "unsupported representation for zero-variant enum");
4182     }
4183
4184     do_check(ccx, vs, id, hint);
4185
4186     check_representable(ccx.tcx, sp, id, "enum");
4187 }
4188
4189 // Returns the type parameter count and the type for the given definition.
4190 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4191                                                 sp: Span,
4192                                                 defn: Def)
4193                                                 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4194     match defn {
4195         Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4196             let typ = fcx.local_ty(sp, nid);
4197             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4198              ty::GenericPredicates::empty())
4199         }
4200         Def::Fn(id) | Def::Method(id) |
4201         Def::Static(id, _) | Def::Variant(_, id) |
4202         Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4203             (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4204         }
4205         Def::Trait(_) |
4206         Def::Enum(..) |
4207         Def::TyAlias(..) |
4208         Def::AssociatedTy(..) |
4209         Def::PrimTy(_) |
4210         Def::TyParam(..) |
4211         Def::Mod(..) |
4212         Def::ForeignMod(..) |
4213         Def::Label(..) |
4214         Def::SelfTy(..) |
4215         Def::Err => {
4216             fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4217         }
4218     }
4219 }
4220
4221 // Instantiates the given path, which must refer to an item with the given
4222 // number of type parameters and type.
4223 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4224                                   segments: &[hir::PathSegment],
4225                                   type_scheme: TypeScheme<'tcx>,
4226                                   type_predicates: &ty::GenericPredicates<'tcx>,
4227                                   opt_self_ty: Option<Ty<'tcx>>,
4228                                   def: Def,
4229                                   span: Span,
4230                                   node_id: ast::NodeId) {
4231     debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4232            segments,
4233            def,
4234            node_id,
4235            type_scheme);
4236
4237     // We need to extract the type parameters supplied by the user in
4238     // the path `path`. Due to the current setup, this is a bit of a
4239     // tricky-process; the problem is that resolve only tells us the
4240     // end-point of the path resolution, and not the intermediate steps.
4241     // Luckily, we can (at least for now) deduce the intermediate steps
4242     // just from the end-point.
4243     //
4244     // There are basically four cases to consider:
4245     //
4246     // 1. Reference to a *type*, such as a struct or enum:
4247     //
4248     //        mod a { struct Foo<T> { ... } }
4249     //
4250     //    Because we don't allow types to be declared within one
4251     //    another, a path that leads to a type will always look like
4252     //    `a::b::Foo<T>` where `a` and `b` are modules. This implies
4253     //    that only the final segment can have type parameters, and
4254     //    they are located in the TypeSpace.
4255     //
4256     //    *Note:* Generally speaking, references to types don't
4257     //    actually pass through this function, but rather the
4258     //    `ast_ty_to_ty` function in `astconv`. However, in the case
4259     //    of struct patterns (and maybe literals) we do invoke
4260     //    `instantiate_path` to get the general type of an instance of
4261     //    a struct. (In these cases, there are actually no type
4262     //    parameters permitted at present, but perhaps we will allow
4263     //    them in the future.)
4264     //
4265     // 1b. Reference to an enum variant or tuple-like struct:
4266     //
4267     //        struct foo<T>(...)
4268     //        enum E<T> { foo(...) }
4269     //
4270     //    In these cases, the parameters are declared in the type
4271     //    space.
4272     //
4273     // 2. Reference to a *fn item*:
4274     //
4275     //        fn foo<T>() { }
4276     //
4277     //    In this case, the path will again always have the form
4278     //    `a::b::foo::<T>` where only the final segment should have
4279     //    type parameters. However, in this case, those parameters are
4280     //    declared on a value, and hence are in the `FnSpace`.
4281     //
4282     // 3. Reference to a *method*:
4283     //
4284     //        impl<A> SomeStruct<A> {
4285     //            fn foo<B>(...)
4286     //        }
4287     //
4288     //    Here we can have a path like
4289     //    `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4290     //    may appear in two places. The penultimate segment,
4291     //    `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4292     //    final segment, `foo::<B>` contains parameters in fn space.
4293     //
4294     // 4. Reference to an *associated const*:
4295     //
4296     // impl<A> AnotherStruct<A> {
4297     // const FOO: B = BAR;
4298     // }
4299     //
4300     // The path in this case will look like
4301     // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4302     // only will have parameters in TypeSpace.
4303     //
4304     // The first step then is to categorize the segments appropriately.
4305
4306     assert!(!segments.is_empty());
4307
4308     let mut ufcs_associated = None;
4309     let mut segment_spaces: Vec<_>;
4310     match def {
4311         // Case 1 and 1b. Reference to a *type* or *enum variant*.
4312         Def::SelfTy(..) |
4313         Def::Struct(..) |
4314         Def::Variant(..) |
4315         Def::Enum(..) |
4316         Def::TyAlias(..) |
4317         Def::AssociatedTy(..) |
4318         Def::Trait(..) |
4319         Def::PrimTy(..) |
4320         Def::TyParam(..) => {
4321             // Everything but the final segment should have no
4322             // parameters at all.
4323             segment_spaces = vec![None; segments.len() - 1];
4324             segment_spaces.push(Some(subst::TypeSpace));
4325         }
4326
4327         // Case 2. Reference to a top-level value.
4328         Def::Fn(..) |
4329         Def::Const(..) |
4330         Def::Static(..) => {
4331             segment_spaces = vec![None; segments.len() - 1];
4332             segment_spaces.push(Some(subst::FnSpace));
4333         }
4334
4335         // Case 3. Reference to a method.
4336         Def::Method(def_id) => {
4337             let container = fcx.tcx().impl_or_trait_item(def_id).container();
4338             match container {
4339                 ty::TraitContainer(trait_did) => {
4340                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4341                 }
4342                 ty::ImplContainer(_) => {}
4343             }
4344
4345             if segments.len() >= 2 {
4346                 segment_spaces = vec![None; segments.len() - 2];
4347                 segment_spaces.push(Some(subst::TypeSpace));
4348                 segment_spaces.push(Some(subst::FnSpace));
4349             } else {
4350                 // `<T>::method` will end up here, and so can `T::method`.
4351                 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4352                 segment_spaces = vec![Some(subst::FnSpace)];
4353                 ufcs_associated = Some((container, self_ty));
4354             }
4355         }
4356
4357         Def::AssociatedConst(def_id) => {
4358             let container = fcx.tcx().impl_or_trait_item(def_id).container();
4359             match container {
4360                 ty::TraitContainer(trait_did) => {
4361                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4362                 }
4363                 ty::ImplContainer(_) => {}
4364             }
4365
4366             if segments.len() >= 2 {
4367                 segment_spaces = vec![None; segments.len() - 2];
4368                 segment_spaces.push(Some(subst::TypeSpace));
4369                 segment_spaces.push(None);
4370             } else {
4371                 // `<T>::CONST` will end up here, and so can `T::CONST`.
4372                 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4373                 segment_spaces = vec![None];
4374                 ufcs_associated = Some((container, self_ty));
4375             }
4376         }
4377
4378         // Other cases. Various nonsense that really shouldn't show up
4379         // here. If they do, an error will have been reported
4380         // elsewhere. (I hope)
4381         Def::Mod(..) |
4382         Def::ForeignMod(..) |
4383         Def::Local(..) |
4384         Def::Label(..) |
4385         Def::Upvar(..) |
4386         Def::Err => {
4387             segment_spaces = vec![None; segments.len()];
4388         }
4389     }
4390     assert_eq!(segment_spaces.len(), segments.len());
4391
4392     // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4393     // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4394     // type parameters are not mandatory.
4395     let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4396
4397     debug!("segment_spaces={:?}", segment_spaces);
4398
4399     // Next, examine the definition, and determine how many type
4400     // parameters we expect from each space.
4401     let type_defs = &type_scheme.generics.types;
4402     let region_defs = &type_scheme.generics.regions;
4403
4404     // Now that we have categorized what space the parameters for each
4405     // segment belong to, let's sort out the parameters that the user
4406     // provided (if any) into their appropriate spaces. We'll also report
4407     // errors if type parameters are provided in an inappropriate place.
4408     let mut substs = Substs::empty();
4409     for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4410         match *opt_space {
4411             None => {
4412                 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4413             }
4414
4415             Some(space) => {
4416                 push_explicit_parameters_from_segment_to_substs(fcx,
4417                                                                 space,
4418                                                                 span,
4419                                                                 type_defs,
4420                                                                 region_defs,
4421                                                                 segment,
4422                                                                 &mut substs);
4423             }
4424         }
4425     }
4426     if let Some(self_ty) = opt_self_ty {
4427         if type_defs.len(subst::SelfSpace) == 1 {
4428             substs.types.push(subst::SelfSpace, self_ty);
4429         }
4430     }
4431
4432     // Now we have to compare the types that the user *actually*
4433     // provided against the types that were *expected*. If the user
4434     // did not provide any types, then we want to substitute inference
4435     // variables. If the user provided some types, we may still need
4436     // to add defaults. If the user provided *too many* types, that's
4437     // a problem.
4438     for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4439         adjust_type_parameters(fcx, span, space, type_defs,
4440                                require_type_space, &mut substs);
4441         assert_eq!(substs.types.len(space), type_defs.len(space));
4442
4443         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4444         assert_eq!(substs.regions().len(space), region_defs.len(space));
4445     }
4446
4447     // The things we are substituting into the type should not contain
4448     // escaping late-bound regions, and nor should the base type scheme.
4449     assert!(!substs.has_regions_escaping_depth(0));
4450     assert!(!type_scheme.has_escaping_regions());
4451
4452     // Add all the obligations that are required, substituting and
4453     // normalized appropriately.
4454     let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4455     fcx.add_obligations_for_parameters(
4456         traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4457         &bounds);
4458
4459     // Substitute the values for the type parameters into the type of
4460     // the referenced item.
4461     let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4462
4463
4464     if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4465         // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4466         // is inherent, there is no `Self` parameter, instead, the impl needs
4467         // type parameters, which we can infer by unifying the provided `Self`
4468         // with the substituted impl type.
4469         let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4470         assert_eq!(substs.types.len(subst::TypeSpace),
4471                    impl_scheme.generics.types.len(subst::TypeSpace));
4472         assert_eq!(substs.regions().len(subst::TypeSpace),
4473                    impl_scheme.generics.regions.len(subst::TypeSpace));
4474
4475         let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4476         if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4477             fcx.tcx().sess.span_bug(span,
4478             &format!(
4479                 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4480                 self_ty,
4481                 impl_ty));
4482         }
4483     }
4484
4485     debug!("instantiate_path: type of {:?} is {:?}",
4486            node_id,
4487            ty_substituted);
4488     fcx.write_ty(node_id, ty_substituted);
4489     fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4490     return;
4491
4492     /// Finds the parameters that the user provided and adds them to `substs`. If too many
4493     /// parameters are provided, then reports an error and clears the output vector.
4494     ///
4495     /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4496     /// use inference variables. This seems less likely to lead to derived errors.
4497     ///
4498     /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4499     /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4500     /// here because we can easily use the precise span of the N+1'th parameter.
4501     fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4502         fcx: &FnCtxt<'a, 'tcx>,
4503         space: subst::ParamSpace,
4504         span: Span,
4505         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4506         region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4507         segment: &hir::PathSegment,
4508         substs: &mut Substs<'tcx>)
4509     {
4510         match segment.parameters {
4511             hir::AngleBracketedParameters(ref data) => {
4512                 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4513                     fcx, space, type_defs, region_defs, data, substs);
4514             }
4515
4516             hir::ParenthesizedParameters(ref data) => {
4517                 span_err!(fcx.tcx().sess, span, E0238,
4518                     "parenthesized parameters may only be used with a trait");
4519                 push_explicit_parenthesized_parameters_from_segment_to_substs(
4520                     fcx, space, span, type_defs, data, substs);
4521             }
4522         }
4523     }
4524
4525     fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4526         fcx: &FnCtxt<'a, 'tcx>,
4527         space: subst::ParamSpace,
4528         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4529         region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4530         data: &hir::AngleBracketedParameterData,
4531         substs: &mut Substs<'tcx>)
4532     {
4533         {
4534             let type_count = type_defs.len(space);
4535             assert_eq!(substs.types.len(space), 0);
4536             for (i, typ) in data.types.iter().enumerate() {
4537                 let t = fcx.to_ty(&typ);
4538                 if i < type_count {
4539                     substs.types.push(space, t);
4540                 } else if i == type_count {
4541                     span_err!(fcx.tcx().sess, typ.span, E0087,
4542                         "too many type parameters provided: \
4543                          expected at most {} parameter{}, \
4544                          found {} parameter{}",
4545                          type_count,
4546                          if type_count == 1 {""} else {"s"},
4547                          data.types.len(),
4548                          if data.types.len() == 1 {""} else {"s"});
4549                     substs.types.truncate(space, 0);
4550                     break;
4551                 }
4552             }
4553         }
4554
4555         if !data.bindings.is_empty() {
4556             span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4557                       "unexpected binding of associated item in expression path \
4558                        (only allowed in type paths)");
4559         }
4560
4561         {
4562             let region_count = region_defs.len(space);
4563             assert_eq!(substs.regions().len(space), 0);
4564             for (i, lifetime) in data.lifetimes.iter().enumerate() {
4565                 let r = ast_region_to_region(fcx.tcx(), lifetime);
4566                 if i < region_count {
4567                     substs.mut_regions().push(space, r);
4568                 } else if i == region_count {
4569                     span_err!(fcx.tcx().sess, lifetime.span, E0088,
4570                         "too many lifetime parameters provided: \
4571                          expected {} parameter{}, found {} parameter{}",
4572                         region_count,
4573                         if region_count == 1 {""} else {"s"},
4574                         data.lifetimes.len(),
4575                         if data.lifetimes.len() == 1 {""} else {"s"});
4576                     substs.mut_regions().truncate(space, 0);
4577                     break;
4578                 }
4579             }
4580         }
4581     }
4582
4583     /// As with
4584     /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4585     /// but intended for `Foo(A,B) -> C` form. This expands to
4586     /// roughly the same thing as `Foo<(A,B),C>`. One important
4587     /// difference has to do with the treatment of anonymous
4588     /// regions, which are translated into bound regions (NYI).
4589     fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4590         fcx: &FnCtxt<'a, 'tcx>,
4591         space: subst::ParamSpace,
4592         span: Span,
4593         type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4594         data: &hir::ParenthesizedParameterData,
4595         substs: &mut Substs<'tcx>)
4596     {
4597         let type_count = type_defs.len(space);
4598         if type_count < 2 {
4599             span_err!(fcx.tcx().sess, span, E0167,
4600                       "parenthesized form always supplies 2 type parameters, \
4601                       but only {} parameter(s) were expected",
4602                       type_count);
4603         }
4604
4605         let input_tys: Vec<Ty> =
4606             data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4607
4608         let tuple_ty = fcx.tcx().mk_tup(input_tys);
4609
4610         if type_count >= 1 {
4611             substs.types.push(space, tuple_ty);
4612         }
4613
4614         let output_ty: Option<Ty> =
4615             data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4616
4617         let output_ty =
4618             output_ty.unwrap_or(fcx.tcx().mk_nil());
4619
4620         if type_count >= 2 {
4621             substs.types.push(space, output_ty);
4622         }
4623     }
4624
4625     fn adjust_type_parameters<'a, 'tcx>(
4626         fcx: &FnCtxt<'a, 'tcx>,
4627         span: Span,
4628         space: ParamSpace,
4629         defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4630         require_type_space: bool,
4631         substs: &mut Substs<'tcx>)
4632     {
4633         let provided_len = substs.types.len(space);
4634         let desired = defs.get_slice(space);
4635         let required_len = desired.iter()
4636                               .take_while(|d| d.default.is_none())
4637                               .count();
4638
4639         debug!("adjust_type_parameters(space={:?}, \
4640                provided_len={}, \
4641                desired_len={}, \
4642                required_len={})",
4643                space,
4644                provided_len,
4645                desired.len(),
4646                required_len);
4647
4648         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4649         assert!(provided_len <= desired.len());
4650
4651         // Nothing specified at all: supply inference variables for
4652         // everything.
4653         if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4654             substs.types.replace(space, Vec::new());
4655             fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4656             return;
4657         }
4658
4659         // Too few parameters specified: report an error and use Err
4660         // for everything.
4661         if provided_len < required_len {
4662             let qualifier =
4663                 if desired.len() != required_len { "at least " } else { "" };
4664             span_err!(fcx.tcx().sess, span, E0089,
4665                 "too few type parameters provided: expected {}{} parameter{}, \
4666                  found {} parameter{}",
4667                 qualifier, required_len,
4668                 if required_len == 1 {""} else {"s"},
4669                 provided_len,
4670                 if provided_len == 1 {""} else {"s"});
4671             substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4672             return;
4673         }
4674
4675         // Otherwise, add in any optional parameters that the user
4676         // omitted. The case of *too many* parameters is handled
4677         // already by
4678         // push_explicit_parameters_from_segment_to_substs(). Note
4679         // that the *default* type are expressed in terms of all prior
4680         // parameters, so we have to substitute as we go with the
4681         // partial substitution that we have built up.
4682         for i in provided_len..desired.len() {
4683             let default = desired[i].default.unwrap();
4684             let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4685             substs.types.push(space, default);
4686         }
4687         assert_eq!(substs.types.len(space), desired.len());
4688
4689         debug!("Final substs: {:?}", substs);
4690     }
4691
4692     fn adjust_region_parameters(
4693         fcx: &FnCtxt,
4694         span: Span,
4695         space: ParamSpace,
4696         defs: &VecPerParamSpace<ty::RegionParameterDef>,
4697         substs: &mut Substs)
4698     {
4699         let provided_len = substs.mut_regions().len(space);
4700         let desired = defs.get_slice(space);
4701
4702         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4703         assert!(provided_len <= desired.len());
4704
4705         // If nothing was provided, just use inference variables.
4706         if provided_len == 0 {
4707             substs.mut_regions().replace(
4708                 space,
4709                 fcx.infcx().region_vars_for_defs(span, desired));
4710             return;
4711         }
4712
4713         // If just the right number were provided, everybody is happy.
4714         if provided_len == desired.len() {
4715             return;
4716         }
4717
4718         // Otherwise, too few were provided. Report an error and then
4719         // use inference variables.
4720         span_err!(fcx.tcx().sess, span, E0090,
4721             "too few lifetime parameters provided: expected {} parameter{}, \
4722              found {} parameter{}",
4723             desired.len(),
4724             if desired.len() == 1 {""} else {"s"},
4725             provided_len,
4726             if provided_len == 1 {""} else {"s"});
4727
4728         substs.mut_regions().replace(
4729             space,
4730             fcx.infcx().region_vars_for_defs(span, desired));
4731     }
4732 }
4733
4734 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4735                                                   sp: Span,
4736                                                   ty: Ty<'tcx>,
4737                                                   f: F) -> Ty<'tcx>
4738     where F: Fn() -> Ty<'tcx>
4739 {
4740     let mut ty = fcx.resolve_type_vars_if_possible(ty);
4741
4742     if ty.is_ty_var() {
4743         let alternative = f();
4744
4745         // If not, error.
4746         if alternative.is_ty_var() || alternative.references_error() {
4747             fcx.type_error_message(sp, |_actual| {
4748                 "the type of this value must be known in this context".to_string()
4749             }, ty, None);
4750             demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4751             ty = fcx.tcx().types.err;
4752         } else {
4753             demand::suptype(fcx, sp, alternative, ty);
4754             ty = alternative;
4755         }
4756     }
4757
4758     ty
4759 }
4760
4761 // Resolves `typ` by a single level if `typ` is a type variable.  If no
4762 // resolution is possible, then an error is reported.
4763 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4764                                             sp: Span,
4765                                             ty: Ty<'tcx>)
4766                                             -> Ty<'tcx>
4767 {
4768     structurally_resolve_type_or_else(fcx, sp, ty, || {
4769         fcx.tcx().types.err
4770     })
4771 }
4772
4773 // Returns true if b contains a break that can exit from b
4774 pub fn may_break(cx: &TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4775     // First: is there an unlabeled break immediately
4776     // inside the loop?
4777     (loop_query(&b, |e| {
4778         match *e {
4779             hir::ExprBreak(None) => true,
4780             _ => false
4781         }
4782     })) ||
4783     // Second: is there a labeled break with label
4784     // <id> nested anywhere inside the loop?
4785     (block_query(b, |e| {
4786         if let hir::ExprBreak(Some(_)) = e.node {
4787             lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4788         } else {
4789             false
4790         }
4791     }))
4792 }
4793
4794 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4795                                        tps: &[hir::TyParam],
4796                                        ty: Ty<'tcx>) {
4797     debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4798            tps.len(),  ty);
4799
4800     // make a vector of booleans initially false, set to true when used
4801     if tps.is_empty() { return; }
4802     let mut tps_used = vec![false; tps.len()];
4803
4804     for leaf_ty in ty.walk() {
4805         if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4806             debug!("Found use of ty param num {}", idx);
4807             tps_used[idx as usize] = true;
4808         }
4809     }
4810
4811     for (i, b) in tps_used.iter().enumerate() {
4812         if !*b {
4813             span_err!(ccx.tcx.sess, tps[i].span, E0091,
4814                 "type parameter `{}` is unused",
4815                 tps[i].name);
4816         }
4817     }
4818 }