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.
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.
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
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
23 - gather: creates type variables to represent the type of each local
24 variable and pattern binding.
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.
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.
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
43 - vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
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.
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`.
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.
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
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
79 pub use self::LvaluePreference::*;
80 pub use self::Expectation::*;
81 pub use self::compare_method::{compare_impl_method, compare_const_impl};
82 use self::TupleArgumentsFlag::*;
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};
90 use middle::pat_util::{self, pat_id_map};
91 use middle::privacy::{AllPublic, LastMod};
92 use middle::region::{self, CodeExtent};
93 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
94 use middle::traits::{self, report_fulfillment_errors};
95 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
96 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
97 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
98 use middle::ty::{MethodCall, MethodCallee};
99 use middle::ty_fold::{TypeFolder, TypeFoldable};
100 use require_c_abi_if_variadic;
101 use rscope::{ElisionFailureInfo, RegionScope};
102 use session::Session;
103 use {CrateCtxt, lookup_full_def, require_same_types};
106 use util::common::{block_query, ErrorReported, indenter, loop_query};
107 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
108 use util::lev_distance::lev_distance;
110 use std::cell::{Cell, Ref, RefCell};
111 use std::mem::replace;
113 use syntax::{self, abi, attr};
114 use syntax::attr::AttrMetaMethods;
115 use syntax::ast::{self, DefId, Visibility};
116 use syntax::ast_util::{self, local_def};
117 use syntax::codemap::{self, Span};
118 use syntax::owned_slice::OwnedSlice;
119 use syntax::parse::token;
120 use syntax::print::pprust;
122 use syntax::visit::{self, Visitor};
140 /// closures defined within the function. For example:
143 /// bar(move|| { ... })
146 /// Here, the function `foo()` and the closure passed to
147 /// `bar()` will each have their own `FnCtxt`, but they will
148 /// share the inherited fields.
149 pub struct Inherited<'a, 'tcx: 'a> {
150 infcx: infer::InferCtxt<'a, 'tcx>,
151 locals: RefCell<NodeMap<Ty<'tcx>>>,
153 tables: &'a RefCell<ty::Tables<'tcx>>,
155 // A mapping from each fn's id to its signature, with all bound
156 // regions replaced with free ones. Unlike the other tables, this
157 // one is never copied into the tcx: it is only used by regionck.
158 fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
160 // When we process a call like `c()` where `c` is a closure type,
161 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
162 // `FnOnce` closure. In that case, we defer full resolution of the
163 // call until upvar inference can kick in and make the
164 // decision. We keep these deferred resolutions grouped by the
165 // def-id of the closure, so that once we decide, we can easily go
166 // back and process them.
167 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
169 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
172 trait DeferredCallResolution<'tcx> {
173 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
176 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
178 /// When type-checking an expression, we propagate downward
179 /// whatever type hint we are able in the form of an `Expectation`.
180 #[derive(Copy, Clone, Debug)]
181 pub enum Expectation<'tcx> {
182 /// We know nothing about what type this expression should have.
185 /// This expression should have the type given (or some subtype)
186 ExpectHasType(Ty<'tcx>),
188 /// This expression will be cast to the `Ty`
189 ExpectCastableToType(Ty<'tcx>),
191 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
192 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
193 ExpectRvalueLikeUnsized(Ty<'tcx>),
196 impl<'tcx> Expectation<'tcx> {
197 // Disregard "castable to" expectations because they
198 // can lead us astray. Consider for example `if cond
199 // {22} else {c} as u8` -- if we propagate the
200 // "castable to u8" constraint to 22, it will pick the
201 // type 22u8, which is overly constrained (c might not
202 // be a u8). In effect, the problem is that the
203 // "castable to" expectation is not the tightest thing
204 // we can say, so we want to drop it in this case.
205 // The tightest thing we can say is "must unify with
206 // else branch". Note that in the case of a "has type"
207 // constraint, this limitation does not hold.
209 // If the expected type is just a type variable, then don't use
210 // an expected type. Otherwise, we might write parts of the type
211 // when checking the 'then' block which are incompatible with the
213 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
215 ExpectHasType(ety) => {
216 let ety = fcx.infcx().shallow_resolve(ety);
217 if !ety.is_ty_var() {
223 ExpectRvalueLikeUnsized(ety) => {
224 ExpectRvalueLikeUnsized(ety)
231 #[derive(Copy, Clone)]
232 pub struct UnsafetyState {
233 pub def: ast::NodeId,
234 pub unsafety: ast::Unsafety,
239 pub fn function(unsafety: ast::Unsafety, def: ast::NodeId) -> UnsafetyState {
240 UnsafetyState { def: def, unsafety: unsafety, from_fn: true }
243 pub fn recurse(&mut self, blk: &ast::Block) -> UnsafetyState {
244 match self.unsafety {
245 // If this unsafe, then if the outer function was already marked as
246 // unsafe we shouldn't attribute the unsafe'ness to the block. This
247 // way the block can be warned about instead of ignoring this
248 // extraneous block (functions are never warned about).
249 ast::Unsafety::Unsafe if self.from_fn => *self,
252 let (unsafety, def) = match blk.rules {
253 ast::UnsafeBlock(..) => (ast::Unsafety::Unsafe, blk.id),
254 ast::DefaultBlock => (unsafety, self.def),
256 UnsafetyState{ def: def,
265 pub struct FnCtxt<'a, 'tcx: 'a> {
266 body_id: ast::NodeId,
268 // This flag is set to true if, during the writeback phase, we encounter
269 // a type error in this function.
270 writeback_errors: Cell<bool>,
272 // Number of errors that had been reported when we started
273 // checking this function. On exit, if we find that *more* errors
274 // have been reported, we will skip regionck and other work that
275 // expects the types within the function to be consistent.
276 err_count_on_creation: usize,
278 ret_ty: ty::FnOutput<'tcx>,
280 ps: RefCell<UnsafetyState>,
282 inh: &'a Inherited<'a, 'tcx>,
284 ccx: &'a CrateCtxt<'a, 'tcx>,
287 impl<'a, 'tcx> Inherited<'a, 'tcx> {
288 fn new(tcx: &'a ty::ctxt<'tcx>,
289 tables: &'a RefCell<ty::Tables<'tcx>>,
290 param_env: ty::ParameterEnvironment<'a, 'tcx>)
291 -> Inherited<'a, 'tcx> {
294 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
295 locals: RefCell::new(NodeMap()),
297 fn_sig_map: RefCell::new(NodeMap()),
298 deferred_call_resolutions: RefCell::new(DefIdMap()),
299 deferred_cast_checks: RefCell::new(Vec::new()),
303 fn normalize_associated_types_in<T>(&self,
305 body_id: ast::NodeId,
308 where T : TypeFoldable<'tcx> + HasTypeFlags
310 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
311 assoc::normalize_associated_types_in(&self.infcx,
320 // Used by check_const and check_enum_variants
321 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
322 inh: &'a Inherited<'a, 'tcx>,
323 rty: ty::FnOutput<'tcx>,
324 body_id: ast::NodeId)
325 -> FnCtxt<'a, 'tcx> {
328 writeback_errors: Cell::new(false),
329 err_count_on_creation: ccx.tcx.sess.err_count(),
331 ps: RefCell::new(UnsafetyState::function(ast::Unsafety::Normal, 0)),
337 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
338 tables: &'a RefCell<ty::Tables<'tcx>>)
339 -> Inherited<'a, 'tcx> {
340 // It's kind of a kludge to manufacture a fake function context
341 // and statement context, but we might as well do write the code only once
342 let param_env = ccx.tcx.empty_parameter_environment();
343 Inherited::new(ccx.tcx, &tables, param_env)
346 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
347 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
349 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
350 fn visit_item(&mut self, i: &'tcx ast::Item) {
351 check_item_type(self.ccx, i);
352 visit::walk_item(self, i);
355 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
357 ast::TyFixedLengthVec(_, ref expr) => {
358 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
363 visit::walk_ty(self, t);
367 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
368 fn visit_item(&mut self, i: &'tcx ast::Item) {
369 check_item_body(self.ccx, i);
370 visit::walk_item(self, i);
374 pub fn check_item_types(ccx: &CrateCtxt) {
375 let krate = ccx.tcx.map.krate();
376 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
377 visit::walk_crate(&mut visit, krate);
379 // If types are not well-formed, it leads to all manner of errors
380 // downstream, so stop reporting errors at this point.
381 ccx.tcx.sess.abort_if_errors();
383 let mut visit = CheckItemTypesVisitor { ccx: ccx };
384 visit::walk_crate(&mut visit, krate);
386 ccx.tcx.sess.abort_if_errors();
388 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
389 visit::walk_crate(&mut visit, krate);
391 ccx.tcx.sess.abort_if_errors();
393 for drop_method_did in ccx.tcx.destructors.borrow().iter() {
394 if drop_method_did.krate == ast::LOCAL_CRATE {
395 let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
396 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
399 assert!(ccx.tcx.sess.has_errors());
405 ccx.tcx.sess.abort_if_errors();
408 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
409 decl: &'tcx ast::FnDecl,
410 body: &'tcx ast::Block,
414 param_env: ty::ParameterEnvironment<'a, 'tcx>)
417 ty::TyBareFn(_, ref fn_ty) => {
418 let tables = RefCell::new(ty::Tables::empty());
419 let inh = Inherited::new(ccx.tcx, &tables, param_env);
421 // Compute the fty from point of view of inside fn.
423 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
425 ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
428 inh.normalize_associated_types_in(body.span,
432 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
433 decl, fn_id, body, &inh);
435 fcx.select_all_obligations_and_apply_defaults();
436 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
437 fcx.select_all_obligations_or_error();
440 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
442 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
443 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
445 _ => ccx.tcx.sess.impossible_case(body.span,
446 "check_bare_fn: function type expected")
450 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
451 fcx: &'a FnCtxt<'a, 'tcx>
454 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
455 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
458 // infer the variable's type
459 let var_ty = self.fcx.infcx().next_ty_var();
460 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
464 // take type that the user specified
465 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
472 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
473 // Add explicitly-declared locals.
474 fn visit_local(&mut self, local: &'tcx ast::Local) {
475 let o_ty = match local.ty {
476 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
479 self.assign(local.span, local.id, o_ty);
480 debug!("Local variable {:?} is assigned type {}",
482 self.fcx.infcx().ty_to_string(
483 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
484 visit::walk_local(self, local);
487 // Add pattern bindings.
488 fn visit_pat(&mut self, p: &'tcx ast::Pat) {
489 if let ast::PatIdent(_, ref path1, _) = p.node {
490 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) {
491 let var_ty = self.assign(p.span, p.id, None);
493 self.fcx.require_type_is_sized(var_ty, p.span,
494 traits::VariableType(p.id));
496 debug!("Pattern binding {} is assigned to {} with type {:?}",
497 token::get_ident(path1.node),
498 self.fcx.infcx().ty_to_string(
499 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
503 visit::walk_pat(self, p);
506 fn visit_block(&mut self, b: &'tcx ast::Block) {
507 // non-obvious: the `blk` variable maps to region lb, so
508 // we have to keep this up-to-date. This
509 // is... unfortunate. It'd be nice to not need this.
510 visit::walk_block(self, b);
513 // Since an expr occurs as part of the type fixed size arrays we
514 // need to record the type for that node
515 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
517 ast::TyFixedLengthVec(ref ty, ref count_expr) => {
518 self.visit_ty(&**ty);
519 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
521 _ => visit::walk_ty(self, t)
525 // Don't descend into fns and items
526 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx ast::FnDecl,
527 _: &'tcx ast::Block, _: Span, _: ast::NodeId) { }
528 fn visit_item(&mut self, _: &ast::Item) { }
532 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
533 /// body and returns the function context used for that purpose, since in the case of a fn item
534 /// there is still a bit more to do.
537 /// * inherited: other fields inherited from the enclosing fn (if any)
538 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
539 unsafety: ast::Unsafety,
540 unsafety_id: ast::NodeId,
541 fn_sig: &ty::FnSig<'tcx>,
542 decl: &'tcx ast::FnDecl,
544 body: &'tcx ast::Block,
545 inherited: &'a Inherited<'a, 'tcx>)
549 let err_count_on_creation = tcx.sess.err_count();
551 let arg_tys = &fn_sig.inputs;
552 let ret_ty = fn_sig.output;
554 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
559 // Create the function context. This is either derived from scratch or,
560 // in the case of function expressions, based on the outer context.
563 writeback_errors: Cell::new(false),
564 err_count_on_creation: err_count_on_creation,
566 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
571 // Remember return type so that regionck can access it later.
572 let mut fn_sig_tys: Vec<Ty> =
577 if let ty::FnConverging(ret_ty) = ret_ty {
578 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
579 fn_sig_tys.push(ret_ty);
582 debug!("fn-sig-map: fn_id={} fn_sig_tys={:?}",
586 inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys);
589 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
591 // Add formal parameters.
592 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
593 // Create type variables for each argument.
594 pat_util::pat_bindings(
597 |_bm, pat_id, sp, _path| {
598 let var_ty = visit.assign(sp, pat_id, None);
599 fcx.require_type_is_sized(var_ty, sp,
600 traits::VariableType(pat_id));
603 // Check the pattern.
606 map: pat_id_map(&tcx.def_map, &*input.pat),
608 _match::check_pat(&pcx, &*input.pat, *arg_ty);
611 visit.visit_block(body);
614 check_block_with_expected(&fcx, body, match ret_ty {
615 ty::FnConverging(result_type) => ExpectHasType(result_type),
616 ty::FnDiverging => NoExpectation
619 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
620 fcx.write_ty(input.id, arg);
626 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
629 check_representable(tcx, span, id, "struct");
630 check_instantiable(tcx, span, id);
632 if tcx.lookup_simd(local_def(id)) {
633 check_simd(tcx, span, id);
637 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
638 debug!("check_item_type(it.id={}, it.ident={})",
640 ccx.tcx.item_path_str(local_def(it.id)));
641 let _indenter = indenter();
643 // Consts can play a role in type-checking, so they are included here.
644 ast::ItemStatic(_, _, ref e) |
645 ast::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
646 ast::ItemEnum(ref enum_definition, _) => {
647 check_enum_variants(ccx,
649 &enum_definition.variants,
652 ast::ItemFn(..) => {} // entirely within check_item_body
653 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
654 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
655 match ccx.tcx.impl_trait_ref(local_def(it.id)) {
656 Some(impl_trait_ref) => {
657 check_impl_items_against_trait(ccx,
665 ast::ItemTrait(_, ref generics, _, _) => {
666 check_trait_on_unimplemented(ccx, generics, it);
668 ast::ItemStruct(..) => {
669 check_struct(ccx, it.id, it.span);
671 ast::ItemTy(ref t, ref generics) => {
672 let pty_ty = ccx.tcx.node_id_to_type(it.id);
673 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
675 ast::ItemForeignMod(ref m) => {
676 if m.abi == abi::RustIntrinsic {
677 for item in &m.items {
678 check_intrinsic_type(ccx, &**item);
681 for item in &m.items {
682 let pty = ccx.tcx.lookup_item_type(local_def(item.id));
683 if !pty.generics.types.is_empty() {
684 span_err!(ccx.tcx.sess, item.span, E0044,
685 "foreign items may not have type parameters");
688 if let ast::ForeignItemFn(ref fn_decl, _) = item.node {
689 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
694 _ => {/* nothing to do */ }
698 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
699 debug!("check_item_body(it.id={}, it.ident={})",
701 ccx.tcx.item_path_str(local_def(it.id)));
702 let _indenter = indenter();
704 ast::ItemFn(ref decl, _, _, _, _, ref body) => {
705 let fn_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
706 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
707 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
709 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
710 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
712 let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
714 for impl_item in impl_items {
715 match impl_item.node {
716 ast::ConstImplItem(_, ref expr) => {
717 check_const(ccx, impl_item.span, &*expr, impl_item.id)
719 ast::MethodImplItem(ref sig, ref body) => {
720 check_method_body(ccx, &impl_pty.generics, sig, body,
721 impl_item.id, impl_item.span);
723 ast::TypeImplItem(_) |
724 ast::MacImplItem(_) => {
725 // Nothing to do here.
730 ast::ItemTrait(_, _, _, ref trait_items) => {
731 let trait_def = ccx.tcx.lookup_trait_def(local_def(it.id));
732 for trait_item in trait_items {
733 match trait_item.node {
734 ast::ConstTraitItem(_, Some(ref expr)) => {
735 check_const(ccx, trait_item.span, &*expr, trait_item.id)
737 ast::MethodTraitItem(ref sig, Some(ref body)) => {
738 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
740 check_method_body(ccx, &trait_def.generics, sig, body,
741 trait_item.id, trait_item.span);
743 ast::MethodTraitItem(ref sig, None) => {
744 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
746 ast::ConstTraitItem(_, None) |
747 ast::TypeTraitItem(..) => {
753 _ => {/* nothing to do */ }
757 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
759 constness: ast::Constness)
762 ast::Constness::NotConst => {
765 ast::Constness::Const => {
766 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
771 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
772 generics: &ast::Generics,
774 if let Some(ref attr) = item.attrs.iter().find(|a| {
775 a.check_name("rustc_on_unimplemented")
777 if let Some(ref istring) = attr.value_str() {
778 let parser = Parser::new(&istring);
779 let types = &*generics.ty_params;
780 for token in parser {
782 Piece::String(_) => (), // Normal string, no need to check it
783 Piece::NextArgument(a) => match a.position {
784 // `{Self}` is allowed
785 Position::ArgumentNamed(s) if s == "Self" => (),
786 // So is `{A}` if A is a type parameter
787 Position::ArgumentNamed(s) => match types.iter().find(|t| {
788 t.ident.as_str() == s
792 span_err!(ccx.tcx.sess, attr.span, E0230,
793 "there is no type parameter \
795 s, item.ident.as_str());
798 // `{:1}` and `{}` are not to be used
799 Position::ArgumentIs(_) | Position::ArgumentNext => {
800 span_err!(ccx.tcx.sess, attr.span, E0231,
801 "only named substitution \
802 parameters are allowed");
808 span_err!(ccx.tcx.sess, attr.span, E0232,
809 "this attribute must have a value, \
810 eg `#[rustc_on_unimplemented = \"foo\"]`")
815 /// Type checks a method body.
819 /// * `item_generics`: generics defined on the impl/trait that contains
821 /// * `self_bound`: bound for the `Self` type parameter, if any
822 /// * `method`: the method definition
823 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
824 item_generics: &ty::Generics<'tcx>,
825 sig: &'tcx ast::MethodSig,
826 body: &'tcx ast::Block,
827 id: ast::NodeId, span: Span) {
828 debug!("check_method_body(item_generics={:?}, id={})",
830 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
832 let fty = ccx.tcx.node_id_to_type(id);
833 debug!("check_method_body: fty={:?}", fty);
835 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
838 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
840 impl_trait_ref: &ty::TraitRef<'tcx>,
841 impl_items: &[P<ast::ImplItem>]) {
842 // Locate trait methods
844 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
845 let mut overridden_associated_type = None;
847 // Check existing impl methods to see if they are both present in trait
848 // and compatible with trait signature
849 for impl_item in impl_items {
850 let ty_impl_item = ccx.tcx.impl_or_trait_item(local_def(impl_item.id));
851 let ty_trait_item = trait_items.iter()
852 .find(|ac| ac.name() == ty_impl_item.name())
854 // This is checked by resolve
855 tcx.sess.span_bug(impl_item.span,
856 &format!("impl-item `{}` is not a member of `{:?}`",
857 token::get_name(ty_impl_item.name()),
860 match impl_item.node {
861 ast::ConstImplItem(..) => {
862 let impl_const = match ty_impl_item {
863 ty::ConstTraitItem(ref cti) => cti,
864 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
867 // Find associated const definition.
868 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
869 compare_const_impl(ccx.tcx,
875 span_err!(tcx.sess, impl_item.span, E0323,
876 "item `{}` is an associated const, \
877 which doesn't match its trait `{:?}`",
878 token::get_name(impl_const.name),
882 ast::MethodImplItem(ref sig, ref body) => {
883 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
885 let impl_method = match ty_impl_item {
886 ty::MethodTraitItem(ref mti) => mti,
887 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
890 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
891 compare_impl_method(ccx.tcx,
898 span_err!(tcx.sess, impl_item.span, E0324,
899 "item `{}` is an associated method, \
900 which doesn't match its trait `{:?}`",
901 token::get_name(impl_method.name),
905 ast::TypeImplItem(_) => {
906 let impl_type = match ty_impl_item {
907 ty::TypeTraitItem(ref tti) => tti,
908 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
911 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
912 if let Some(_) = at.ty {
913 overridden_associated_type = Some(impl_item);
916 span_err!(tcx.sess, impl_item.span, E0325,
917 "item `{}` is an associated type, \
918 which doesn't match its trait `{:?}`",
919 token::get_name(impl_type.name),
923 ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
928 // Check for missing items from trait
929 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
930 let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
931 let mut missing_items = Vec::new();
932 let mut invalidated_items = Vec::new();
933 let associated_type_overridden = overridden_associated_type.is_some();
934 for trait_item in trait_items.iter() {
936 ty::ConstTraitItem(ref associated_const) => {
937 let is_implemented = impl_items.iter().any(|ii| {
939 ast::ConstImplItem(..) => {
940 ii.ident.name == associated_const.name
946 associated_consts.iter().any(|ac| ac.default.is_some() &&
947 ac.name == associated_const.name);
950 missing_items.push(associated_const.name);
951 } else if associated_type_overridden {
952 invalidated_items.push(associated_const.name);
956 ty::MethodTraitItem(ref trait_method) => {
958 impl_items.iter().any(|ii| {
960 ast::MethodImplItem(..) => {
961 ii.ident.name == trait_method.name
967 provided_methods.iter().any(|m| m.name == trait_method.name);
970 missing_items.push(trait_method.name);
971 } else if associated_type_overridden {
972 invalidated_items.push(trait_method.name);
976 ty::TypeTraitItem(ref associated_type) => {
977 let is_implemented = impl_items.iter().any(|ii| {
979 ast::TypeImplItem(_) => {
980 ii.ident.name == associated_type.name
985 let is_provided = associated_type.ty.is_some();
988 missing_items.push(associated_type.name);
989 } else if associated_type_overridden {
990 invalidated_items.push(associated_type.name);
997 if !missing_items.is_empty() {
998 span_err!(tcx.sess, impl_span, E0046,
999 "not all trait items implemented, missing: `{}`",
1000 missing_items.iter()
1001 .map(<ast::Name>::as_str)
1002 .collect::<Vec<_>>().join("`, `"))
1005 if !invalidated_items.is_empty() {
1006 let invalidator = overridden_associated_type.unwrap();
1007 span_err!(tcx.sess, invalidator.span, E0399,
1008 "the following trait items need to be reimplemented \
1009 as `{}` was overridden: `{}`",
1010 invalidator.ident.as_str(),
1011 invalidated_items.iter()
1012 .map(<ast::Name>::as_str)
1013 .collect::<Vec<_>>().join("`, `"))
1017 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1024 let tstr = fcx.infcx().ty_to_string(t_cast);
1025 fcx.type_error_message(span, |actual| {
1026 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1029 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1030 let mtstr = match mt {
1031 ast::MutMutable => "mut ",
1032 ast::MutImmutable => ""
1034 if t_cast.is_trait() {
1035 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1037 fcx.tcx().sess.span_suggestion(t_span,
1038 "try casting to a reference instead:",
1039 format!("&{}{}", mtstr, s));
1042 span_help!(fcx.tcx().sess, t_span,
1043 "did you mean `&{}{}`?", mtstr, tstr),
1046 span_help!(fcx.tcx().sess, span,
1047 "consider using an implicit coercion to `&{}{}` instead",
1052 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1054 fcx.tcx().sess.span_suggestion(t_span,
1055 "try casting to a `Box` instead:",
1056 format!("Box<{}>", s));
1059 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1063 span_help!(fcx.tcx().sess, e_span,
1064 "consider using a box or reference as appropriate");
1067 fcx.write_error(id);
1071 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1072 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1074 fn get_item_type_scheme(&self, _: Span, id: ast::DefId)
1075 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1077 Ok(self.tcx().lookup_item_type(id))
1080 fn get_trait_def(&self, _: Span, id: ast::DefId)
1081 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1083 Ok(self.tcx().lookup_trait_def(id))
1086 fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
1087 // all super predicates are ensured during collect pass
1091 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1092 Some(&self.inh.infcx.parameter_environment.free_substs)
1095 fn get_type_parameter_bounds(&self,
1097 node_id: ast::NodeId)
1098 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1100 let def = self.tcx().type_parameter_def(node_id);
1101 let r = self.inh.infcx.parameter_environment
1104 .filter_map(|predicate| {
1106 ty::Predicate::Trait(ref data) => {
1107 if data.0.self_ty().is_param(def.space, def.index) {
1108 Some(data.to_poly_trait_ref())
1122 fn trait_defines_associated_type_named(&self,
1123 trait_def_id: ast::DefId,
1124 assoc_name: ast::Name)
1127 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1128 trait_def.associated_type_names.contains(&assoc_name)
1131 fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
1132 self.infcx().next_ty_var()
1135 fn projected_ty_from_poly_trait_ref(&self,
1137 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1138 item_name: ast::Name)
1141 let (trait_ref, _) =
1142 self.infcx().replace_late_bound_regions_with_fresh_var(
1144 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1147 self.normalize_associated_type(span, trait_ref, item_name)
1150 fn projected_ty(&self,
1152 trait_ref: ty::TraitRef<'tcx>,
1153 item_name: ast::Name)
1156 self.normalize_associated_type(span, trait_ref, item_name)
1160 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1161 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1163 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1167 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1168 &self.inh.infcx.parameter_environment
1171 pub fn sess(&self) -> &Session {
1175 pub fn err_count_since_creation(&self) -> usize {
1176 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1179 /// Resolves type variables in `ty` if possible. Unlike the infcx
1180 /// version, this version will also select obligations if it seems
1181 /// useful, in an effort to get more type information.
1182 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1183 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1185 // No TyInfer()? Nothing needs doing.
1186 if !ty.has_infer_types() {
1187 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1191 // If `ty` is a type variable, see whether we already know what it is.
1192 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1193 if !ty.has_infer_types() {
1194 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1198 // If not, try resolving any new fcx obligations that have cropped up.
1199 self.select_new_obligations();
1200 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1201 if !ty.has_infer_types() {
1202 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1206 // If not, try resolving *all* pending obligations as much as
1207 // possible. This can help substantially when there are
1208 // indirect dependencies that don't seem worth tracking
1210 self.select_obligations_where_possible();
1211 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1213 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1217 fn record_deferred_call_resolution(&self,
1218 closure_def_id: ast::DefId,
1219 r: DeferredCallResolutionHandler<'tcx>) {
1220 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1221 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1224 fn remove_deferred_call_resolutions(&self,
1225 closure_def_id: ast::DefId)
1226 -> Vec<DeferredCallResolutionHandler<'tcx>>
1228 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1229 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1232 pub fn tag(&self) -> String {
1233 let self_ptr: *const FnCtxt = self;
1234 format!("{:?}", self_ptr)
1237 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1238 match self.inh.locals.borrow().get(&nid) {
1241 self.tcx().sess.span_err(
1243 &format!("no type for local variable {}", nid));
1244 self.tcx().types.err
1249 /// Apply "fallbacks" to some types
1250 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1251 pub fn default_type_parameters(&self) {
1252 use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
1253 for (_, &mut ref ty) in &mut self.inh.tables.borrow_mut().node_types {
1254 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1255 if self.infcx().type_var_diverges(resolved) {
1256 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1258 match self.infcx().type_is_unconstrained_numeric(resolved) {
1259 UnconstrainedInt => {
1260 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1262 UnconstrainedFloat => {
1263 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1272 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1273 debug!("write_ty({}, {:?}) in fcx {}",
1274 node_id, ty, self.tag());
1275 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1278 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1279 if !substs.substs.is_noop() {
1280 debug!("write_substs({}, {:?}) in fcx {}",
1285 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1289 pub fn write_autoderef_adjustment(&self,
1290 node_id: ast::NodeId,
1292 self.write_adjustment(
1294 ty::AdjustDerefRef(ty::AutoDerefRef {
1302 pub fn write_adjustment(&self,
1303 node_id: ast::NodeId,
1304 adj: ty::AutoAdjustment<'tcx>) {
1305 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1307 if adj.is_identity() {
1311 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1314 /// Basically whenever we are converting from a type scheme into
1315 /// the fn body space, we always want to normalize associated
1316 /// types as well. This function combines the two.
1317 fn instantiate_type_scheme<T>(&self,
1319 substs: &Substs<'tcx>,
1322 where T : TypeFoldable<'tcx> + HasTypeFlags
1324 let value = value.subst(self.tcx(), substs);
1325 let result = self.normalize_associated_types_in(span, &value);
1326 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1333 /// As `instantiate_type_scheme`, but for the bounds found in a
1334 /// generic type scheme.
1335 fn instantiate_bounds(&self,
1337 substs: &Substs<'tcx>,
1338 bounds: &ty::GenericPredicates<'tcx>)
1339 -> ty::InstantiatedPredicates<'tcx>
1341 ty::InstantiatedPredicates {
1342 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1347 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1348 where T : TypeFoldable<'tcx> + HasTypeFlags
1350 self.inh.normalize_associated_types_in(span, self.body_id, value)
1353 fn normalize_associated_type(&self,
1355 trait_ref: ty::TraitRef<'tcx>,
1356 item_name: ast::Name)
1359 let cause = traits::ObligationCause::new(span,
1361 traits::ObligationCauseCode::MiscObligation);
1366 .normalize_projection_type(self.infcx(),
1368 trait_ref: trait_ref,
1369 item_name: item_name,
1374 /// Returns the type of `def_id` with all generics replaced by by fresh type/region variables.
1375 /// Also returns the substitution from the type parameters on `def_id` to the fresh variables.
1376 /// Registers any trait obligations specified on `def_id` at the same time.
1378 /// Note that function is only intended to be used with types (notably, not fns). This is
1379 /// because it doesn't do any instantiation of late-bound regions.
1380 pub fn instantiate_type(&self,
1383 -> TypeAndSubsts<'tcx>
1386 self.tcx().lookup_item_type(def_id);
1387 let type_predicates =
1388 self.tcx().lookup_predicates(def_id);
1390 self.infcx().fresh_substs_for_generics(
1392 &type_scheme.generics);
1394 self.instantiate_bounds(span, &substs, &type_predicates);
1395 self.add_obligations_for_parameters(
1396 traits::ObligationCause::new(
1399 traits::ItemObligation(def_id)),
1402 self.instantiate_type_scheme(span, &substs, &type_scheme.ty);
1410 /// Returns the type that this AST path refers to. If the path has no type
1411 /// parameters and the corresponding type has type parameters, fresh type
1412 /// and/or region variables are substituted.
1414 /// This is used when checking the constructor in struct literals.
1415 fn instantiate_struct_literal_ty(&self,
1418 -> TypeAndSubsts<'tcx>
1420 let tcx = self.tcx();
1422 let ty::TypeScheme { generics, ty: decl_ty } =
1423 tcx.lookup_item_type(did);
1425 let substs = astconv::ast_path_substs_for_ty(self, self,
1427 PathParamMode::Optional,
1429 path.segments.last().unwrap());
1431 let ty = self.instantiate_type_scheme(path.span, &substs, &decl_ty);
1433 TypeAndSubsts { substs: substs, ty: ty }
1436 pub fn write_nil(&self, node_id: ast::NodeId) {
1437 self.write_ty(node_id, self.tcx().mk_nil());
1439 pub fn write_error(&self, node_id: ast::NodeId) {
1440 self.write_ty(node_id, self.tcx().types.err);
1443 pub fn require_type_meets(&self,
1446 code: traits::ObligationCauseCode<'tcx>,
1447 bound: ty::BuiltinBound)
1449 self.register_builtin_bound(
1452 traits::ObligationCause::new(span, self.body_id, code));
1455 pub fn require_type_is_sized(&self,
1458 code: traits::ObligationCauseCode<'tcx>)
1460 self.require_type_meets(ty, span, code, ty::BoundSized);
1463 pub fn require_expr_have_sized_type(&self,
1465 code: traits::ObligationCauseCode<'tcx>)
1467 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1470 pub fn type_is_known_to_be_sized(&self,
1475 traits::type_known_to_meet_builtin_bound(self.infcx(),
1481 pub fn register_builtin_bound(&self,
1483 builtin_bound: ty::BuiltinBound,
1484 cause: traits::ObligationCause<'tcx>)
1486 self.inh.infcx.fulfillment_cx.borrow_mut()
1487 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1490 pub fn register_predicate(&self,
1491 obligation: traits::PredicateObligation<'tcx>)
1493 debug!("register_predicate({:?})",
1495 self.inh.infcx.fulfillment_cx
1497 .register_predicate_obligation(self.infcx(), obligation);
1500 pub fn to_ty(&self, ast_t: &ast::Ty) -> Ty<'tcx> {
1501 let t = ast_ty_to_ty(self, self, ast_t);
1503 let mut bounds_checker = wf::BoundsChecker::new(self,
1506 bounds_checker.check_ty(t, ast_t.span);
1511 pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
1512 match self.inh.tables.borrow().node_types.get(&ex.id) {
1515 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1521 /// Apply `adjustment` to the type of `expr`
1522 pub fn adjust_expr_ty(&self,
1524 adjustment: Option<&ty::AutoAdjustment<'tcx>>)
1527 let raw_ty = self.expr_ty(expr);
1528 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1529 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1530 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1531 self.inh.tables.borrow().method_map.get(&method_call)
1532 .map(|method| resolve_ty(method.ty))
1536 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1537 match self.inh.tables.borrow().node_types.get(&id) {
1539 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1541 self.tcx().sess.bug(
1542 &format!("no type for node {}: {} in fcx {}",
1543 id, self.tcx().map.node_to_string(id),
1549 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1550 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1551 // it changes when we upgrade the snapshot compiler
1552 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1553 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1557 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1560 pub fn opt_node_ty_substs<F>(&self,
1563 F: FnOnce(&ty::ItemSubsts<'tcx>),
1565 match self.inh.tables.borrow().item_substs.get(&id) {
1571 pub fn mk_subty(&self,
1572 a_is_expected: bool,
1573 origin: infer::TypeOrigin,
1576 -> Result<(), ty::TypeError<'tcx>> {
1577 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1580 pub fn mk_eqty(&self,
1581 a_is_expected: bool,
1582 origin: infer::TypeOrigin,
1585 -> Result<(), ty::TypeError<'tcx>> {
1586 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1589 pub fn mk_subr(&self,
1590 origin: infer::SubregionOrigin<'tcx>,
1593 infer::mk_subr(self.infcx(), origin, sub, sup)
1596 pub fn type_error_message<M>(&self,
1599 actual_ty: Ty<'tcx>,
1600 err: Option<&ty::TypeError<'tcx>>) where
1601 M: FnOnce(String) -> String,
1603 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1606 pub fn report_mismatched_types(&self,
1610 err: &ty::TypeError<'tcx>) {
1611 self.infcx().report_mismatched_types(sp, e, a, err)
1614 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1615 /// outlive the region `r`.
1616 pub fn register_region_obligation(&self,
1619 cause: traits::ObligationCause<'tcx>)
1621 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1622 fulfillment_cx.register_region_obligation(ty, region, cause);
1625 pub fn add_default_region_param_bounds(&self,
1626 substs: &Substs<'tcx>,
1629 for &ty in &substs.types {
1630 let default_bound = ty::ReScope(CodeExtent::from_node_id(expr.id));
1631 let cause = traits::ObligationCause::new(expr.span, self.body_id,
1632 traits::MiscObligation);
1633 self.register_region_obligation(ty, default_bound, cause);
1637 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1638 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1639 /// trait/region obligations.
1641 /// For example, if there is a function:
1644 /// fn foo<'a,T:'a>(...)
1647 /// and a reference:
1653 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1654 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1655 pub fn add_obligations_for_parameters(&self,
1656 cause: traits::ObligationCause<'tcx>,
1657 predicates: &ty::InstantiatedPredicates<'tcx>)
1659 assert!(!predicates.has_escaping_regions());
1661 debug!("add_obligations_for_parameters(predicates={:?})",
1664 for obligation in traits::predicates_for_generics(cause, predicates) {
1665 self.register_predicate(obligation);
1669 // Only for fields! Returns <none> for methods>
1670 // Indifferent to privacy flags
1671 pub fn lookup_field_ty(&self,
1673 class_id: ast::DefId,
1674 items: &[ty::FieldTy],
1675 fieldname: ast::Name,
1676 substs: &subst::Substs<'tcx>)
1679 let o_field = items.iter().find(|f| f.name == fieldname);
1680 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1681 .map(|t| self.normalize_associated_types_in(span, &t))
1684 pub fn lookup_tup_field_ty(&self,
1686 class_id: ast::DefId,
1687 items: &[ty::FieldTy],
1689 substs: &subst::Substs<'tcx>)
1692 let o_field = if idx < items.len() { Some(&items[idx]) } else { None };
1693 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1694 .map(|t| self.normalize_associated_types_in(span, &t))
1697 fn check_casts(&self) {
1698 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1699 for cast in deferred_cast_checks.drain(..) {
1704 fn select_all_obligations_and_apply_defaults(&self) {
1705 debug!("select_all_obligations_and_apply_defaults");
1707 self.select_obligations_where_possible();
1708 self.default_type_parameters();
1709 self.select_obligations_where_possible();
1712 fn select_all_obligations_or_error(&self) {
1713 debug!("select_all_obligations_or_error");
1715 // upvar inference should have ensured that all deferred call
1716 // resolutions are handled by now.
1717 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1719 self.select_all_obligations_and_apply_defaults();
1720 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1721 match fulfillment_cx.select_all_or_error(self.infcx()) {
1723 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1727 /// Select as many obligations as we can at present.
1728 fn select_obligations_where_possible(&self) {
1730 self.inh.infcx.fulfillment_cx
1732 .select_where_possible(self.infcx())
1735 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1739 /// Try to select any fcx obligation that we haven't tried yet, in an effort
1740 /// to improve inference. You could just call
1741 /// `select_obligations_where_possible` except that it leads to repeated
1743 fn select_new_obligations(&self) {
1745 self.inh.infcx.fulfillment_cx
1747 .select_new_obligations(self.infcx())
1750 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1756 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
1757 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1758 Some(self.base_object_lifetime_default(span))
1761 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1762 // RFC #599 specifies that object lifetime defaults take
1763 // precedence over other defaults. But within a fn body we
1764 // don't have a *default* region, rather we use inference to
1765 // find the *correct* region, which is strictly more general
1766 // (and anyway, within a fn body the right region may not even
1767 // be something the user can write explicitly, since it might
1768 // be some expression).
1769 self.infcx().next_region_var(infer::MiscVariable(span))
1772 fn anon_regions(&self, span: Span, count: usize)
1773 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1774 Ok((0..count).map(|_| {
1775 self.infcx().next_region_var(infer::MiscVariable(span))
1780 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1781 pub enum LvaluePreference {
1786 impl LvaluePreference {
1787 pub fn from_mutbl(m: ast::Mutability) -> Self {
1789 ast::MutMutable => PreferMutLvalue,
1790 ast::MutImmutable => NoPreference,
1795 /// Whether `autoderef` requires types to resolve.
1796 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1797 pub enum UnresolvedTypeAction {
1798 /// Produce an error and return `TyError` whenever a type cannot
1799 /// be resolved (i.e. it is `TyInfer`).
1801 /// Go on without emitting any errors, and return the unresolved
1802 /// type. Useful for probing, e.g. in coercions.
1806 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
1807 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
1809 /// Note: this method does not modify the adjustments table. The caller is responsible for
1810 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
1811 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
1814 opt_expr: Option<&ast::Expr>,
1815 unresolved_type_action: UnresolvedTypeAction,
1816 mut lvalue_pref: LvaluePreference,
1818 -> (Ty<'tcx>, usize, Option<T>)
1819 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
1821 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
1826 let mut t = base_ty;
1827 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
1828 let resolved_t = match unresolved_type_action {
1829 UnresolvedTypeAction::Error => {
1830 structurally_resolved_type(fcx, sp, t)
1832 UnresolvedTypeAction::Ignore => {
1833 // We can continue even when the type cannot be resolved
1834 // (i.e. it is an inference variable) because `Ty::builtin_deref`
1835 // and `try_overloaded_deref` both simply return `None`
1836 // in such a case without producing spurious errors.
1837 fcx.resolve_type_vars_if_possible(t)
1840 if resolved_t.references_error() {
1841 return (resolved_t, autoderefs, None);
1844 match should_stop(resolved_t, autoderefs) {
1845 Some(x) => return (resolved_t, autoderefs, Some(x)),
1849 // Otherwise, deref if type is derefable:
1850 let mt = match resolved_t.builtin_deref(false) {
1851 Some(mt) => Some(mt),
1854 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
1856 // Super subtle: it might seem as though we should
1857 // pass `opt_expr` to `try_overloaded_deref`, so that
1858 // the (implicit) autoref of using an overloaded deref
1859 // would get added to the adjustment table. However we
1860 // do not do that, because it's kind of a
1861 // "meta-adjustment" -- instead, we just leave it
1862 // unrecorded and know that there "will be" an
1863 // autoref. regionck and other bits of the code base,
1864 // when they encounter an overloaded autoderef, have
1865 // to do some reconstructive surgery. This is a pretty
1866 // complex mess that is begging for a proper MIR.
1867 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
1873 if mt.mutbl == ast::MutImmutable {
1874 lvalue_pref = NoPreference;
1877 None => return (resolved_t, autoderefs, None)
1881 // We've reached the recursion limit, error gracefully.
1882 span_err!(fcx.tcx().sess, sp, E0055,
1883 "reached the recursion limit while auto-dereferencing {:?}",
1885 (fcx.tcx().types.err, 0, None)
1888 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1890 method_call: Option<MethodCall>,
1891 base_expr: Option<&ast::Expr>,
1893 lvalue_pref: LvaluePreference)
1894 -> Option<ty::TypeAndMut<'tcx>>
1896 // Try DerefMut first, if preferred.
1897 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
1898 (PreferMutLvalue, Some(trait_did)) => {
1899 method::lookup_in_trait(fcx, span, base_expr,
1900 token::intern("deref_mut"), trait_did,
1906 // Otherwise, fall back to Deref.
1907 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
1908 (None, Some(trait_did)) => {
1909 method::lookup_in_trait(fcx, span, base_expr,
1910 token::intern("deref"), trait_did,
1913 (method, _) => method
1916 make_overloaded_lvalue_return_type(fcx, method_call, method)
1919 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
1920 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
1921 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
1922 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1923 method_call: Option<MethodCall>,
1924 method: Option<MethodCallee<'tcx>>)
1925 -> Option<ty::TypeAndMut<'tcx>>
1929 // extract method method return type, which will be &T;
1930 // all LB regions should have been instantiated during method lookup
1931 let ret_ty = method.ty.fn_ret();
1932 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
1934 if let Some(method_call) = method_call {
1935 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
1938 // method returns &T, but the type as visible to user is T, so deref
1939 ret_ty.builtin_deref(true)
1945 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1947 base_expr: &'tcx ast::Expr,
1950 lvalue_pref: LvaluePreference)
1951 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
1953 // FIXME(#18741) -- this is almost but not quite the same as the
1954 // autoderef that normal method probing does. They could likely be
1957 let (ty, autoderefs, final_mt) = autoderef(fcx,
1961 UnresolvedTypeAction::Error,
1964 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
1965 adj_ty, idx, false, lvalue_pref, idx_ty)
1968 if final_mt.is_some() {
1972 // After we have fully autoderef'd, if the resulting type is [T; n], then
1973 // do a final unsized coercion to yield [T].
1974 if let ty::TyArray(element_ty, _) = ty.sty {
1975 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
1976 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
1977 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
1983 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
1984 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
1985 /// This loop implements one step in that search; the autoderef loop is implemented by
1986 /// `lookup_indexing`.
1987 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1988 method_call: MethodCall,
1990 base_expr: &'tcx ast::Expr,
1991 adjusted_ty: Ty<'tcx>,
1994 lvalue_pref: LvaluePreference,
1996 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
1998 let tcx = fcx.tcx();
1999 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2000 autoderefs={}, unsize={}, index_ty={:?})",
2008 let input_ty = fcx.infcx().next_ty_var();
2010 // First, try built-in indexing.
2011 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2012 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2013 debug!("try_index_step: success, using built-in indexing");
2014 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2016 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2017 return Some((tcx.types.usize, ty));
2022 // Try `IndexMut` first, if preferred.
2023 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2024 (PreferMutLvalue, Some(trait_did)) => {
2025 method::lookup_in_trait_adjusted(fcx,
2028 token::intern("index_mut"),
2033 Some(vec![input_ty]))
2038 // Otherwise, fall back to `Index`.
2039 let method = match (method, tcx.lang_items.index_trait()) {
2040 (None, Some(trait_did)) => {
2041 method::lookup_in_trait_adjusted(fcx,
2044 token::intern("index"),
2049 Some(vec![input_ty]))
2051 (method, _) => method,
2054 // If some lookup succeeds, write callee into table and extract index/element
2055 // type from the method signature.
2056 // If some lookup succeeded, install method in table
2057 method.and_then(|method| {
2058 debug!("try_index_step: success, using overloaded indexing");
2059 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2060 map(|ret| (input_ty, ret.ty))
2064 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2066 method_fn_ty: Ty<'tcx>,
2067 callee_expr: &'tcx ast::Expr,
2068 args_no_rcvr: &'tcx [P<ast::Expr>],
2069 tuple_arguments: TupleArgumentsFlag,
2070 expected: Expectation<'tcx>)
2071 -> ty::FnOutput<'tcx> {
2072 if method_fn_ty.references_error() {
2073 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2075 let err_inputs = match tuple_arguments {
2076 DontTupleArguments => err_inputs,
2077 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2080 check_argument_types(fcx,
2087 ty::FnConverging(fcx.tcx().types.err)
2089 match method_fn_ty.sty {
2090 ty::TyBareFn(_, ref fty) => {
2091 // HACK(eddyb) ignore self in the definition (see above).
2092 let expected_arg_tys = expected_types_for_fn_args(fcx,
2096 &fty.sig.0.inputs[1..]);
2097 check_argument_types(fcx,
2099 &fty.sig.0.inputs[1..],
2100 &expected_arg_tys[..],
2107 fcx.tcx().sess.span_bug(callee_expr.span,
2108 "method without bare fn type");
2114 /// Generic function that factors out common logic from function calls, method calls and overloaded
2116 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2118 fn_inputs: &[Ty<'tcx>],
2119 expected_arg_tys: &[Ty<'tcx>],
2120 args: &'tcx [P<ast::Expr>],
2122 tuple_arguments: TupleArgumentsFlag) {
2123 let tcx = fcx.ccx.tcx;
2125 // Grab the argument types, supplying fresh type variables
2126 // if the wrong number of arguments were supplied
2127 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2133 let mut expected_arg_tys = expected_arg_tys;
2134 let expected_arg_count = fn_inputs.len();
2135 let formal_tys = if tuple_arguments == TupleArguments {
2136 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2137 match tuple_type.sty {
2138 ty::TyTuple(ref arg_types) => {
2139 if arg_types.len() != args.len() {
2140 span_err!(tcx.sess, sp, E0057,
2141 "this function takes {} parameter{} but {} parameter{} supplied",
2143 if arg_types.len() == 1 {""} else {"s"},
2145 if args.len() == 1 {" was"} else {"s were"});
2146 expected_arg_tys = &[];
2147 err_args(fcx.tcx(), args.len())
2149 expected_arg_tys = match expected_arg_tys.get(0) {
2150 Some(&ty) => match ty.sty {
2151 ty::TyTuple(ref tys) => &**tys,
2156 (*arg_types).clone()
2160 span_err!(tcx.sess, sp, E0059,
2161 "cannot use call notation; the first type parameter \
2162 for the function trait is neither a tuple nor unit");
2163 expected_arg_tys = &[];
2164 err_args(fcx.tcx(), args.len())
2167 } else if expected_arg_count == supplied_arg_count {
2169 } else if variadic {
2170 if supplied_arg_count >= expected_arg_count {
2173 span_err!(tcx.sess, sp, E0060,
2174 "this function takes at least {} parameter{} \
2175 but {} parameter{} supplied",
2177 if expected_arg_count == 1 {""} else {"s"},
2179 if supplied_arg_count == 1 {" was"} else {"s were"});
2180 expected_arg_tys = &[];
2181 err_args(fcx.tcx(), supplied_arg_count)
2184 span_err!(tcx.sess, sp, E0061,
2185 "this function takes {} parameter{} but {} parameter{} supplied",
2187 if expected_arg_count == 1 {""} else {"s"},
2189 if supplied_arg_count == 1 {" was"} else {"s were"});
2190 expected_arg_tys = &[];
2191 err_args(fcx.tcx(), supplied_arg_count)
2194 debug!("check_argument_types: formal_tys={:?}",
2195 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2197 // Check the arguments.
2198 // We do this in a pretty awful way: first we typecheck any arguments
2199 // that are not anonymous functions, then we typecheck the anonymous
2200 // functions. This is so that we have more information about the types
2201 // of arguments when we typecheck the functions. This isn't really the
2202 // right way to do this.
2203 let xs = [false, true];
2204 for check_blocks in &xs {
2205 let check_blocks = *check_blocks;
2206 debug!("check_blocks={}", check_blocks);
2208 // More awful hacks: before we check argument types, try to do
2209 // an "opportunistic" vtable resolution of any trait bounds on
2210 // the call. This helps coercions.
2212 fcx.select_new_obligations();
2215 // For variadic functions, we don't have a declared type for all of
2216 // the arguments hence we only do our usual type checking with
2217 // the arguments who's types we do know.
2218 let t = if variadic {
2220 } else if tuple_arguments == TupleArguments {
2225 for (i, arg) in args.iter().take(t).enumerate() {
2226 let is_block = match arg.node {
2227 ast::ExprClosure(..) => true,
2231 if is_block == check_blocks {
2232 debug!("checking the argument");
2233 let formal_ty = formal_tys[i];
2235 // The special-cased logic below has three functions:
2236 // 1. Provide as good of an expected type as possible.
2237 let expected = expected_arg_tys.get(i).map(|&ty| {
2238 Expectation::rvalue_hint(ty)
2241 check_expr_with_unifier(fcx, &**arg,
2242 expected.unwrap_or(ExpectHasType(formal_ty)),
2244 // 2. Coerce to the most detailed type that could be coerced
2245 // to, which is `expected_ty` if `rvalue_hint` returns an
2246 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2247 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2248 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2250 // 3. Relate the expected type and the formal one,
2251 // if the expected type was used for the coercion.
2252 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2258 // We also need to make sure we at least write the ty of the other
2259 // arguments which we skipped above.
2261 for arg in args.iter().skip(expected_arg_count) {
2262 check_expr(fcx, &**arg);
2264 // There are a few types which get autopromoted when passed via varargs
2265 // in C but we just error out instead and require explicit casts.
2266 let arg_ty = structurally_resolved_type(fcx, arg.span,
2267 fcx.expr_ty(&**arg));
2269 ty::TyFloat(ast::TyF32) => {
2270 fcx.type_error_message(arg.span,
2272 format!("can't pass an {} to variadic \
2273 function, cast to c_double", t)
2276 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2277 fcx.type_error_message(arg.span, |t| {
2278 format!("can't pass {} to variadic \
2279 function, cast to c_int",
2283 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2284 fcx.type_error_message(arg.span, |t| {
2285 format!("can't pass {} to variadic \
2286 function, cast to c_uint",
2296 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2297 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2298 (0..len).map(|_| tcx.types.err).collect()
2301 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2302 call_expr: &ast::Expr,
2303 output: ty::FnOutput<'tcx>) {
2304 fcx.write_ty(call_expr.id, match output {
2305 ty::FnConverging(output_ty) => output_ty,
2306 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2310 // AST fragment checking
2311 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2313 expected: Expectation<'tcx>)
2316 let tcx = fcx.ccx.tcx;
2319 ast::LitStr(..) => tcx.mk_static_str(),
2320 ast::LitBinary(ref v) => {
2321 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2322 tcx.mk_array(tcx.types.u8, v.len()))
2324 ast::LitByte(_) => tcx.types.u8,
2325 ast::LitChar(_) => tcx.types.char,
2326 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2327 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2328 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2329 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2331 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2332 ty::TyChar => Some(tcx.types.u8),
2333 ty::TyRawPtr(..) => Some(tcx.types.usize),
2334 ty::TyBareFn(..) => Some(tcx.types.usize),
2338 opt_ty.unwrap_or_else(
2339 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2341 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2342 ast::LitFloatUnsuffixed(_) => {
2343 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2345 ty::TyFloat(_) => Some(ty),
2349 opt_ty.unwrap_or_else(
2350 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2352 ast::LitBool(_) => tcx.types.bool
2356 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2357 expr: &'tcx ast::Expr,
2358 expected: Ty<'tcx>) {
2359 check_expr_with_unifier(
2360 fcx, expr, ExpectHasType(expected), NoPreference,
2361 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2364 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2365 expr: &'tcx ast::Expr,
2366 expected: Ty<'tcx>) {
2367 check_expr_with_unifier(
2368 fcx, expr, ExpectHasType(expected), NoPreference,
2369 || demand::coerce(fcx, expr.span, expected, expr));
2372 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx ast::Expr,
2373 expected: Ty<'tcx>) {
2374 check_expr_with_unifier(
2375 fcx, expr, ExpectHasType(expected), NoPreference,
2379 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2380 expr: &'tcx ast::Expr,
2381 expected: Expectation<'tcx>) {
2382 check_expr_with_unifier(
2383 fcx, expr, expected, NoPreference,
2387 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2388 expr: &'tcx ast::Expr,
2389 expected: Expectation<'tcx>,
2390 lvalue_pref: LvaluePreference)
2392 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2395 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr) {
2396 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2399 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr,
2400 lvalue_pref: LvaluePreference) {
2401 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2404 // determine the `self` type, using fresh variables for all variables
2405 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2406 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2408 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2409 span: Span, // (potential) receiver for this impl
2411 -> TypeAndSubsts<'tcx> {
2412 let tcx = fcx.tcx();
2414 let ity = tcx.lookup_item_type(did);
2415 let (n_tps, rps, raw_ty) =
2416 (ity.generics.types.len(subst::TypeSpace),
2417 ity.generics.regions.get_slice(subst::TypeSpace),
2420 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2421 let tps = fcx.inh.infcx.next_ty_vars(n_tps);
2422 let substs = subst::Substs::new_type(tps, rps);
2423 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2425 TypeAndSubsts { substs: substs, ty: substd_ty }
2428 /// Controls whether the arguments are tupled. This is used for the call
2431 /// Tupling means that all call-side arguments are packed into a tuple and
2432 /// passed as a single parameter. For example, if tupling is enabled, this
2435 /// fn f(x: (isize, isize))
2437 /// Can be called as:
2444 #[derive(Clone, Eq, PartialEq)]
2445 enum TupleArgumentsFlag {
2450 /// Unifies the return type with the expected type early, for more coercions
2451 /// and forward type information on the argument expressions.
2452 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2454 expected_ret: Expectation<'tcx>,
2455 formal_ret: ty::FnOutput<'tcx>,
2456 formal_args: &[Ty<'tcx>])
2458 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2459 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2460 fcx.infcx().commit_regions_if_ok(|| {
2461 // Attempt to apply a subtyping relationship between the formal
2462 // return type (likely containing type variables if the function
2463 // is polymorphic) and the expected return type.
2464 // No argument expectations are produced if unification fails.
2465 let origin = infer::Misc(call_span);
2466 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2467 // FIXME(#15760) can't use try! here, FromError doesn't default
2468 // to identity so the resulting type is not constrained.
2469 if let Err(e) = ures {
2473 // Record all the argument types, with the substitutions
2474 // produced from the above subtyping unification.
2475 Ok(formal_args.iter().map(|ty| {
2476 fcx.infcx().resolve_type_vars_if_possible(ty)
2482 }).unwrap_or(vec![]);
2483 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2484 formal_args, formal_ret,
2485 expected_args, expected_ret);
2490 /// If an expression has any sub-expressions that result in a type error,
2491 /// inspecting that expression's type with `ty.references_error()` will return
2492 /// true. Likewise, if an expression is known to diverge, inspecting its
2493 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2494 /// strict, _|_ can appear in the type of an expression that does not,
2495 /// itself, diverge: for example, fn() -> _|_.)
2496 /// Note that inspecting a type's structure *directly* may expose the fact
2497 /// that there are actually multiple representations for `TyError`, so avoid
2498 /// that when err needs to be handled differently.
2499 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2500 expr: &'tcx ast::Expr,
2501 expected: Expectation<'tcx>,
2502 lvalue_pref: LvaluePreference,
2506 debug!(">> typechecking: expr={:?} expected={:?}",
2509 // Checks a method call.
2510 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2511 expr: &'tcx ast::Expr,
2512 method_name: ast::SpannedIdent,
2513 args: &'tcx [P<ast::Expr>],
2515 expected: Expectation<'tcx>,
2516 lvalue_pref: LvaluePreference) {
2517 let rcvr = &*args[0];
2518 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2520 // no need to check for bot/err -- callee does that
2521 let expr_t = structurally_resolved_type(fcx,
2523 fcx.expr_ty(&*rcvr));
2525 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2526 let fn_ty = match method::lookup(fcx,
2528 method_name.node.name,
2534 let method_ty = method.ty;
2535 let method_call = MethodCall::expr(expr.id);
2536 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2540 method::report_error(fcx, method_name.span, expr_t,
2541 method_name.node.name, Some(rcvr), error);
2542 fcx.write_error(expr.id);
2547 // Call the generic checker.
2548 let ret_ty = check_method_argument_types(fcx,
2556 write_call(fcx, expr, ret_ty);
2559 // A generic function for checking the then and else in an if
2561 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2562 cond_expr: &'tcx ast::Expr,
2563 then_blk: &'tcx ast::Block,
2564 opt_else_expr: Option<&'tcx ast::Expr>,
2567 expected: Expectation<'tcx>) {
2568 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2570 let expected = expected.adjust_for_branches(fcx);
2571 check_block_with_expected(fcx, then_blk, expected);
2572 let then_ty = fcx.node_ty(then_blk.id);
2574 let branches_ty = match opt_else_expr {
2575 Some(ref else_expr) => {
2576 check_expr_with_expectation(fcx, &**else_expr, expected);
2577 let else_ty = fcx.expr_ty(&**else_expr);
2578 infer::common_supertype(fcx.infcx(),
2579 infer::IfExpression(sp),
2585 infer::common_supertype(fcx.infcx(),
2586 infer::IfExpressionWithNoElse(sp),
2593 let cond_ty = fcx.expr_ty(cond_expr);
2594 let if_ty = if cond_ty.references_error() {
2600 fcx.write_ty(id, if_ty);
2603 // Check field access expressions
2604 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2605 expr: &'tcx ast::Expr,
2606 lvalue_pref: LvaluePreference,
2607 base: &'tcx ast::Expr,
2608 field: &ast::SpannedIdent) {
2609 let tcx = fcx.ccx.tcx;
2610 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2611 let expr_t = structurally_resolved_type(fcx, expr.span,
2613 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2614 let (_, autoderefs, field_ty) = autoderef(fcx,
2618 UnresolvedTypeAction::Error,
2622 ty::TyStruct(base_id, substs) => {
2623 debug!("struct named {:?}", base_t);
2624 let fields = tcx.lookup_struct_fields(base_id);
2625 fcx.lookup_field_ty(expr.span, base_id, &fields[..],
2626 field.node.name, &(*substs))
2633 fcx.write_ty(expr.id, field_ty);
2634 fcx.write_autoderef_adjustment(base.id, autoderefs);
2640 if method::exists(fcx, field.span, field.node.name, expr_t, expr.id) {
2641 fcx.type_error_message(
2644 format!("attempted to take value of method `{}` on type \
2645 `{}`", token::get_ident(field.node), actual)
2649 tcx.sess.fileline_help(field.span,
2650 "maybe a `()` to call it is missing? \
2651 If not, try an anonymous function");
2653 fcx.type_error_message(
2656 format!("attempted access of field `{}` on \
2657 type `{}`, but no field with that \
2659 token::get_ident(field.node),
2663 if let ty::TyStruct(did, _) = expr_t.sty {
2664 suggest_field_names(did, field, tcx, vec![]);
2668 fcx.write_error(expr.id);
2671 // displays hints about the closest matches in field names
2672 fn suggest_field_names<'tcx>(id : DefId,
2673 field : &ast::SpannedIdent,
2674 tcx : &ty::ctxt<'tcx>,
2676 let ident = token::get_ident(field.node);
2678 // only find fits with at least one matching letter
2679 let mut best_dist = name.len();
2680 let fields = tcx.lookup_struct_fields(id);
2681 let mut best = None;
2682 for elem in &fields {
2683 let n = elem.name.as_str();
2684 // ignore already set fields
2685 if skip.iter().any(|&x| x == n) {
2688 // ignore private fields from non-local crates
2689 if id.krate != ast::LOCAL_CRATE && elem.vis != Visibility::Public {
2692 let dist = lev_distance(n, name);
2693 if dist < best_dist {
2698 if let Some(n) = best {
2699 tcx.sess.span_help(field.span,
2700 &format!("did you mean `{}`?", n));
2704 // Check tuple index expressions
2705 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2706 expr: &'tcx ast::Expr,
2707 lvalue_pref: LvaluePreference,
2708 base: &'tcx ast::Expr,
2709 idx: codemap::Spanned<usize>) {
2710 let tcx = fcx.ccx.tcx;
2711 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2712 let expr_t = structurally_resolved_type(fcx, expr.span,
2714 let mut tuple_like = false;
2715 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2716 let (_, autoderefs, field_ty) = autoderef(fcx,
2720 UnresolvedTypeAction::Error,
2724 ty::TyStruct(base_id, substs) => {
2725 tuple_like = tcx.is_tuple_struct(base_id);
2727 debug!("tuple struct named {:?}", base_t);
2728 let fields = tcx.lookup_struct_fields(base_id);
2729 fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
2730 idx.node, &(*substs))
2735 ty::TyTuple(ref v) => {
2737 if idx.node < v.len() { Some(v[idx.node]) } else { None }
2744 fcx.write_ty(expr.id, field_ty);
2745 fcx.write_autoderef_adjustment(base.id, autoderefs);
2750 fcx.type_error_message(
2754 format!("attempted out-of-bounds tuple index `{}` on \
2759 format!("attempted tuple index `{}` on type `{}`, but the \
2760 type was not a tuple or tuple struct",
2767 fcx.write_error(expr.id);
2770 fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2771 struct_ty: Ty<'tcx>,
2773 class_id: ast::DefId,
2774 node_id: ast::NodeId,
2775 substitutions: &'tcx subst::Substs<'tcx>,
2776 field_types: &[ty::FieldTy],
2777 ast_fields: &'tcx [ast::Field],
2778 check_completeness: bool,
2779 enum_id_opt: Option<ast::DefId>) {
2780 let tcx = fcx.ccx.tcx;
2782 let mut class_field_map = FnvHashMap();
2783 let mut fields_found = 0;
2784 for field in field_types {
2785 class_field_map.insert(field.name, (field.id, false));
2788 let mut error_happened = false;
2790 // Typecheck each field.
2791 for field in ast_fields {
2792 let mut expected_field_type = tcx.types.err;
2794 let pair = class_field_map.get(&field.ident.node.name).cloned();
2797 fcx.type_error_message(
2799 |actual| match enum_id_opt {
2801 let variant_type = tcx.enum_variant_with_id(enum_id,
2803 format!("struct variant `{}::{}` has no field named `{}`",
2804 actual, variant_type.name.as_str(),
2805 token::get_ident(field.ident.node))
2808 format!("structure `{}` has no field named `{}`",
2810 token::get_ident(field.ident.node))
2815 // prevent all specified fields from being suggested
2816 let skip_fields = ast_fields.iter().map(|ref x| x.ident.node.name.as_str());
2817 let actual_id = match enum_id_opt {
2818 Some(_) => class_id,
2819 None => struct_ty.ty_to_def_id().unwrap()
2821 suggest_field_names(actual_id, &field.ident, tcx, skip_fields.collect());
2822 error_happened = true;
2824 Some((_, true)) => {
2825 span_err!(fcx.tcx().sess, field.ident.span, E0062,
2826 "field `{}` specified more than once",
2827 token::get_ident(field.ident.node));
2828 error_happened = true;
2830 Some((field_id, false)) => {
2831 expected_field_type =
2832 tcx.lookup_field_type(class_id, field_id, substitutions);
2833 expected_field_type =
2834 fcx.normalize_associated_types_in(
2835 field.span, &expected_field_type);
2836 class_field_map.insert(
2837 field.ident.node.name, (field_id, true));
2842 // Make sure to give a type to the field even if there's
2843 // an error, so we can continue typechecking
2844 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
2848 fcx.write_error(node_id);
2851 if check_completeness && !error_happened {
2852 // Make sure the programmer specified all the fields.
2853 assert!(fields_found <= field_types.len());
2854 if fields_found < field_types.len() {
2855 let mut missing_fields = Vec::new();
2856 for class_field in field_types {
2857 let name = class_field.name;
2858 let (_, seen) = *class_field_map.get(&name).unwrap();
2860 missing_fields.push(
2861 format!("`{}`", &token::get_name(name)))
2865 span_err!(tcx.sess, span, E0063,
2866 "missing field{}: {}",
2867 if missing_fields.len() == 1 {""} else {"s"},
2868 missing_fields.join(", "));
2872 if !error_happened {
2873 fcx.write_ty(node_id, fcx.ccx.tcx.mk_struct(class_id, substitutions));
2877 fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2879 span: codemap::Span,
2880 class_id: ast::DefId,
2881 fields: &'tcx [ast::Field],
2882 base_expr: Option<&'tcx ast::Expr>) {
2883 let tcx = fcx.ccx.tcx;
2885 // Generate the struct type.
2887 ty: mut struct_type,
2888 substs: struct_substs
2889 } = fcx.instantiate_type(span, class_id);
2891 // Look up and check the fields.
2892 let class_fields = tcx.lookup_struct_fields(class_id);
2893 check_struct_or_variant_fields(fcx,
2898 fcx.ccx.tcx.mk_substs(struct_substs),
2901 base_expr.is_none(),
2903 if fcx.node_ty(id).references_error() {
2904 struct_type = tcx.types.err;
2907 // Check the base expression if necessary.
2910 Some(base_expr) => {
2911 check_expr_has_type(fcx, &*base_expr, struct_type);
2915 // Write in the resulting type.
2916 fcx.write_ty(id, struct_type);
2919 fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2921 span: codemap::Span,
2922 enum_id: ast::DefId,
2923 variant_id: ast::DefId,
2924 fields: &'tcx [ast::Field]) {
2925 let tcx = fcx.ccx.tcx;
2927 // Look up the number of type parameters and the raw type, and
2928 // determine whether the enum is region-parameterized.
2931 substs: substitutions
2932 } = fcx.instantiate_type(span, enum_id);
2934 // Look up and check the enum variant fields.
2935 let variant_fields = tcx.lookup_struct_fields(variant_id);
2936 check_struct_or_variant_fields(fcx,
2941 fcx.ccx.tcx.mk_substs(substitutions),
2942 &variant_fields[..],
2946 fcx.write_ty(id, enum_type);
2949 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2951 fields: &'tcx [ast::Field],
2952 base_expr: &'tcx Option<P<ast::Expr>>) {
2953 // Make sure to still write the types
2954 // otherwise we might ICE
2955 fcx.write_error(id);
2956 for field in fields {
2957 check_expr(fcx, &*field.expr);
2960 Some(ref base) => check_expr(fcx, &**base),
2965 type ExprCheckerWithTy = fn(&FnCtxt, &ast::Expr, Ty);
2967 let tcx = fcx.ccx.tcx;
2970 ast::ExprBox(ref opt_place, ref subexpr) => {
2971 opt_place.as_ref().map(|place|check_expr(fcx, &**place));
2972 check_expr(fcx, &**subexpr);
2974 let mut checked = false;
2975 opt_place.as_ref().map(|place| match place.node {
2976 ast::ExprPath(None, ref path) => {
2977 // FIXME(pcwalton): For now we hardcode the only permissible
2978 // place: the exchange heap.
2979 let definition = lookup_full_def(tcx, path.span, place.id);
2980 let def_id = definition.def_id();
2981 let referent_ty = fcx.expr_ty(&**subexpr);
2982 if tcx.lang_items.exchange_heap() == Some(def_id) {
2983 fcx.write_ty(id, tcx.mk_box(referent_ty));
2991 span_err!(tcx.sess, expr.span, E0066,
2992 "only the exchange heap is currently supported");
2993 fcx.write_ty(id, tcx.types.err);
2997 ast::ExprLit(ref lit) => {
2998 let typ = check_lit(fcx, &**lit, expected);
2999 fcx.write_ty(id, typ);
3001 ast::ExprBinary(op, ref lhs, ref rhs) => {
3002 op::check_binop(fcx, expr, op, lhs, rhs);
3004 ast::ExprAssignOp(op, ref lhs, ref rhs) => {
3005 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3007 ast::ExprUnary(unop, ref oprnd) => {
3008 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3010 ast::UnUniq => match ty.sty {
3012 Expectation::rvalue_hint(ty)
3018 ast::UnNot | ast::UnNeg => {
3026 let lvalue_pref = match unop {
3027 ast::UnDeref => lvalue_pref,
3030 check_expr_with_expectation_and_lvalue_pref(
3031 fcx, &**oprnd, expected_inner, lvalue_pref);
3032 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3034 if !oprnd_t.references_error() {
3037 oprnd_t = tcx.mk_box(oprnd_t);
3040 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3041 oprnd_t = match oprnd_t.builtin_deref(true) {
3043 None => match try_overloaded_deref(fcx, expr.span,
3044 Some(MethodCall::expr(expr.id)),
3045 Some(&**oprnd), oprnd_t, lvalue_pref) {
3048 fcx.type_error_message(expr.span, |actual| {
3049 format!("type `{}` cannot be \
3050 dereferenced", actual)
3058 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3060 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3061 oprnd_t = op::check_user_unop(fcx, "!", "not",
3062 tcx.lang_items.not_trait(),
3063 expr, &**oprnd, oprnd_t, unop);
3067 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3069 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3070 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3071 tcx.lang_items.neg_trait(),
3072 expr, &**oprnd, oprnd_t, unop);
3077 fcx.write_ty(id, oprnd_t);
3079 ast::ExprAddrOf(mutbl, ref oprnd) => {
3080 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3082 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3083 if fcx.tcx().expr_is_lval(&**oprnd) {
3084 // Lvalues may legitimately have unsized types.
3085 // For example, dereferences of a fat pointer and
3086 // the last field of a struct can be unsized.
3087 ExpectHasType(mt.ty)
3089 Expectation::rvalue_hint(mt.ty)
3095 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3096 check_expr_with_expectation_and_lvalue_pref(fcx,
3101 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3102 let oprnd_t = if tm.ty.references_error() {
3105 // Note: at this point, we cannot say what the best lifetime
3106 // is to use for resulting pointer. We want to use the
3107 // shortest lifetime possible so as to avoid spurious borrowck
3108 // errors. Moreover, the longest lifetime will depend on the
3109 // precise details of the value whose address is being taken
3110 // (and how long it is valid), which we don't know yet until type
3111 // inference is complete.
3113 // Therefore, here we simply generate a region variable. The
3114 // region inferencer will then select the ultimate value.
3115 // Finally, borrowck is charged with guaranteeing that the
3116 // value whose address was taken can actually be made to live
3117 // as long as it needs to live.
3118 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3119 tcx.mk_ref(tcx.mk_region(region), tm)
3121 fcx.write_ty(id, oprnd_t);
3123 ast::ExprPath(ref maybe_qself, ref path) => {
3124 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3125 fcx.to_ty(&qself.ty)
3128 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3130 } else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
3131 // Create some fake resolution that can't possibly be a type.
3132 def::PathResolution {
3133 base_def: def::DefMod(local_def(ast::CRATE_NODE_ID)),
3134 last_private: LastMod(AllPublic),
3135 depth: path.segments.len()
3138 tcx.sess.span_bug(expr.span,
3139 &format!("unbound path {:?}", expr))
3142 if let Some((opt_ty, segments, def)) =
3143 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3144 expr.span, expr.id) {
3145 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3148 instantiate_path(fcx,
3158 // We always require that the type provided as the value for
3159 // a type parameter outlives the moment of instantiation.
3160 constrain_path_type_parameters(fcx, expr);
3162 ast::ExprInlineAsm(ref ia) => {
3163 for &(_, ref input) in &ia.inputs {
3164 check_expr(fcx, &**input);
3166 for &(_, ref out, _) in &ia.outputs {
3167 check_expr(fcx, &**out);
3171 ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
3172 ast::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3173 ast::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3174 ast::ExprRet(ref expr_opt) => {
3176 ty::FnConverging(result_type) => {
3179 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3180 result_type, fcx.tcx().mk_nil()) {
3181 span_err!(tcx.sess, expr.span, E0069,
3182 "`return;` in a function whose return type is \
3186 check_expr_coercable_to_type(fcx, &**e, result_type);
3190 ty::FnDiverging => {
3191 if let Some(ref e) = *expr_opt {
3192 check_expr(fcx, &**e);
3194 span_err!(tcx.sess, expr.span, E0166,
3195 "`return` in a function declared as diverging");
3198 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3200 ast::ExprParen(ref a) => {
3201 check_expr_with_expectation_and_lvalue_pref(fcx,
3205 fcx.write_ty(id, fcx.expr_ty(&**a));
3207 ast::ExprAssign(ref lhs, ref rhs) => {
3208 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3210 let tcx = fcx.tcx();
3211 if !tcx.expr_is_lval(&**lhs) {
3212 span_err!(tcx.sess, expr.span, E0070,
3213 "illegal left-hand side expression");
3216 let lhs_ty = fcx.expr_ty(&**lhs);
3217 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3218 let rhs_ty = fcx.expr_ty(&**rhs);
3220 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3222 if lhs_ty.references_error() || rhs_ty.references_error() {
3223 fcx.write_error(id);
3228 ast::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3229 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3230 id, expr.span, expected);
3232 ast::ExprIfLet(..) => {
3233 tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
3235 ast::ExprWhile(ref cond, ref body, _) => {
3236 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3237 check_block_no_value(fcx, &**body);
3238 let cond_ty = fcx.expr_ty(&**cond);
3239 let body_ty = fcx.node_ty(body.id);
3240 if cond_ty.references_error() || body_ty.references_error() {
3241 fcx.write_error(id);
3247 ast::ExprWhileLet(..) => {
3248 tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
3250 ast::ExprForLoop(..) => {
3251 tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
3253 ast::ExprLoop(ref body, _) => {
3254 check_block_no_value(fcx, &**body);
3255 if !may_break(tcx, expr.id, &**body) {
3256 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3261 ast::ExprMatch(ref discrim, ref arms, match_src) => {
3262 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3264 ast::ExprClosure(capture, ref decl, ref body) => {
3265 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3267 ast::ExprBlock(ref b) => {
3268 check_block_with_expected(fcx, &**b, expected);
3269 fcx.write_ty(id, fcx.node_ty(b.id));
3271 ast::ExprCall(ref callee, ref args) => {
3272 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3274 ast::ExprMethodCall(ident, ref tps, ref args) => {
3275 check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref);
3276 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3277 let args_err = arg_tys.fold(false,
3279 rest_err || a.references_error()});
3281 fcx.write_error(id);
3284 ast::ExprCast(ref e, ref t) => {
3285 if let ast::TyFixedLengthVec(_, ref count_expr) = t.node {
3286 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3289 // Find the type of `e`. Supply hints based on the type we are casting to,
3291 let t_cast = fcx.to_ty(t);
3292 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3293 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3294 let t_expr = fcx.expr_ty(e);
3296 // Eagerly check for some obvious errors.
3297 if t_expr.references_error() {
3298 fcx.write_error(id);
3299 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3300 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3302 // Write a type for the whole expression, assuming everything is going
3304 fcx.write_ty(id, t_cast);
3306 // Defer other checks until we're done type checking.
3307 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3308 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3309 deferred_cast_checks.push(cast_check);
3312 ast::ExprVec(ref args) => {
3313 let uty = expected.to_option(fcx).and_then(|uty| {
3315 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3320 let typ = match uty {
3323 check_expr_coercable_to_type(fcx, &**e, uty);
3328 let t: Ty = fcx.infcx().next_ty_var();
3330 check_expr_has_type(fcx, &**e, t);
3335 let typ = tcx.mk_array(typ, args.len());
3336 fcx.write_ty(id, typ);
3338 ast::ExprRepeat(ref element, ref count_expr) => {
3339 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3340 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3342 let uty = match expected {
3343 ExpectHasType(uty) => {
3345 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3352 let (element_ty, t) = match uty {
3354 check_expr_coercable_to_type(fcx, &**element, uty);
3358 let t: Ty = fcx.infcx().next_ty_var();
3359 check_expr_has_type(fcx, &**element, t);
3360 (fcx.expr_ty(&**element), t)
3365 // For [foo, ..n] where n > 1, `foo` must have
3367 fcx.require_type_meets(
3374 if element_ty.references_error() {
3375 fcx.write_error(id);
3377 let t = tcx.mk_array(t, count);
3378 fcx.write_ty(id, t);
3381 ast::ExprTup(ref elts) => {
3382 let flds = expected.only_has_type(fcx).and_then(|ty| {
3384 ty::TyTuple(ref flds) => Some(&flds[..]),
3388 let mut err_field = false;
3390 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3391 let t = match flds {
3392 Some(ref fs) if i < fs.len() => {
3394 check_expr_coercable_to_type(fcx, &**e, ety);
3398 check_expr_with_expectation(fcx, &**e, NoExpectation);
3402 err_field = err_field || t.references_error();
3406 fcx.write_error(id);
3408 let typ = tcx.mk_tup(elt_ts);
3409 fcx.write_ty(id, typ);
3412 ast::ExprStruct(ref path, ref fields, ref base_expr) => {
3413 // Resolve the path.
3414 let def = lookup_full_def(tcx, path.span, id);
3415 let struct_id = match def {
3416 def::DefVariant(enum_id, variant_id, true) => {
3417 if let &Some(ref base_expr) = base_expr {
3418 span_err!(tcx.sess, base_expr.span, E0436,
3419 "functional record update syntax requires a struct");
3420 fcx.write_error(base_expr.id);
3422 check_struct_enum_variant(fcx, id, expr.span, enum_id,
3423 variant_id, &fields[..]);
3426 def::DefTrait(def_id) => {
3427 span_err!(tcx.sess, path.span, E0159,
3428 "use of trait `{}` as a struct constructor",
3429 pprust::path_to_string(path));
3430 check_struct_fields_on_error(fcx,
3437 // Verify that this was actually a struct.
3438 let typ = fcx.ccx.tcx.lookup_item_type(def.def_id());
3440 ty::TyStruct(struct_did, _) => {
3441 check_struct_constructor(fcx,
3446 base_expr.as_ref().map(|e| &**e));
3449 span_err!(tcx.sess, path.span, E0071,
3450 "`{}` does not name a structure",
3451 pprust::path_to_string(path));
3452 check_struct_fields_on_error(fcx,
3463 // Turn the path into a type and verify that that type unifies with
3464 // the resulting structure type. This is needed to handle type
3465 // parameters correctly.
3466 let actual_structure_type = fcx.expr_ty(&*expr);
3467 if !actual_structure_type.references_error() {
3468 let type_and_substs = fcx.instantiate_struct_literal_ty(struct_id, path);
3469 match fcx.mk_subty(false,
3470 infer::Misc(path.span),
3471 actual_structure_type,
3472 type_and_substs.ty) {
3474 Err(type_error) => {
3475 span_err!(fcx.tcx().sess, path.span, E0235,
3476 "structure constructor specifies a \
3477 structure of type `{}`, but this \
3478 structure has type `{}`: {}",
3480 .ty_to_string(type_and_substs.ty),
3483 actual_structure_type),
3485 tcx.note_and_explain_type_err(&type_error, path.span);
3490 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3492 ast::ExprField(ref base, ref field) => {
3493 check_field(fcx, expr, lvalue_pref, &**base, field);
3495 ast::ExprTupField(ref base, idx) => {
3496 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3498 ast::ExprIndex(ref base, ref idx) => {
3499 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3500 check_expr(fcx, &**idx);
3502 let base_t = fcx.expr_ty(&**base);
3503 let idx_t = fcx.expr_ty(&**idx);
3505 if base_t.references_error() {
3506 fcx.write_ty(id, base_t);
3507 } else if idx_t.references_error() {
3508 fcx.write_ty(id, idx_t);
3510 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3511 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3512 Some((index_ty, element_ty)) => {
3513 let idx_expr_ty = fcx.expr_ty(idx);
3514 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3515 fcx.write_ty(id, element_ty);
3518 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3519 fcx.type_error_message(
3522 format!("cannot index a value of type `{}`",
3527 fcx.write_ty(id, fcx.tcx().types.err);
3532 ast::ExprRange(ref start, ref end) => {
3533 let t_start = start.as_ref().map(|e| {
3534 check_expr(fcx, &**e);
3537 let t_end = end.as_ref().map(|e| {
3538 check_expr(fcx, &**e);
3542 let idx_type = match (t_start, t_end) {
3543 (Some(ty), None) | (None, Some(ty)) => {
3546 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3547 t_end.references_error()) => {
3548 Some(fcx.tcx().types.err)
3550 (Some(t_start), Some(t_end)) => {
3551 Some(infer::common_supertype(fcx.infcx(),
3552 infer::RangeExpression(expr.span),
3560 // Note that we don't check the type of start/end satisfy any
3561 // bounds because right now the range structs do not have any. If we add
3562 // some bounds, then we'll need to check `t_start` against them here.
3564 let range_type = match idx_type {
3565 Some(idx_type) if idx_type.references_error() => {
3569 // Find the did from the appropriate lang item.
3570 let did = match (start, end) {
3571 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3572 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3573 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3575 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3579 if let Some(did) = did {
3580 let predicates = tcx.lookup_predicates(did);
3581 let substs = Substs::new_type(vec![idx_type], vec![]);
3582 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3583 fcx.add_obligations_for_parameters(
3584 traits::ObligationCause::new(expr.span,
3586 traits::ItemObligation(did)),
3589 tcx.mk_struct(did, tcx.mk_substs(substs))
3591 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3596 // Neither start nor end => RangeFull
3597 if let Some(did) = tcx.lang_items.range_full_struct() {
3598 let substs = Substs::new_type(vec![], vec![]);
3599 tcx.mk_struct(did, tcx.mk_substs(substs))
3601 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3607 fcx.write_ty(id, range_type);
3612 debug!("type of expr({}) {} is...", expr.id,
3613 syntax::print::pprust::expr_to_string(expr));
3614 debug!("... {:?}, expected is {:?}",
3621 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3622 path_res: def::PathResolution,
3623 opt_self_ty: Option<Ty<'tcx>>,
3624 path: &'a ast::Path,
3626 node_id: ast::NodeId)
3627 -> Option<(Option<Ty<'tcx>>,
3628 &'a [ast::PathSegment],
3632 // Associated constants can't depend on generic types.
3633 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3637 node_id: ast::NodeId) -> bool {
3639 def::DefAssociatedConst(..) => {
3640 if ty.has_param_types() || ty.has_self_ty() {
3641 span_err!(fcx.sess(), span, E0329,
3642 "Associated consts cannot depend \
3643 on type parameters or Self.");
3644 fcx.write_error(node_id);
3653 // If fully resolved already, we don't have to do anything.
3654 if path_res.depth == 0 {
3655 if let Some(ty) = opt_self_ty {
3656 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3661 Some((opt_self_ty, &path.segments, path_res.base_def))
3663 let mut def = path_res.base_def;
3664 let ty_segments = path.segments.split_last().unwrap().1;
3665 let base_ty_end = path.segments.len() - path_res.depth;
3666 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3667 PathParamMode::Optional,
3670 &ty_segments[..base_ty_end],
3671 &ty_segments[base_ty_end..]);
3672 let item_segment = path.segments.last().unwrap();
3673 let item_name = item_segment.identifier.name;
3674 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3676 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3679 // Write back the new resolution.
3680 fcx.ccx.tcx.def_map.borrow_mut()
3681 .insert(node_id, def::PathResolution {
3683 last_private: path_res.last_private.or(lp),
3686 Some((Some(ty), slice::ref_slice(item_segment), def))
3689 method::report_error(fcx, span, ty,
3690 item_name, None, error);
3691 fcx.write_error(node_id);
3698 fn constrain_path_type_parameters(fcx: &FnCtxt,
3701 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3702 fcx.add_default_region_param_bounds(&item_substs.substs, expr);
3706 impl<'tcx> Expectation<'tcx> {
3707 /// Provide an expectation for an rvalue expression given an *optional*
3708 /// hint, which is not required for type safety (the resulting type might
3709 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3710 /// is useful in determining the concrete type.
3712 /// The primary use case is where the expected type is a fat pointer,
3713 /// like `&[isize]`. For example, consider the following statement:
3715 /// let x: &[isize] = &[1, 2, 3];
3717 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3718 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3719 /// expectation `ExpectHasType([isize])`, that would be too strong --
3720 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3721 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3722 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3723 /// which still is useful, because it informs integer literals and the like.
3724 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3725 /// for examples of where this comes up,.
3726 fn rvalue_hint(ty: Ty<'tcx>) -> Expectation<'tcx> {
3728 ty::TySlice(_) | ty::TyTrait(..) => {
3729 ExpectRvalueLikeUnsized(ty)
3731 _ => ExpectHasType(ty)
3735 // Resolves `expected` by a single level if it is a variable. If
3736 // there is no expected type or resolution is not possible (e.g.,
3737 // no constraints yet present), just returns `None`.
3738 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3743 ExpectCastableToType(t) => {
3744 ExpectCastableToType(
3745 fcx.infcx().resolve_type_vars_if_possible(&t))
3747 ExpectHasType(t) => {
3749 fcx.infcx().resolve_type_vars_if_possible(&t))
3751 ExpectRvalueLikeUnsized(t) => {
3752 ExpectRvalueLikeUnsized(
3753 fcx.infcx().resolve_type_vars_if_possible(&t))
3758 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3759 match self.resolve(fcx) {
3760 NoExpectation => None,
3761 ExpectCastableToType(ty) |
3763 ExpectRvalueLikeUnsized(ty) => Some(ty),
3767 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3768 match self.resolve(fcx) {
3769 ExpectHasType(ty) => Some(ty),
3775 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3776 local: &'tcx ast::Local,
3777 init: &'tcx ast::Expr)
3779 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3781 let local_ty = fcx.local_ty(init.span, local.id);
3782 if let Some(m) = ref_bindings {
3783 // Somewhat subtle: if we have a `ref` binding in the pattern,
3784 // we want to avoid introducing coercions for the RHS. This is
3785 // both because it helps preserve sanity and, in the case of
3786 // ref mut, for soundness (issue #23116). In particular, in
3787 // the latter case, we need to be clear that the type of the
3788 // referent for the reference that results is *equal to* the
3789 // type of the lvalue it is referencing, and not some
3790 // supertype thereof.
3791 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3792 let init_ty = fcx.expr_ty(init);
3793 demand::eqtype(fcx, init.span, init_ty, local_ty);
3795 check_expr_coercable_to_type(fcx, init, local_ty)
3799 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local) {
3800 let tcx = fcx.ccx.tcx;
3802 let t = fcx.local_ty(local.span, local.id);
3803 fcx.write_ty(local.id, t);
3805 if let Some(ref init) = local.init {
3806 check_decl_initializer(fcx, local, &**init);
3807 let init_ty = fcx.expr_ty(&**init);
3808 if init_ty.references_error() {
3809 fcx.write_ty(local.id, init_ty);
3813 let pcx = pat_ctxt {
3815 map: pat_id_map(&tcx.def_map, &*local.pat),
3817 _match::check_pat(&pcx, &*local.pat, t);
3818 let pat_ty = fcx.node_ty(local.pat.id);
3819 if pat_ty.references_error() {
3820 fcx.write_ty(local.id, pat_ty);
3824 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
3826 let mut saw_bot = false;
3827 let mut saw_err = false;
3829 ast::StmtDecl(ref decl, id) => {
3832 ast::DeclLocal(ref l) => {
3833 check_decl_local(fcx, &**l);
3834 let l_t = fcx.node_ty(l.id);
3835 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3836 saw_err = saw_err || l_t.references_error();
3838 ast::DeclItem(_) => {/* ignore for now */ }
3841 ast::StmtExpr(ref expr, id) => {
3843 // Check with expected type of ()
3844 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3845 let expr_ty = fcx.expr_ty(&**expr);
3846 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3847 saw_err = saw_err || expr_ty.references_error();
3849 ast::StmtSemi(ref expr, id) => {
3851 check_expr(fcx, &**expr);
3852 let expr_ty = fcx.expr_ty(&**expr);
3853 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3854 saw_err |= expr_ty.references_error();
3856 ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro")
3859 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3862 fcx.write_error(node_id);
3865 fcx.write_nil(node_id)
3869 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) {
3870 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3871 let blkty = fcx.node_ty(blk.id);
3872 if blkty.references_error() {
3873 fcx.write_error(blk.id);
3875 let nilty = fcx.tcx().mk_nil();
3876 demand::suptype(fcx, blk.span, nilty, blkty);
3880 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3881 blk: &'tcx ast::Block,
3882 expected: Expectation<'tcx>) {
3884 let mut fcx_ps = fcx.ps.borrow_mut();
3885 let unsafety_state = fcx_ps.recurse(blk);
3886 replace(&mut *fcx_ps, unsafety_state)
3889 let mut warned = false;
3890 let mut any_diverges = false;
3891 let mut any_err = false;
3892 for s in &blk.stmts {
3893 check_stmt(fcx, &**s);
3894 let s_id = ast_util::stmt_id(&**s);
3895 let s_ty = fcx.node_ty(s_id);
3896 if any_diverges && !warned && match s.node {
3897 ast::StmtDecl(ref decl, _) => {
3899 ast::DeclLocal(_) => true,
3903 ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
3909 .add_lint(lint::builtin::UNREACHABLE_CODE,
3912 "unreachable statement".to_string());
3915 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3916 any_err = any_err || s_ty.references_error();
3919 None => if any_err {
3920 fcx.write_error(blk.id);
3921 } else if any_diverges {
3922 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3924 fcx.write_nil(blk.id);
3927 if any_diverges && !warned {
3931 .add_lint(lint::builtin::UNREACHABLE_CODE,
3934 "unreachable expression".to_string());
3936 let ety = match expected {
3937 ExpectHasType(ety) => {
3938 check_expr_coercable_to_type(fcx, &**e, ety);
3942 check_expr_with_expectation(fcx, &**e, expected);
3948 fcx.write_error(blk.id);
3949 } else if any_diverges {
3950 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3952 fcx.write_ty(blk.id, ety);
3957 *fcx.ps.borrow_mut() = prev;
3960 /// Checks a constant appearing in a type. At the moment this is just the
3961 /// length expression in a fixed-length vector, but someday it might be
3962 /// extended to type-level numeric literals.
3963 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3964 expr: &'tcx ast::Expr,
3965 expected_type: Ty<'tcx>) {
3966 let tables = RefCell::new(ty::Tables::empty());
3967 let inh = static_inherited_fields(ccx, &tables);
3968 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3969 check_const_with_ty(&fcx, expr.span, expr, expected_type);
3972 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3976 let tables = RefCell::new(ty::Tables::empty());
3977 let inh = static_inherited_fields(ccx, &tables);
3978 let rty = ccx.tcx.node_id_to_type(id);
3979 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
3980 let declty = fcx.ccx.tcx.lookup_item_type(local_def(id)).ty;
3981 check_const_with_ty(&fcx, sp, e, declty);
3984 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3988 // Gather locals in statics (because of block expressions).
3989 // This is technically unnecessary because locals in static items are forbidden,
3990 // but prevents type checking from blowing up before const checking can properly
3992 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
3994 check_expr_with_hint(fcx, e, declty);
3995 demand::coerce(fcx, e.span, declty, e);
3996 fcx.select_all_obligations_or_error();
3998 regionck::regionck_expr(fcx, e);
3999 writeback::resolve_type_vars_in_expr(fcx, e);
4002 /// Checks whether a type can be represented in memory. In particular, it
4003 /// identifies types that contain themselves without indirection through a
4004 /// pointer, which would mean their size is unbounded. This is different from
4005 /// the question of whether a type can be instantiated. See the definition of
4006 /// `check_instantiable`.
4007 pub fn check_representable(tcx: &ty::ctxt,
4009 item_id: ast::NodeId,
4010 designation: &str) -> bool {
4011 let rty = tcx.node_id_to_type(item_id);
4013 // Check that it is possible to represent this type. This call identifies
4014 // (1) types that contain themselves and (2) types that contain a different
4015 // recursive type. It is only necessary to throw an error on those that
4016 // contain themselves. For case 2, there must be an inner type that will be
4017 // caught by case 1.
4018 match rty.is_representable(tcx, sp) {
4019 ty::SelfRecursive => {
4020 span_err!(tcx.sess, sp, E0072,
4021 "illegal recursive {} type; \
4022 wrap the inner value in a box to make it representable",
4026 ty::Representable | ty::ContainsRecursive => (),
4031 /// Checks whether a type can be created without an instance of itself.
4032 /// This is similar but different from the question of whether a type
4033 /// can be represented. For example, the following type:
4035 /// enum foo { None, Some(foo) }
4037 /// is instantiable but is not representable. Similarly, the type
4039 /// enum foo { Some(@foo) }
4041 /// is representable, but not instantiable.
4042 pub fn check_instantiable(tcx: &ty::ctxt,
4044 item_id: ast::NodeId)
4046 let item_ty = tcx.node_id_to_type(item_id);
4047 if !item_ty.is_instantiable(tcx) {
4048 span_err!(tcx.sess, sp, E0073,
4049 "this type cannot be instantiated without an \
4050 instance of itself");
4051 fileline_help!(tcx.sess, sp, "consider using `Option<{:?}>`",
4059 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4060 let t = tcx.node_id_to_type(id);
4061 if t.needs_subst() {
4062 span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
4066 ty::TyStruct(did, substs) => {
4067 let fields = tcx.lookup_struct_fields(did);
4068 if fields.is_empty() {
4069 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4072 let e = tcx.lookup_field_type(did, fields[0].id, substs);
4073 if !fields.iter().all(
4074 |f| tcx.lookup_field_type(did, f.id, substs) == e) {
4075 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4078 if !e.is_machine() {
4079 span_err!(tcx.sess, sp, E0077,
4080 "SIMD vector element type should be machine type");
4088 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4090 vs: &'tcx [P<ast::Variant>],
4093 fn disr_in_range(ccx: &CrateCtxt,
4095 disr: ty::Disr) -> bool {
4096 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4098 ast::TyU8 => disr as u8 as Disr == disr,
4099 ast::TyU16 => disr as u16 as Disr == disr,
4100 ast::TyU32 => disr as u32 as Disr == disr,
4101 ast::TyU64 => disr as u64 as Disr == disr,
4102 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4105 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4107 ast::TyI8 => disr as i8 as Disr == disr,
4108 ast::TyI16 => disr as i16 as Disr == disr,
4109 ast::TyI32 => disr as i32 as Disr == disr,
4110 ast::TyI64 => disr as i64 as Disr == disr,
4111 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4115 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4116 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4120 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4121 vs: &'tcx [P<ast::Variant>],
4123 hint: attr::ReprAttr) {
4124 #![allow(trivial_numeric_casts)]
4126 let rty = ccx.tcx.node_id_to_type(id);
4127 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4129 let tables = RefCell::new(ty::Tables::empty());
4130 let inh = static_inherited_fields(ccx, &tables);
4131 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4133 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4135 if let Some(ref e) = v.node.disr_expr {
4136 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4140 let def_id = local_def(id);
4142 // ty::enum_variants guards against discriminant overflows, so
4143 // we need not check for that.
4144 let variants = ccx.tcx.enum_variants(def_id);
4146 for (v, variant) in vs.iter().zip(variants.iter()) {
4147 let current_disr_val = variant.disr_val;
4149 // Check for duplicate discriminant values
4150 match disr_vals.iter().position(|&x| x == current_disr_val) {
4152 span_err!(ccx.tcx.sess, v.span, E0081,
4153 "discriminant value `{}` already exists", disr_vals[i]);
4154 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variants[i].id.node),
4155 "conflicting discriminant here")
4159 // Check for unrepresentable discriminant values
4161 attr::ReprAny | attr::ReprExtern => (),
4162 attr::ReprInt(sp, ity) => {
4163 if !disr_in_range(ccx, ity, current_disr_val) {
4164 span_err!(ccx.tcx.sess, v.span, E0082,
4165 "discriminant value outside specified type");
4166 span_note!(ccx.tcx.sess, sp,
4167 "discriminant type specified here");
4170 attr::ReprPacked => {
4171 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4174 disr_vals.push(current_disr_val);
4178 let hint = *ccx.tcx.lookup_repr_hints(ast::DefId { krate: ast::LOCAL_CRATE, node: id })
4179 .get(0).unwrap_or(&attr::ReprAny);
4181 if hint != attr::ReprAny && vs.len() <= 1 {
4183 span_err!(ccx.tcx.sess, sp, E0083,
4184 "unsupported representation for univariant enum");
4186 span_err!(ccx.tcx.sess, sp, E0084,
4187 "unsupported representation for zero-variant enum");
4191 do_check(ccx, vs, id, hint);
4193 check_representable(ccx.tcx, sp, id, "enum");
4195 // Check that it is possible to instantiate this enum:
4197 // This *sounds* like the same that as representable, but it's
4198 // not. See def'n of `check_instantiable()` for details.
4199 check_instantiable(ccx.tcx, sp, id);
4202 // Returns the type parameter count and the type for the given definition.
4203 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4206 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4208 def::DefLocal(nid) | def::DefUpvar(nid, _) => {
4209 let typ = fcx.local_ty(sp, nid);
4210 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4211 ty::GenericPredicates::empty())
4213 def::DefFn(id, _) | def::DefMethod(id, _) |
4214 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4215 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
4216 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4220 def::DefAssociatedTy(..) |
4222 def::DefTyParam(..) |
4224 def::DefForeignMod(..) |
4226 def::DefRegion(..) |
4228 def::DefSelfTy(..) => {
4229 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4234 // Instantiates the given path, which must refer to an item with the given
4235 // number of type parameters and type.
4236 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4237 segments: &[ast::PathSegment],
4238 type_scheme: TypeScheme<'tcx>,
4239 type_predicates: &ty::GenericPredicates<'tcx>,
4240 opt_self_ty: Option<Ty<'tcx>>,
4243 node_id: ast::NodeId) {
4244 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4250 // We need to extract the type parameters supplied by the user in
4251 // the path `path`. Due to the current setup, this is a bit of a
4252 // tricky-process; the problem is that resolve only tells us the
4253 // end-point of the path resolution, and not the intermediate steps.
4254 // Luckily, we can (at least for now) deduce the intermediate steps
4255 // just from the end-point.
4257 // There are basically four cases to consider:
4259 // 1. Reference to a *type*, such as a struct or enum:
4261 // mod a { struct Foo<T> { ... } }
4263 // Because we don't allow types to be declared within one
4264 // another, a path that leads to a type will always look like
4265 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4266 // that only the final segment can have type parameters, and
4267 // they are located in the TypeSpace.
4269 // *Note:* Generally speaking, references to types don't
4270 // actually pass through this function, but rather the
4271 // `ast_ty_to_ty` function in `astconv`. However, in the case
4272 // of struct patterns (and maybe literals) we do invoke
4273 // `instantiate_path` to get the general type of an instance of
4274 // a struct. (In these cases, there are actually no type
4275 // parameters permitted at present, but perhaps we will allow
4276 // them in the future.)
4278 // 1b. Reference to a enum variant or tuple-like struct:
4280 // struct foo<T>(...)
4281 // enum E<T> { foo(...) }
4283 // In these cases, the parameters are declared in the type
4286 // 2. Reference to a *fn item*:
4290 // In this case, the path will again always have the form
4291 // `a::b::foo::<T>` where only the final segment should have
4292 // type parameters. However, in this case, those parameters are
4293 // declared on a value, and hence are in the `FnSpace`.
4295 // 3. Reference to a *method*:
4297 // impl<A> SomeStruct<A> {
4301 // Here we can have a path like
4302 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4303 // may appear in two places. The penultimate segment,
4304 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4305 // final segment, `foo::<B>` contains parameters in fn space.
4307 // 4. Reference to an *associated const*:
4309 // impl<A> AnotherStruct<A> {
4310 // const FOO: B = BAR;
4313 // The path in this case will look like
4314 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4315 // only will have parameters in TypeSpace.
4317 // The first step then is to categorize the segments appropriately.
4319 assert!(!segments.is_empty());
4321 let mut ufcs_method = None;
4322 let mut segment_spaces: Vec<_>;
4324 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4325 def::DefSelfTy(..) |
4326 def::DefStruct(..) |
4327 def::DefVariant(..) |
4329 def::DefAssociatedTy(..) |
4331 def::DefPrimTy(..) |
4332 def::DefTyParam(..) => {
4333 // Everything but the final segment should have no
4334 // parameters at all.
4335 segment_spaces = vec![None; segments.len() - 1];
4336 segment_spaces.push(Some(subst::TypeSpace));
4339 // Case 2. Reference to a top-level value.
4342 def::DefStatic(..) => {
4343 segment_spaces = vec![None; segments.len() - 1];
4344 segment_spaces.push(Some(subst::FnSpace));
4347 // Case 3. Reference to a method.
4348 def::DefMethod(_, provenance) => {
4350 def::FromTrait(trait_did) => {
4351 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4353 def::FromImpl(_) => {}
4356 if segments.len() >= 2 {
4357 segment_spaces = vec![None; segments.len() - 2];
4358 segment_spaces.push(Some(subst::TypeSpace));
4359 segment_spaces.push(Some(subst::FnSpace));
4361 // `<T>::method` will end up here, and so can `T::method`.
4362 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4363 segment_spaces = vec![Some(subst::FnSpace)];
4364 ufcs_method = Some((provenance, self_ty));
4368 def::DefAssociatedConst(_, provenance) => {
4370 def::FromTrait(trait_did) => {
4371 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4373 def::FromImpl(_) => {}
4376 if segments.len() >= 2 {
4377 segment_spaces = vec![None; segments.len() - 2];
4378 segment_spaces.push(Some(subst::TypeSpace));
4379 segment_spaces.push(None);
4381 segment_spaces = vec![None];
4385 // Other cases. Various nonsense that really shouldn't show up
4386 // here. If they do, an error will have been reported
4387 // elsewhere. (I hope)
4389 def::DefForeignMod(..) |
4392 def::DefRegion(..) |
4394 def::DefUpvar(..) => {
4395 segment_spaces = vec![None; segments.len()];
4398 assert_eq!(segment_spaces.len(), segments.len());
4400 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4401 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4402 // type parameters are not mandatory.
4403 let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
4405 debug!("segment_spaces={:?}", segment_spaces);
4407 // Next, examine the definition, and determine how many type
4408 // parameters we expect from each space.
4409 let type_defs = &type_scheme.generics.types;
4410 let region_defs = &type_scheme.generics.regions;
4412 // Now that we have categorized what space the parameters for each
4413 // segment belong to, let's sort out the parameters that the user
4414 // provided (if any) into their appropriate spaces. We'll also report
4415 // errors if type parameters are provided in an inappropriate place.
4416 let mut substs = Substs::empty();
4417 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4420 check_path_args(fcx.tcx(), slice::ref_slice(segment),
4421 NO_TPS | NO_REGIONS);
4425 push_explicit_parameters_from_segment_to_substs(fcx,
4435 if let Some(self_ty) = opt_self_ty {
4436 if type_defs.len(subst::SelfSpace) == 1 {
4437 substs.types.push(subst::SelfSpace, self_ty);
4441 // Now we have to compare the types that the user *actually*
4442 // provided against the types that were *expected*. If the user
4443 // did not provide any types, then we want to substitute inference
4444 // variables. If the user provided some types, we may still need
4445 // to add defaults. If the user provided *too many* types, that's
4447 for &space in &ParamSpace::all() {
4448 adjust_type_parameters(fcx, span, space, type_defs,
4449 require_type_space, &mut substs);
4450 assert_eq!(substs.types.len(space), type_defs.len(space));
4452 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4453 assert_eq!(substs.regions().len(space), region_defs.len(space));
4456 // The things we are substituting into the type should not contain
4457 // escaping late-bound regions, and nor should the base type scheme.
4458 assert!(!substs.has_regions_escaping_depth(0));
4459 assert!(!type_scheme.has_escaping_regions());
4461 // Add all the obligations that are required, substituting and
4462 // normalized appropriately.
4463 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4464 fcx.add_obligations_for_parameters(
4465 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4468 // Substitute the values for the type parameters into the type of
4469 // the referenced item.
4470 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4473 if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
4474 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4475 // is inherent, there is no `Self` parameter, instead, the impl needs
4476 // type parameters, which we can infer by unifying the provided `Self`
4477 // with the substituted impl type.
4478 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4479 assert_eq!(substs.types.len(subst::TypeSpace),
4480 impl_scheme.generics.types.len(subst::TypeSpace));
4481 assert_eq!(substs.regions().len(subst::TypeSpace),
4482 impl_scheme.generics.regions.len(subst::TypeSpace));
4484 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4485 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4486 fcx.tcx().sess.span_bug(span,
4488 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4494 fcx.write_ty(node_id, ty_substituted);
4495 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4498 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4499 /// parameters are provided, then reports an error and clears the output vector.
4501 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4502 /// use inference variables. This seems less likely to lead to derived errors.
4504 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4505 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4506 /// here because we can easily use the precise span of the N+1'th parameter.
4507 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4508 fcx: &FnCtxt<'a, 'tcx>,
4509 space: subst::ParamSpace,
4511 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4512 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4513 segment: &ast::PathSegment,
4514 substs: &mut Substs<'tcx>)
4516 match segment.parameters {
4517 ast::AngleBracketedParameters(ref data) => {
4518 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4519 fcx, space, type_defs, region_defs, data, substs);
4522 ast::ParenthesizedParameters(ref data) => {
4523 span_err!(fcx.tcx().sess, span, E0238,
4524 "parenthesized parameters may only be used with a trait");
4525 push_explicit_parenthesized_parameters_from_segment_to_substs(
4526 fcx, space, span, type_defs, data, substs);
4531 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4532 fcx: &FnCtxt<'a, 'tcx>,
4533 space: subst::ParamSpace,
4534 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4535 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4536 data: &ast::AngleBracketedParameterData,
4537 substs: &mut Substs<'tcx>)
4540 let type_count = type_defs.len(space);
4541 assert_eq!(substs.types.len(space), 0);
4542 for (i, typ) in data.types.iter().enumerate() {
4543 let t = fcx.to_ty(&**typ);
4545 substs.types.push(space, t);
4546 } else if i == type_count {
4547 span_err!(fcx.tcx().sess, typ.span, E0087,
4548 "too many type parameters provided: \
4549 expected at most {} parameter{}, \
4550 found {} parameter{}",
4552 if type_count == 1 {""} else {"s"},
4554 if data.types.len() == 1 {""} else {"s"});
4555 substs.types.truncate(space, 0);
4561 if !data.bindings.is_empty() {
4562 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4563 "unexpected binding of associated item in expression path \
4564 (only allowed in type paths)");
4568 let region_count = region_defs.len(space);
4569 assert_eq!(substs.regions().len(space), 0);
4570 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4571 let r = ast_region_to_region(fcx.tcx(), lifetime);
4572 if i < region_count {
4573 substs.mut_regions().push(space, r);
4574 } else if i == region_count {
4575 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4576 "too many lifetime parameters provided: \
4577 expected {} parameter{}, found {} parameter{}",
4579 if region_count == 1 {""} else {"s"},
4580 data.lifetimes.len(),
4581 if data.lifetimes.len() == 1 {""} else {"s"});
4582 substs.mut_regions().truncate(space, 0);
4590 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4591 /// but intended for `Foo(A,B) -> C` form. This expands to
4592 /// roughly the same thing as `Foo<(A,B),C>`. One important
4593 /// difference has to do with the treatment of anonymous
4594 /// regions, which are translated into bound regions (NYI).
4595 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4596 fcx: &FnCtxt<'a, 'tcx>,
4597 space: subst::ParamSpace,
4599 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4600 data: &ast::ParenthesizedParameterData,
4601 substs: &mut Substs<'tcx>)
4603 let type_count = type_defs.len(space);
4605 span_err!(fcx.tcx().sess, span, E0167,
4606 "parenthesized form always supplies 2 type parameters, \
4607 but only {} parameter(s) were expected",
4611 let input_tys: Vec<Ty> =
4612 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4614 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4616 if type_count >= 1 {
4617 substs.types.push(space, tuple_ty);
4620 let output_ty: Option<Ty> =
4621 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4624 output_ty.unwrap_or(fcx.tcx().mk_nil());
4626 if type_count >= 2 {
4627 substs.types.push(space, output_ty);
4631 fn adjust_type_parameters<'a, 'tcx>(
4632 fcx: &FnCtxt<'a, 'tcx>,
4635 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4636 require_type_space: bool,
4637 substs: &mut Substs<'tcx>)
4639 let provided_len = substs.types.len(space);
4640 let desired = defs.get_slice(space);
4641 let required_len = desired.iter()
4642 .take_while(|d| d.default.is_none())
4645 debug!("adjust_type_parameters(space={:?}, \
4654 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4655 assert!(provided_len <= desired.len());
4657 // Nothing specified at all: supply inference variables for
4659 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4660 substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
4664 // Too few parameters specified: report an error and use Err
4666 if provided_len < required_len {
4668 if desired.len() != required_len { "at least " } else { "" };
4669 span_err!(fcx.tcx().sess, span, E0089,
4670 "too few type parameters provided: expected {}{} parameter{}, \
4671 found {} parameter{}",
4672 qualifier, required_len,
4673 if required_len == 1 {""} else {"s"},
4675 if provided_len == 1 {""} else {"s"});
4676 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4680 // Otherwise, add in any optional parameters that the user
4681 // omitted. The case of *too many* parameters is handled
4683 // push_explicit_parameters_from_segment_to_substs(). Note
4684 // that the *default* type are expressed in terms of all prior
4685 // parameters, so we have to substitute as we go with the
4686 // partial substitution that we have built up.
4687 for i in provided_len..desired.len() {
4688 let default = desired[i].default.unwrap();
4689 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4690 substs.types.push(space, default);
4692 assert_eq!(substs.types.len(space), desired.len());
4694 debug!("Final substs: {:?}", substs);
4697 fn adjust_region_parameters(
4701 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4702 substs: &mut Substs)
4704 let provided_len = substs.mut_regions().len(space);
4705 let desired = defs.get_slice(space);
4707 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4708 assert!(provided_len <= desired.len());
4710 // If nothing was provided, just use inference variables.
4711 if provided_len == 0 {
4712 substs.mut_regions().replace(
4714 fcx.infcx().region_vars_for_defs(span, desired));
4718 // If just the right number were provided, everybody is happy.
4719 if provided_len == desired.len() {
4723 // Otherwise, too few were provided. Report an error and then
4724 // use inference variables.
4725 span_err!(fcx.tcx().sess, span, E0090,
4726 "too few lifetime parameters provided: expected {} parameter{}, \
4727 found {} parameter{}",
4729 if desired.len() == 1 {""} else {"s"},
4731 if provided_len == 1 {""} else {"s"});
4733 substs.mut_regions().replace(
4735 fcx.infcx().region_vars_for_defs(span, desired));
4739 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4743 where F: Fn() -> Ty<'tcx>
4745 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4748 let alternative = f();
4751 if alternative.is_ty_var() || alternative.references_error() {
4752 fcx.type_error_message(sp, |_actual| {
4753 "the type of this value must be known in this context".to_string()
4755 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4756 ty = fcx.tcx().types.err;
4758 demand::suptype(fcx, sp, alternative, ty);
4766 // Resolves `typ` by a single level if `typ` is a type variable. If no
4767 // resolution is possible, then an error is reported.
4768 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4773 structurally_resolve_type_or_else(fcx, sp, ty, || {
4778 // Returns true if b contains a break that can exit from b
4779 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
4780 // First: is there an unlabeled break immediately
4782 (loop_query(&*b, |e| {
4784 ast::ExprBreak(None) => true,
4788 // Second: is there a labeled break with label
4789 // <id> nested anywhere inside the loop?
4790 (block_query(b, |e| {
4791 if let ast::ExprBreak(Some(_)) = e.node {
4792 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4799 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4801 tps: &OwnedSlice<ast::TyParam>,
4803 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4806 // make a vector of booleans initially false, set to true when used
4807 if tps.is_empty() { return; }
4808 let mut tps_used = vec![false; tps.len()];
4810 for leaf_ty in ty.walk() {
4811 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4812 debug!("Found use of ty param num {}", idx);
4813 tps_used[idx as usize] = true;
4817 for (i, b) in tps_used.iter().enumerate() {
4819 span_err!(ccx.tcx.sess, span, E0091,
4820 "type parameter `{}` is unused",
4821 token::get_ident(tps[i].ident));
4826 /// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
4827 /// and in libcore/intrinsics.rs
4828 pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
4829 fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
4830 let name = token::intern(&format!("P{}", n));
4831 ccx.tcx.mk_param(subst::FnSpace, n, name)
4835 let name = token::get_ident(it.ident);
4836 let (n_tps, inputs, output) = if name.starts_with("atomic_") {
4837 let split : Vec<&str> = name.split('_').collect();
4838 assert!(split.len() >= 2, "Atomic intrinsic not correct format");
4840 //We only care about the operation here
4841 let (n_tps, inputs, output) = match split[1] {
4842 "cxchg" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)),
4846 "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))),
4848 "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4851 "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" |
4852 "min" | "umax" | "umin" => {
4853 (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4856 "fence" | "singlethreadfence" => {
4857 (0, Vec::new(), tcx.mk_nil())
4860 span_err!(tcx.sess, it.span, E0092,
4861 "unrecognized atomic operation function: `{}`", op);
4865 (n_tps, inputs, ty::FnConverging(output))
4866 } else if &name[..] == "abort" || &name[..] == "unreachable" {
4867 (0, Vec::new(), ty::FnDiverging)
4869 let (n_tps, inputs, output) = match &name[..] {
4870 "breakpoint" => (0, Vec::new(), tcx.mk_nil()),
4872 "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize),
4873 "size_of_val" | "min_align_of_val" => {
4875 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
4878 ], ccx.tcx.types.usize)
4880 "init" | "init_dropped" => (1, Vec::new(), param(ccx, 0)),
4881 "uninit" => (1, Vec::new(), param(ccx, 0)),
4882 "forget" => (1, vec!( param(ccx, 0) ), tcx.mk_nil()),
4883 "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)),
4884 "move_val_init" => {
4887 tcx.mk_mut_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
4894 "drop_in_place" => {
4895 (1, vec![tcx.mk_mut_ptr(param(ccx, 0))], tcx.mk_nil())
4897 "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool),
4899 "type_name" => (1, Vec::new(), tcx.mk_static_str()),
4900 "type_id" => (1, Vec::new(), ccx.tcx.types.u64),
4901 "offset" | "arith_offset" => {
4904 tcx.mk_ptr(ty::TypeAndMut {
4906 mutbl: ast::MutImmutable
4910 tcx.mk_ptr(ty::TypeAndMut {
4912 mutbl: ast::MutImmutable
4915 "copy" | "copy_nonoverlapping" => {
4918 tcx.mk_ptr(ty::TypeAndMut {
4920 mutbl: ast::MutImmutable
4922 tcx.mk_ptr(ty::TypeAndMut {
4924 mutbl: ast::MutMutable
4930 "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
4933 tcx.mk_ptr(ty::TypeAndMut {
4935 mutbl: ast::MutMutable
4937 tcx.mk_ptr(ty::TypeAndMut {
4939 mutbl: ast::MutImmutable
4945 "write_bytes" | "volatile_set_memory" => {
4948 tcx.mk_ptr(ty::TypeAndMut {
4950 mutbl: ast::MutMutable
4957 "sqrtf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4958 "sqrtf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4961 vec!( tcx.types.f32, tcx.types.i32 ),
4966 vec!( tcx.types.f64, tcx.types.i32 ),
4969 "sinf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4970 "sinf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4971 "cosf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4972 "cosf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4975 vec!( tcx.types.f32, tcx.types.f32 ),
4980 vec!( tcx.types.f64, tcx.types.f64 ),
4983 "expf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4984 "expf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4985 "exp2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4986 "exp2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4987 "logf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4988 "logf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4989 "log10f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4990 "log10f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4991 "log2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4992 "log2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4995 vec!( tcx.types.f32, tcx.types.f32, tcx.types.f32 ),
5000 vec!( tcx.types.f64, tcx.types.f64, tcx.types.f64 ),
5003 "fabsf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5004 "fabsf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5005 "copysignf32" => (0, vec!( tcx.types.f32, tcx.types.f32 ), tcx.types.f32),
5006 "copysignf64" => (0, vec!( tcx.types.f64, tcx.types.f64 ), tcx.types.f64),
5007 "floorf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5008 "floorf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5009 "ceilf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5010 "ceilf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5011 "truncf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5012 "truncf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5013 "rintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5014 "rintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5015 "nearbyintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5016 "nearbyintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5017 "roundf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5018 "roundf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5019 "ctpop8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5020 "ctpop16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5021 "ctpop32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5022 "ctpop64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5023 "ctlz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5024 "ctlz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5025 "ctlz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5026 "ctlz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5027 "cttz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5028 "cttz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5029 "cttz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5030 "cttz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5031 "bswap16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5032 "bswap32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5033 "bswap64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5036 (1, vec!( tcx.mk_imm_ptr(param(ccx, 0)) ), param(ccx, 0)),
5038 (1, vec!( tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ), tcx.mk_nil()),
5040 "i8_add_with_overflow" | "i8_sub_with_overflow" | "i8_mul_with_overflow" =>
5041 (0, vec!(tcx.types.i8, tcx.types.i8),
5042 tcx.mk_tup(vec!(tcx.types.i8, tcx.types.bool))),
5044 "i16_add_with_overflow" | "i16_sub_with_overflow" | "i16_mul_with_overflow" =>
5045 (0, vec!(tcx.types.i16, tcx.types.i16),
5046 tcx.mk_tup(vec!(tcx.types.i16, tcx.types.bool))),
5048 "i32_add_with_overflow" | "i32_sub_with_overflow" | "i32_mul_with_overflow" =>
5049 (0, vec!(tcx.types.i32, tcx.types.i32),
5050 tcx.mk_tup(vec!(tcx.types.i32, tcx.types.bool))),
5052 "i64_add_with_overflow" | "i64_sub_with_overflow" | "i64_mul_with_overflow" =>
5053 (0, vec!(tcx.types.i64, tcx.types.i64),
5054 tcx.mk_tup(vec!(tcx.types.i64, tcx.types.bool))),
5056 "u8_add_with_overflow" | "u8_sub_with_overflow" | "u8_mul_with_overflow" =>
5057 (0, vec!(tcx.types.u8, tcx.types.u8),
5058 tcx.mk_tup(vec!(tcx.types.u8, tcx.types.bool))),
5060 "u16_add_with_overflow" | "u16_sub_with_overflow" | "u16_mul_with_overflow" =>
5061 (0, vec!(tcx.types.u16, tcx.types.u16),
5062 tcx.mk_tup(vec!(tcx.types.u16, tcx.types.bool))),
5064 "u32_add_with_overflow" | "u32_sub_with_overflow" | "u32_mul_with_overflow"=>
5065 (0, vec!(tcx.types.u32, tcx.types.u32),
5066 tcx.mk_tup(vec!(tcx.types.u32, tcx.types.bool))),
5068 "u64_add_with_overflow" | "u64_sub_with_overflow" | "u64_mul_with_overflow" =>
5069 (0, vec!(tcx.types.u64, tcx.types.u64),
5070 tcx.mk_tup(vec!(tcx.types.u64, tcx.types.bool))),
5072 "unchecked_udiv" | "unchecked_sdiv" | "unchecked_urem" | "unchecked_srem" =>
5073 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5075 "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
5076 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5078 "return_address" => (0, vec![], tcx.mk_imm_ptr(tcx.types.u8)),
5080 "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()),
5082 "discriminant_value" => (1, vec![
5083 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
5085 param(ccx, 0))], tcx.types.u64),
5088 let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
5089 let fn_ty = ty::BareFnTy {
5090 unsafety: ast::Unsafety::Normal,
5092 sig: ty::Binder(FnSig {
5093 inputs: vec![mut_u8],
5094 output: ty::FnOutput::FnConverging(tcx.mk_nil()),
5098 let fn_ty = tcx.mk_bare_fn(fn_ty);
5099 (0, vec![tcx.mk_fn(None, fn_ty), mut_u8], mut_u8)
5103 span_err!(tcx.sess, it.span, E0093,
5104 "unrecognized intrinsic function: `{}`", *other);
5108 (n_tps, inputs, ty::FnConverging(output))
5110 let fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy {
5111 unsafety: ast::Unsafety::Unsafe,
5112 abi: abi::RustIntrinsic,
5113 sig: ty::Binder(FnSig {
5119 let i_ty = ccx.tcx.lookup_item_type(local_def(it.id));
5120 let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
5121 if i_n_tps != n_tps {
5122 span_err!(tcx.sess, it.span, E0094,
5123 "intrinsic has wrong number of type \
5124 parameters: found {}, expected {}",
5127 require_same_types(tcx,
5134 format!("intrinsic has wrong type: expected `{}`",