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