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