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