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