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