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