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