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