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