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