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