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