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