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