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::infer::type_variable;
91 use middle::pat_util::{self, pat_id_map};
92 use middle::privacy::{AllPublic, LastMod};
93 use middle::region::{self, CodeExtent};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
97 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
98 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
99 use middle::ty::{MethodCall, MethodCallee};
100 use middle::ty_fold::{TypeFolder, TypeFoldable};
101 use require_c_abi_if_variadic;
102 use rscope::{ElisionFailureInfo, RegionScope};
103 use session::Session;
104 use {CrateCtxt, lookup_full_def, require_same_types};
107 use util::common::{block_query, ErrorReported, indenter, loop_query};
108 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
109 use util::lev_distance::lev_distance;
111 use std::cell::{Cell, Ref, RefCell};
112 use std::collections::HashSet;
113 use std::mem::replace;
115 use syntax::{self, abi, attr};
116 use syntax::attr::AttrMetaMethods;
117 use syntax::ast::{self, DefId, Visibility};
118 use syntax::ast_util::{self, local_def};
119 use syntax::codemap::{self, Span};
120 use syntax::feature_gate::emit_feature_err;
121 use syntax::owned_slice::OwnedSlice;
122 use syntax::parse::token;
123 use syntax::print::pprust;
125 use syntax::visit::{self, Visitor};
143 /// closures defined within the function. For example:
146 /// bar(move|| { ... })
149 /// Here, the function `foo()` and the closure passed to
150 /// `bar()` will each have their own `FnCtxt`, but they will
151 /// share the inherited fields.
152 pub struct Inherited<'a, 'tcx: 'a> {
153 infcx: infer::InferCtxt<'a, 'tcx>,
154 locals: RefCell<NodeMap<Ty<'tcx>>>,
156 tables: &'a RefCell<ty::Tables<'tcx>>,
158 // A mapping from each fn's id to its signature, with all bound
159 // regions replaced with free ones. Unlike the other tables, this
160 // one is never copied into the tcx: it is only used by regionck.
161 fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
163 // When we process a call like `c()` where `c` is a closure type,
164 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
165 // `FnOnce` closure. In that case, we defer full resolution of the
166 // call until upvar inference can kick in and make the
167 // decision. We keep these deferred resolutions grouped by the
168 // def-id of the closure, so that once we decide, we can easily go
169 // back and process them.
170 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
172 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
175 trait DeferredCallResolution<'tcx> {
176 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
179 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
181 /// When type-checking an expression, we propagate downward
182 /// whatever type hint we are able in the form of an `Expectation`.
183 #[derive(Copy, Clone, Debug)]
184 pub enum Expectation<'tcx> {
185 /// We know nothing about what type this expression should have.
188 /// This expression should have the type given (or some subtype)
189 ExpectHasType(Ty<'tcx>),
191 /// This expression will be cast to the `Ty`
192 ExpectCastableToType(Ty<'tcx>),
194 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
195 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
196 ExpectRvalueLikeUnsized(Ty<'tcx>),
199 impl<'tcx> Expectation<'tcx> {
200 // Disregard "castable to" expectations because they
201 // can lead us astray. Consider for example `if cond
202 // {22} else {c} as u8` -- if we propagate the
203 // "castable to u8" constraint to 22, it will pick the
204 // type 22u8, which is overly constrained (c might not
205 // be a u8). In effect, the problem is that the
206 // "castable to" expectation is not the tightest thing
207 // we can say, so we want to drop it in this case.
208 // The tightest thing we can say is "must unify with
209 // else branch". Note that in the case of a "has type"
210 // constraint, this limitation does not hold.
212 // If the expected type is just a type variable, then don't use
213 // an expected type. Otherwise, we might write parts of the type
214 // when checking the 'then' block which are incompatible with the
216 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
218 ExpectHasType(ety) => {
219 let ety = fcx.infcx().shallow_resolve(ety);
220 if !ety.is_ty_var() {
226 ExpectRvalueLikeUnsized(ety) => {
227 ExpectRvalueLikeUnsized(ety)
234 #[derive(Copy, Clone)]
235 pub struct UnsafetyState {
236 pub def: ast::NodeId,
237 pub unsafety: ast::Unsafety,
238 pub unsafe_push_count: u32,
243 pub fn function(unsafety: ast::Unsafety, def: ast::NodeId) -> UnsafetyState {
244 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
247 pub fn recurse(&mut self, blk: &ast::Block) -> UnsafetyState {
248 match self.unsafety {
249 // If this unsafe, then if the outer function was already marked as
250 // unsafe we shouldn't attribute the unsafe'ness to the block. This
251 // way the block can be warned about instead of ignoring this
252 // extraneous block (functions are never warned about).
253 ast::Unsafety::Unsafe if self.from_fn => *self,
256 let (unsafety, def, count) = match blk.rules {
257 ast::PushUnsafeBlock(..) =>
258 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
259 ast::PopUnsafeBlock(..) =>
260 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
261 ast::UnsafeBlock(..) =>
262 (ast::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
264 (unsafety, self.def, self.unsafe_push_count),
266 UnsafetyState{ def: def,
268 unsafe_push_count: count,
276 pub struct FnCtxt<'a, 'tcx: 'a> {
277 body_id: ast::NodeId,
279 // This flag is set to true if, during the writeback phase, we encounter
280 // a type error in this function.
281 writeback_errors: Cell<bool>,
283 // Number of errors that had been reported when we started
284 // checking this function. On exit, if we find that *more* errors
285 // have been reported, we will skip regionck and other work that
286 // expects the types within the function to be consistent.
287 err_count_on_creation: usize,
289 ret_ty: ty::FnOutput<'tcx>,
291 ps: RefCell<UnsafetyState>,
293 inh: &'a Inherited<'a, 'tcx>,
295 ccx: &'a CrateCtxt<'a, 'tcx>,
298 impl<'a, 'tcx> Inherited<'a, 'tcx> {
299 fn new(tcx: &'a ty::ctxt<'tcx>,
300 tables: &'a RefCell<ty::Tables<'tcx>>,
301 param_env: ty::ParameterEnvironment<'a, 'tcx>)
302 -> Inherited<'a, 'tcx> {
305 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
306 locals: RefCell::new(NodeMap()),
308 fn_sig_map: RefCell::new(NodeMap()),
309 deferred_call_resolutions: RefCell::new(DefIdMap()),
310 deferred_cast_checks: RefCell::new(Vec::new()),
314 fn normalize_associated_types_in<T>(&self,
316 body_id: ast::NodeId,
319 where T : TypeFoldable<'tcx> + HasTypeFlags
321 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
322 assoc::normalize_associated_types_in(&self.infcx,
331 // Used by check_const and check_enum_variants
332 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
333 inh: &'a Inherited<'a, 'tcx>,
334 rty: ty::FnOutput<'tcx>,
335 body_id: ast::NodeId)
336 -> FnCtxt<'a, 'tcx> {
339 writeback_errors: Cell::new(false),
340 err_count_on_creation: ccx.tcx.sess.err_count(),
342 ps: RefCell::new(UnsafetyState::function(ast::Unsafety::Normal, 0)),
348 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
349 tables: &'a RefCell<ty::Tables<'tcx>>)
350 -> Inherited<'a, 'tcx> {
351 // It's kind of a kludge to manufacture a fake function context
352 // and statement context, but we might as well do write the code only once
353 let param_env = ccx.tcx.empty_parameter_environment();
354 Inherited::new(ccx.tcx, &tables, param_env)
357 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
358 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
360 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
361 fn visit_item(&mut self, i: &'tcx ast::Item) {
362 check_item_type(self.ccx, i);
363 visit::walk_item(self, i);
366 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
368 ast::TyFixedLengthVec(_, ref expr) => {
369 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
374 visit::walk_ty(self, t);
378 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
379 fn visit_item(&mut self, i: &'tcx ast::Item) {
380 check_item_body(self.ccx, i);
381 visit::walk_item(self, i);
385 pub fn check_item_types(ccx: &CrateCtxt) {
386 let krate = ccx.tcx.map.krate();
387 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
388 visit::walk_crate(&mut visit, krate);
390 // If types are not well-formed, it leads to all manner of errors
391 // downstream, so stop reporting errors at this point.
392 ccx.tcx.sess.abort_if_errors();
394 let mut visit = CheckItemTypesVisitor { ccx: ccx };
395 visit::walk_crate(&mut visit, krate);
397 ccx.tcx.sess.abort_if_errors();
399 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
400 visit::walk_crate(&mut visit, krate);
402 ccx.tcx.sess.abort_if_errors();
404 for drop_method_did in ccx.tcx.destructors.borrow().iter() {
405 if drop_method_did.krate == ast::LOCAL_CRATE {
406 let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
407 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
410 assert!(ccx.tcx.sess.has_errors());
416 ccx.tcx.sess.abort_if_errors();
419 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
420 decl: &'tcx ast::FnDecl,
421 body: &'tcx ast::Block,
425 param_env: ty::ParameterEnvironment<'a, 'tcx>)
428 ty::TyBareFn(_, ref fn_ty) => {
429 let tables = RefCell::new(ty::Tables::empty());
430 let inh = Inherited::new(ccx.tcx, &tables, param_env);
432 // Compute the fty from point of view of inside fn.
434 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
436 ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
439 inh.normalize_associated_types_in(body.span,
443 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
444 decl, fn_id, body, &inh);
446 fcx.select_all_obligations_and_apply_defaults();
447 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
448 fcx.select_all_obligations_or_error();
451 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
453 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
454 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
456 _ => ccx.tcx.sess.impossible_case(body.span,
457 "check_bare_fn: function type expected")
461 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
462 fcx: &'a FnCtxt<'a, 'tcx>
465 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
466 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
469 // infer the variable's type
470 let var_ty = self.fcx.infcx().next_ty_var();
471 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
475 // take type that the user specified
476 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
483 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
484 // Add explicitly-declared locals.
485 fn visit_local(&mut self, local: &'tcx ast::Local) {
486 let o_ty = match local.ty {
487 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
490 self.assign(local.span, local.id, o_ty);
491 debug!("Local variable {:?} is assigned type {}",
493 self.fcx.infcx().ty_to_string(
494 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
495 visit::walk_local(self, local);
498 // Add pattern bindings.
499 fn visit_pat(&mut self, p: &'tcx ast::Pat) {
500 if let ast::PatIdent(_, ref path1, _) = p.node {
501 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) {
502 let var_ty = self.assign(p.span, p.id, None);
504 self.fcx.require_type_is_sized(var_ty, p.span,
505 traits::VariableType(p.id));
507 debug!("Pattern binding {} is assigned to {} with type {:?}",
508 token::get_ident(path1.node),
509 self.fcx.infcx().ty_to_string(
510 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
514 visit::walk_pat(self, p);
517 fn visit_block(&mut self, b: &'tcx ast::Block) {
518 // non-obvious: the `blk` variable maps to region lb, so
519 // we have to keep this up-to-date. This
520 // is... unfortunate. It'd be nice to not need this.
521 visit::walk_block(self, b);
524 // Since an expr occurs as part of the type fixed size arrays we
525 // need to record the type for that node
526 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
528 ast::TyFixedLengthVec(ref ty, ref count_expr) => {
529 self.visit_ty(&**ty);
530 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
532 _ => visit::walk_ty(self, t)
536 // Don't descend into fns and items
537 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx ast::FnDecl,
538 _: &'tcx ast::Block, _: Span, _: ast::NodeId) { }
539 fn visit_item(&mut self, _: &ast::Item) { }
543 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
544 /// body and returns the function context used for that purpose, since in the case of a fn item
545 /// there is still a bit more to do.
548 /// * inherited: other fields inherited from the enclosing fn (if any)
549 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
550 unsafety: ast::Unsafety,
551 unsafety_id: ast::NodeId,
552 fn_sig: &ty::FnSig<'tcx>,
553 decl: &'tcx ast::FnDecl,
555 body: &'tcx ast::Block,
556 inherited: &'a Inherited<'a, 'tcx>)
560 let err_count_on_creation = tcx.sess.err_count();
562 let arg_tys = &fn_sig.inputs;
563 let ret_ty = fn_sig.output;
565 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
570 // Create the function context. This is either derived from scratch or,
571 // in the case of function expressions, based on the outer context.
574 writeback_errors: Cell::new(false),
575 err_count_on_creation: err_count_on_creation,
577 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
582 // Remember return type so that regionck can access it later.
583 let mut fn_sig_tys: Vec<Ty> =
588 if let ty::FnConverging(ret_ty) = ret_ty {
589 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
590 fn_sig_tys.push(ret_ty);
593 debug!("fn-sig-map: fn_id={} fn_sig_tys={:?}",
597 inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys);
600 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
602 // Add formal parameters.
603 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
604 // Create type variables for each argument.
605 pat_util::pat_bindings(
608 |_bm, pat_id, sp, _path| {
609 let var_ty = visit.assign(sp, pat_id, None);
610 fcx.require_type_is_sized(var_ty, sp,
611 traits::VariableType(pat_id));
614 // Check the pattern.
617 map: pat_id_map(&tcx.def_map, &*input.pat),
619 _match::check_pat(&pcx, &*input.pat, *arg_ty);
622 visit.visit_block(body);
625 check_block_with_expected(&fcx, body, match ret_ty {
626 ty::FnConverging(result_type) => ExpectHasType(result_type),
627 ty::FnDiverging => NoExpectation
630 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
631 fcx.write_ty(input.id, arg);
637 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
640 check_representable(tcx, span, id, "struct");
641 check_instantiable(tcx, span, id);
643 if tcx.lookup_simd(local_def(id)) {
644 check_simd(tcx, span, id);
648 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
649 debug!("check_item_type(it.id={}, it.ident={})",
651 ccx.tcx.item_path_str(local_def(it.id)));
652 let _indenter = indenter();
654 // Consts can play a role in type-checking, so they are included here.
655 ast::ItemStatic(_, _, ref e) |
656 ast::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
657 ast::ItemEnum(ref enum_definition, _) => {
658 check_enum_variants(ccx,
660 &enum_definition.variants,
663 ast::ItemFn(..) => {} // entirely within check_item_body
664 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
665 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
666 match ccx.tcx.impl_trait_ref(local_def(it.id)) {
667 Some(impl_trait_ref) => {
668 check_impl_items_against_trait(ccx,
676 ast::ItemTrait(_, ref generics, _, _) => {
677 check_trait_on_unimplemented(ccx, generics, it);
679 ast::ItemStruct(..) => {
680 check_struct(ccx, it.id, it.span);
682 ast::ItemTy(ref t, ref generics) => {
683 let pty_ty = ccx.tcx.node_id_to_type(it.id);
684 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
686 ast::ItemForeignMod(ref m) => {
687 if m.abi == abi::RustIntrinsic {
688 for item in &m.items {
689 check_intrinsic_type(ccx, &**item);
692 for item in &m.items {
693 let pty = ccx.tcx.lookup_item_type(local_def(item.id));
694 if !pty.generics.types.is_empty() {
695 span_err!(ccx.tcx.sess, item.span, E0044,
696 "foreign items may not have type parameters");
699 if let ast::ForeignItemFn(ref fn_decl, _) = item.node {
700 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
705 _ => {/* nothing to do */ }
709 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
710 debug!("check_item_body(it.id={}, it.ident={})",
712 ccx.tcx.item_path_str(local_def(it.id)));
713 let _indenter = indenter();
715 ast::ItemFn(ref decl, _, _, _, _, ref body) => {
716 let fn_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
717 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
718 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
720 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
721 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
723 let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
725 for impl_item in impl_items {
726 match impl_item.node {
727 ast::ConstImplItem(_, ref expr) => {
728 check_const(ccx, impl_item.span, &*expr, impl_item.id)
730 ast::MethodImplItem(ref sig, ref body) => {
731 check_method_body(ccx, &impl_pty.generics, sig, body,
732 impl_item.id, impl_item.span);
734 ast::TypeImplItem(_) |
735 ast::MacImplItem(_) => {
736 // Nothing to do here.
741 ast::ItemTrait(_, _, _, ref trait_items) => {
742 let trait_def = ccx.tcx.lookup_trait_def(local_def(it.id));
743 for trait_item in trait_items {
744 match trait_item.node {
745 ast::ConstTraitItem(_, Some(ref expr)) => {
746 check_const(ccx, trait_item.span, &*expr, trait_item.id)
748 ast::MethodTraitItem(ref sig, Some(ref body)) => {
749 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
751 check_method_body(ccx, &trait_def.generics, sig, body,
752 trait_item.id, trait_item.span);
754 ast::MethodTraitItem(ref sig, None) => {
755 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
757 ast::ConstTraitItem(_, None) |
758 ast::TypeTraitItem(..) => {
764 _ => {/* nothing to do */ }
768 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
770 constness: ast::Constness)
773 ast::Constness::NotConst => {
776 ast::Constness::Const => {
777 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
782 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
783 generics: &ast::Generics,
785 if let Some(ref attr) = item.attrs.iter().find(|a| {
786 a.check_name("rustc_on_unimplemented")
788 if let Some(ref istring) = attr.value_str() {
789 let parser = Parser::new(&istring);
790 let types = &*generics.ty_params;
791 for token in parser {
793 Piece::String(_) => (), // Normal string, no need to check it
794 Piece::NextArgument(a) => match a.position {
795 // `{Self}` is allowed
796 Position::ArgumentNamed(s) if s == "Self" => (),
797 // So is `{A}` if A is a type parameter
798 Position::ArgumentNamed(s) => match types.iter().find(|t| {
799 t.ident.as_str() == s
803 span_err!(ccx.tcx.sess, attr.span, E0230,
804 "there is no type parameter \
806 s, item.ident.as_str());
809 // `{:1}` and `{}` are not to be used
810 Position::ArgumentIs(_) | Position::ArgumentNext => {
811 span_err!(ccx.tcx.sess, attr.span, E0231,
812 "only named substitution \
813 parameters are allowed");
819 span_err!(ccx.tcx.sess, attr.span, E0232,
820 "this attribute must have a value, \
821 eg `#[rustc_on_unimplemented = \"foo\"]`")
826 /// Type checks a method body.
830 /// * `item_generics`: generics defined on the impl/trait that contains
832 /// * `self_bound`: bound for the `Self` type parameter, if any
833 /// * `method`: the method definition
834 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
835 item_generics: &ty::Generics<'tcx>,
836 sig: &'tcx ast::MethodSig,
837 body: &'tcx ast::Block,
838 id: ast::NodeId, span: Span) {
839 debug!("check_method_body(item_generics={:?}, id={})",
841 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
843 let fty = ccx.tcx.node_id_to_type(id);
844 debug!("check_method_body: fty={:?}", fty);
846 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
849 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
851 impl_trait_ref: &ty::TraitRef<'tcx>,
852 impl_items: &[P<ast::ImplItem>]) {
853 // Locate trait methods
855 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
856 let mut overridden_associated_type = None;
858 // Check existing impl methods to see if they are both present in trait
859 // and compatible with trait signature
860 for impl_item in impl_items {
861 let ty_impl_item = ccx.tcx.impl_or_trait_item(local_def(impl_item.id));
862 let ty_trait_item = trait_items.iter()
863 .find(|ac| ac.name() == ty_impl_item.name())
865 // This is checked by resolve
866 tcx.sess.span_bug(impl_item.span,
867 &format!("impl-item `{}` is not a member of `{:?}`",
868 token::get_name(ty_impl_item.name()),
871 match impl_item.node {
872 ast::ConstImplItem(..) => {
873 let impl_const = match ty_impl_item {
874 ty::ConstTraitItem(ref cti) => cti,
875 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
878 // Find associated const definition.
879 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
880 compare_const_impl(ccx.tcx,
886 span_err!(tcx.sess, impl_item.span, E0323,
887 "item `{}` is an associated const, \
888 which doesn't match its trait `{:?}`",
889 token::get_name(impl_const.name),
893 ast::MethodImplItem(ref sig, ref body) => {
894 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
896 let impl_method = match ty_impl_item {
897 ty::MethodTraitItem(ref mti) => mti,
898 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
901 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
902 compare_impl_method(ccx.tcx,
909 span_err!(tcx.sess, impl_item.span, E0324,
910 "item `{}` is an associated method, \
911 which doesn't match its trait `{:?}`",
912 token::get_name(impl_method.name),
916 ast::TypeImplItem(_) => {
917 let impl_type = match ty_impl_item {
918 ty::TypeTraitItem(ref tti) => tti,
919 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
922 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
923 if let Some(_) = at.ty {
924 overridden_associated_type = Some(impl_item);
927 span_err!(tcx.sess, impl_item.span, E0325,
928 "item `{}` is an associated type, \
929 which doesn't match its trait `{:?}`",
930 token::get_name(impl_type.name),
934 ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
939 // Check for missing items from trait
940 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
941 let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
942 let mut missing_items = Vec::new();
943 let mut invalidated_items = Vec::new();
944 let associated_type_overridden = overridden_associated_type.is_some();
945 for trait_item in trait_items.iter() {
947 ty::ConstTraitItem(ref associated_const) => {
948 let is_implemented = impl_items.iter().any(|ii| {
950 ast::ConstImplItem(..) => {
951 ii.ident.name == associated_const.name
957 associated_consts.iter().any(|ac| ac.default.is_some() &&
958 ac.name == associated_const.name);
961 missing_items.push(associated_const.name);
962 } else if associated_type_overridden {
963 invalidated_items.push(associated_const.name);
967 ty::MethodTraitItem(ref trait_method) => {
969 impl_items.iter().any(|ii| {
971 ast::MethodImplItem(..) => {
972 ii.ident.name == trait_method.name
978 provided_methods.iter().any(|m| m.name == trait_method.name);
981 missing_items.push(trait_method.name);
982 } else if associated_type_overridden {
983 invalidated_items.push(trait_method.name);
987 ty::TypeTraitItem(ref associated_type) => {
988 let is_implemented = impl_items.iter().any(|ii| {
990 ast::TypeImplItem(_) => {
991 ii.ident.name == associated_type.name
996 let is_provided = associated_type.ty.is_some();
999 missing_items.push(associated_type.name);
1000 } else if associated_type_overridden {
1001 invalidated_items.push(associated_type.name);
1008 if !missing_items.is_empty() {
1009 span_err!(tcx.sess, impl_span, E0046,
1010 "not all trait items implemented, missing: `{}`",
1011 missing_items.iter()
1012 .map(<ast::Name>::as_str)
1013 .collect::<Vec<_>>().join("`, `"))
1016 if !invalidated_items.is_empty() {
1017 let invalidator = overridden_associated_type.unwrap();
1018 span_err!(tcx.sess, invalidator.span, E0399,
1019 "the following trait items need to be reimplemented \
1020 as `{}` was overridden: `{}`",
1021 invalidator.ident.as_str(),
1022 invalidated_items.iter()
1023 .map(<ast::Name>::as_str)
1024 .collect::<Vec<_>>().join("`, `"))
1028 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1035 let tstr = fcx.infcx().ty_to_string(t_cast);
1036 fcx.type_error_message(span, |actual| {
1037 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1040 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1041 let mtstr = match mt {
1042 ast::MutMutable => "mut ",
1043 ast::MutImmutable => ""
1045 if t_cast.is_trait() {
1046 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1048 fcx.tcx().sess.span_suggestion(t_span,
1049 "try casting to a reference instead:",
1050 format!("&{}{}", mtstr, s));
1053 span_help!(fcx.tcx().sess, t_span,
1054 "did you mean `&{}{}`?", mtstr, tstr),
1057 span_help!(fcx.tcx().sess, span,
1058 "consider using an implicit coercion to `&{}{}` instead",
1063 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1065 fcx.tcx().sess.span_suggestion(t_span,
1066 "try casting to a `Box` instead:",
1067 format!("Box<{}>", s));
1070 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1074 span_help!(fcx.tcx().sess, e_span,
1075 "consider using a box or reference as appropriate");
1078 fcx.write_error(id);
1082 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1083 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1085 fn get_item_type_scheme(&self, _: Span, id: ast::DefId)
1086 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1088 Ok(self.tcx().lookup_item_type(id))
1091 fn get_trait_def(&self, _: Span, id: ast::DefId)
1092 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1094 Ok(self.tcx().lookup_trait_def(id))
1097 fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
1098 // all super predicates are ensured during collect pass
1102 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1103 Some(&self.inh.infcx.parameter_environment.free_substs)
1106 fn get_type_parameter_bounds(&self,
1108 node_id: ast::NodeId)
1109 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1111 let def = self.tcx().type_parameter_def(node_id);
1112 let r = self.inh.infcx.parameter_environment
1115 .filter_map(|predicate| {
1117 ty::Predicate::Trait(ref data) => {
1118 if data.0.self_ty().is_param(def.space, def.index) {
1119 Some(data.to_poly_trait_ref())
1133 fn trait_defines_associated_type_named(&self,
1134 trait_def_id: ast::DefId,
1135 assoc_name: ast::Name)
1138 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1139 trait_def.associated_type_names.contains(&assoc_name)
1142 fn ty_infer(&self, default: Option<Ty<'tcx>>, _span: Span) -> Ty<'tcx> {
1143 let default = default.map(|t| type_variable::Default { ty: t });
1144 self.infcx().next_ty_var_with_default(default)
1147 fn projected_ty_from_poly_trait_ref(&self,
1149 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1150 item_name: ast::Name)
1153 let (trait_ref, _) =
1154 self.infcx().replace_late_bound_regions_with_fresh_var(
1156 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1159 self.normalize_associated_type(span, trait_ref, item_name)
1162 fn projected_ty(&self,
1164 trait_ref: ty::TraitRef<'tcx>,
1165 item_name: ast::Name)
1168 self.normalize_associated_type(span, trait_ref, item_name)
1172 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1173 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1175 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1179 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1180 &self.inh.infcx.parameter_environment
1183 pub fn sess(&self) -> &Session {
1187 pub fn err_count_since_creation(&self) -> usize {
1188 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1191 /// Resolves type variables in `ty` if possible. Unlike the infcx
1192 /// version, this version will also select obligations if it seems
1193 /// useful, in an effort to get more type information.
1194 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1195 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1197 // No TyInfer()? Nothing needs doing.
1198 if !ty.has_infer_types() {
1199 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1203 // If `ty` is a type variable, see whether we already know what it is.
1204 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1205 if !ty.has_infer_types() {
1206 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1210 // If not, try resolving any new fcx obligations that have cropped up.
1211 self.select_new_obligations();
1212 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1213 if !ty.has_infer_types() {
1214 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1218 // If not, try resolving *all* pending obligations as much as
1219 // possible. This can help substantially when there are
1220 // indirect dependencies that don't seem worth tracking
1222 self.select_obligations_where_possible();
1223 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1225 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1229 fn record_deferred_call_resolution(&self,
1230 closure_def_id: ast::DefId,
1231 r: DeferredCallResolutionHandler<'tcx>) {
1232 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1233 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1236 fn remove_deferred_call_resolutions(&self,
1237 closure_def_id: ast::DefId)
1238 -> Vec<DeferredCallResolutionHandler<'tcx>>
1240 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1241 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1244 pub fn tag(&self) -> String {
1245 let self_ptr: *const FnCtxt = self;
1246 format!("{:?}", self_ptr)
1249 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1250 match self.inh.locals.borrow().get(&nid) {
1253 self.tcx().sess.span_err(
1255 &format!("no type for local variable {}", nid));
1256 self.tcx().types.err
1262 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1263 debug!("write_ty({}, {:?}) in fcx {}",
1264 node_id, ty, self.tag());
1265 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1268 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1269 if !substs.substs.is_noop() {
1270 debug!("write_substs({}, {:?}) in fcx {}",
1275 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1279 pub fn write_autoderef_adjustment(&self,
1280 node_id: ast::NodeId,
1282 self.write_adjustment(
1284 ty::AdjustDerefRef(ty::AutoDerefRef {
1292 pub fn write_adjustment(&self,
1293 node_id: ast::NodeId,
1294 adj: ty::AutoAdjustment<'tcx>) {
1295 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1297 if adj.is_identity() {
1301 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1304 /// Basically whenever we are converting from a type scheme into
1305 /// the fn body space, we always want to normalize associated
1306 /// types as well. This function combines the two.
1307 fn instantiate_type_scheme<T>(&self,
1309 substs: &Substs<'tcx>,
1312 where T : TypeFoldable<'tcx> + HasTypeFlags
1314 let value = value.subst(self.tcx(), substs);
1315 let result = self.normalize_associated_types_in(span, &value);
1316 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1323 /// As `instantiate_type_scheme`, but for the bounds found in a
1324 /// generic type scheme.
1325 fn instantiate_bounds(&self,
1327 substs: &Substs<'tcx>,
1328 bounds: &ty::GenericPredicates<'tcx>)
1329 -> ty::InstantiatedPredicates<'tcx>
1331 ty::InstantiatedPredicates {
1332 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1337 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1338 where T : TypeFoldable<'tcx> + HasTypeFlags
1340 self.inh.normalize_associated_types_in(span, self.body_id, value)
1343 fn normalize_associated_type(&self,
1345 trait_ref: ty::TraitRef<'tcx>,
1346 item_name: ast::Name)
1349 let cause = traits::ObligationCause::new(span,
1351 traits::ObligationCauseCode::MiscObligation);
1356 .normalize_projection_type(self.infcx(),
1358 trait_ref: trait_ref,
1359 item_name: item_name,
1364 /// Returns the type of `def_id` with all generics replaced by by fresh type/region variables.
1365 /// Also returns the substitution from the type parameters on `def_id` to the fresh variables.
1366 /// Registers any trait obligations specified on `def_id` at the same time.
1368 /// Note that function is only intended to be used with types (notably, not fns). This is
1369 /// because it doesn't do any instantiation of late-bound regions.
1370 pub fn instantiate_type(&self,
1373 -> TypeAndSubsts<'tcx>
1376 self.tcx().lookup_item_type(def_id);
1377 let type_predicates =
1378 self.tcx().lookup_predicates(def_id);
1380 self.infcx().fresh_substs_for_generics(
1382 &type_scheme.generics);
1384 self.instantiate_bounds(span, &substs, &type_predicates);
1385 self.add_obligations_for_parameters(
1386 traits::ObligationCause::new(
1389 traits::ItemObligation(def_id)),
1392 self.instantiate_type_scheme(span, &substs, &type_scheme.ty);
1400 /// Returns the type that this AST path refers to. If the path has no type
1401 /// parameters and the corresponding type has type parameters, fresh type
1402 /// and/or region variables are substituted.
1404 /// This is used when checking the constructor in struct literals.
1405 fn instantiate_struct_literal_ty(&self,
1408 -> TypeAndSubsts<'tcx>
1410 let tcx = self.tcx();
1412 let ty::TypeScheme { generics, ty: decl_ty } =
1413 tcx.lookup_item_type(did);
1415 let substs = astconv::ast_path_substs_for_ty(self, self,
1417 PathParamMode::Optional,
1419 path.segments.last().unwrap());
1421 let ty = self.instantiate_type_scheme(path.span, &substs, &decl_ty);
1423 TypeAndSubsts { substs: substs, ty: ty }
1426 pub fn write_nil(&self, node_id: ast::NodeId) {
1427 self.write_ty(node_id, self.tcx().mk_nil());
1429 pub fn write_error(&self, node_id: ast::NodeId) {
1430 self.write_ty(node_id, self.tcx().types.err);
1433 pub fn require_type_meets(&self,
1436 code: traits::ObligationCauseCode<'tcx>,
1437 bound: ty::BuiltinBound)
1439 self.register_builtin_bound(
1442 traits::ObligationCause::new(span, self.body_id, code));
1445 pub fn require_type_is_sized(&self,
1448 code: traits::ObligationCauseCode<'tcx>)
1450 self.require_type_meets(ty, span, code, ty::BoundSized);
1453 pub fn require_expr_have_sized_type(&self,
1455 code: traits::ObligationCauseCode<'tcx>)
1457 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1460 pub fn type_is_known_to_be_sized(&self,
1465 traits::type_known_to_meet_builtin_bound(self.infcx(),
1471 pub fn register_builtin_bound(&self,
1473 builtin_bound: ty::BuiltinBound,
1474 cause: traits::ObligationCause<'tcx>)
1476 self.inh.infcx.fulfillment_cx.borrow_mut()
1477 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1480 pub fn register_predicate(&self,
1481 obligation: traits::PredicateObligation<'tcx>)
1483 debug!("register_predicate({:?})",
1485 self.inh.infcx.fulfillment_cx
1487 .register_predicate_obligation(self.infcx(), obligation);
1490 pub fn to_ty(&self, ast_t: &ast::Ty) -> Ty<'tcx> {
1491 let t = ast_ty_to_ty(self, self, ast_t);
1493 let mut bounds_checker = wf::BoundsChecker::new(self,
1496 bounds_checker.check_ty(t, ast_t.span);
1501 pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
1502 match self.inh.tables.borrow().node_types.get(&ex.id) {
1505 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1511 /// Apply `adjustment` to the type of `expr`
1512 pub fn adjust_expr_ty(&self,
1514 adjustment: Option<&ty::AutoAdjustment<'tcx>>)
1517 let raw_ty = self.expr_ty(expr);
1518 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1519 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1520 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1521 self.inh.tables.borrow().method_map.get(&method_call)
1522 .map(|method| resolve_ty(method.ty))
1526 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1527 match self.inh.tables.borrow().node_types.get(&id) {
1529 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1531 self.tcx().sess.bug(
1532 &format!("no type for node {}: {} in fcx {}",
1533 id, self.tcx().map.node_to_string(id),
1539 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1540 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1541 // it changes when we upgrade the snapshot compiler
1542 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1543 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1547 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1550 pub fn opt_node_ty_substs<F>(&self,
1553 F: FnOnce(&ty::ItemSubsts<'tcx>),
1555 match self.inh.tables.borrow().item_substs.get(&id) {
1561 pub fn mk_subty(&self,
1562 a_is_expected: bool,
1563 origin: infer::TypeOrigin,
1566 -> Result<(), ty::TypeError<'tcx>> {
1567 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1570 pub fn mk_eqty(&self,
1571 a_is_expected: bool,
1572 origin: infer::TypeOrigin,
1575 -> Result<(), ty::TypeError<'tcx>> {
1576 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1579 pub fn mk_subr(&self,
1580 origin: infer::SubregionOrigin<'tcx>,
1583 infer::mk_subr(self.infcx(), origin, sub, sup)
1586 pub fn type_error_message<M>(&self,
1589 actual_ty: Ty<'tcx>,
1590 err: Option<&ty::TypeError<'tcx>>) where
1591 M: FnOnce(String) -> String,
1593 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1596 pub fn report_mismatched_types(&self,
1600 err: &ty::TypeError<'tcx>) {
1601 self.infcx().report_mismatched_types(sp, e, a, err)
1604 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1605 /// outlive the region `r`.
1606 pub fn register_region_obligation(&self,
1609 cause: traits::ObligationCause<'tcx>)
1611 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1612 fulfillment_cx.register_region_obligation(ty, region, cause);
1615 pub fn add_default_region_param_bounds(&self,
1616 substs: &Substs<'tcx>,
1619 for &ty in &substs.types {
1620 let default_bound = ty::ReScope(CodeExtent::from_node_id(expr.id));
1621 let cause = traits::ObligationCause::new(expr.span, self.body_id,
1622 traits::MiscObligation);
1623 self.register_region_obligation(ty, default_bound, cause);
1627 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1628 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1629 /// trait/region obligations.
1631 /// For example, if there is a function:
1634 /// fn foo<'a,T:'a>(...)
1637 /// and a reference:
1643 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1644 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1645 pub fn add_obligations_for_parameters(&self,
1646 cause: traits::ObligationCause<'tcx>,
1647 predicates: &ty::InstantiatedPredicates<'tcx>)
1649 assert!(!predicates.has_escaping_regions());
1651 debug!("add_obligations_for_parameters(predicates={:?})",
1654 for obligation in traits::predicates_for_generics(cause, predicates) {
1655 self.register_predicate(obligation);
1659 // Only for fields! Returns <none> for methods>
1660 // Indifferent to privacy flags
1661 pub fn lookup_field_ty(&self,
1663 class_id: ast::DefId,
1664 items: &[ty::FieldTy],
1665 fieldname: ast::Name,
1666 substs: &subst::Substs<'tcx>)
1669 let o_field = items.iter().find(|f| f.name == fieldname);
1670 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1671 .map(|t| self.normalize_associated_types_in(span, &t))
1674 pub fn lookup_tup_field_ty(&self,
1676 class_id: ast::DefId,
1677 items: &[ty::FieldTy],
1679 substs: &subst::Substs<'tcx>)
1682 let o_field = if idx < items.len() { Some(&items[idx]) } else { None };
1683 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1684 .map(|t| self.normalize_associated_types_in(span, &t))
1687 fn check_casts(&self) {
1688 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1689 for cast in deferred_cast_checks.drain(..) {
1694 fn select_all_obligations_and_apply_defaults(&self) {
1695 use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
1697 // debug!("select_all_obligations_and_apply_defaults: defaults={:?}", self.infcx().defaults);
1699 for _ in (0..self.tcx().sess.recursion_limit.get()) {
1700 self.select_obligations_where_possible();
1702 let unsolved_variables = self.inh.infcx.unsolved_variables();
1703 let mut unbound_tyvars = HashSet::new();
1705 // Gather all unconstrainted integer and float variables
1706 for ty in &unsolved_variables {
1707 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1708 if self.infcx().type_var_diverges(resolved) {
1709 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1711 match self.infcx().type_is_unconstrained_numeric(resolved) {
1712 UnconstrainedInt => {
1713 unbound_tyvars.insert(resolved);
1715 UnconstrainedFloat => {
1716 unbound_tyvars.insert(resolved);
1723 // Collect the set of variables that need fallback applied
1724 for ty in &unsolved_variables {
1725 if let Some(_) = self.inh.infcx.default(ty) {
1726 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1728 // debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1729 // ty, self.inh.infcx.defaults.borrow().get(ty));
1731 match resolved.sty {
1732 ty::TyInfer(ty::TyVar(_)) => {
1733 unbound_tyvars.insert(ty);
1736 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1737 unbound_tyvars.insert(ty);
1738 if unbound_tyvars.contains(resolved) {
1739 unbound_tyvars.remove(resolved);
1748 if unbound_tyvars.is_empty() {
1752 // Go through the unbound variables and unify them with the proper fallbacks
1753 for ty in &unbound_tyvars {
1754 if self.infcx().type_var_diverges(ty) {
1755 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1757 match self.infcx().type_is_unconstrained_numeric(ty) {
1758 UnconstrainedInt => {
1759 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1761 UnconstrainedFloat => {
1762 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1765 if let Some(default) = self.inh.infcx.default(ty) {
1766 match infer::mk_eqty(self.infcx(), false,
1767 infer::Misc(codemap::DUMMY_SP),
1769 Ok(()) => { /* ok */ }
1771 self.infcx().report_conflicting_default_types(
1783 self.select_obligations_where_possible();
1787 fn select_all_obligations_or_error(&self) {
1788 debug!("select_all_obligations_or_error");
1790 // upvar inference should have ensured that all deferred call
1791 // resolutions are handled by now.
1792 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1794 self.select_all_obligations_and_apply_defaults();
1795 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1796 match fulfillment_cx.select_all_or_error(self.infcx()) {
1798 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1802 /// Select as many obligations as we can at present.
1803 fn select_obligations_where_possible(&self) {
1805 self.inh.infcx.fulfillment_cx
1807 .select_where_possible(self.infcx())
1810 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1814 /// Try to select any fcx obligation that we haven't tried yet, in an effort
1815 /// to improve inference. You could just call
1816 /// `select_obligations_where_possible` except that it leads to repeated
1818 fn select_new_obligations(&self) {
1820 self.inh.infcx.fulfillment_cx
1822 .select_new_obligations(self.infcx())
1825 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1831 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
1832 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1833 Some(self.base_object_lifetime_default(span))
1836 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1837 // RFC #599 specifies that object lifetime defaults take
1838 // precedence over other defaults. But within a fn body we
1839 // don't have a *default* region, rather we use inference to
1840 // find the *correct* region, which is strictly more general
1841 // (and anyway, within a fn body the right region may not even
1842 // be something the user can write explicitly, since it might
1843 // be some expression).
1844 self.infcx().next_region_var(infer::MiscVariable(span))
1847 fn anon_regions(&self, span: Span, count: usize)
1848 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1849 Ok((0..count).map(|_| {
1850 self.infcx().next_region_var(infer::MiscVariable(span))
1855 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1856 pub enum LvaluePreference {
1861 impl LvaluePreference {
1862 pub fn from_mutbl(m: ast::Mutability) -> Self {
1864 ast::MutMutable => PreferMutLvalue,
1865 ast::MutImmutable => NoPreference,
1870 /// Whether `autoderef` requires types to resolve.
1871 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1872 pub enum UnresolvedTypeAction {
1873 /// Produce an error and return `TyError` whenever a type cannot
1874 /// be resolved (i.e. it is `TyInfer`).
1876 /// Go on without emitting any errors, and return the unresolved
1877 /// type. Useful for probing, e.g. in coercions.
1881 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
1882 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
1884 /// Note: this method does not modify the adjustments table. The caller is responsible for
1885 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
1886 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
1889 opt_expr: Option<&ast::Expr>,
1890 unresolved_type_action: UnresolvedTypeAction,
1891 mut lvalue_pref: LvaluePreference,
1893 -> (Ty<'tcx>, usize, Option<T>)
1894 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
1896 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
1901 let mut t = base_ty;
1902 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
1903 let resolved_t = match unresolved_type_action {
1904 UnresolvedTypeAction::Error => {
1905 structurally_resolved_type(fcx, sp, t)
1907 UnresolvedTypeAction::Ignore => {
1908 // We can continue even when the type cannot be resolved
1909 // (i.e. it is an inference variable) because `Ty::builtin_deref`
1910 // and `try_overloaded_deref` both simply return `None`
1911 // in such a case without producing spurious errors.
1912 fcx.resolve_type_vars_if_possible(t)
1915 if resolved_t.references_error() {
1916 return (resolved_t, autoderefs, None);
1919 match should_stop(resolved_t, autoderefs) {
1920 Some(x) => return (resolved_t, autoderefs, Some(x)),
1924 // Otherwise, deref if type is derefable:
1925 let mt = match resolved_t.builtin_deref(false) {
1926 Some(mt) => Some(mt),
1929 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
1931 // Super subtle: it might seem as though we should
1932 // pass `opt_expr` to `try_overloaded_deref`, so that
1933 // the (implicit) autoref of using an overloaded deref
1934 // would get added to the adjustment table. However we
1935 // do not do that, because it's kind of a
1936 // "meta-adjustment" -- instead, we just leave it
1937 // unrecorded and know that there "will be" an
1938 // autoref. regionck and other bits of the code base,
1939 // when they encounter an overloaded autoderef, have
1940 // to do some reconstructive surgery. This is a pretty
1941 // complex mess that is begging for a proper MIR.
1942 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
1948 if mt.mutbl == ast::MutImmutable {
1949 lvalue_pref = NoPreference;
1952 None => return (resolved_t, autoderefs, None)
1956 // We've reached the recursion limit, error gracefully.
1957 span_err!(fcx.tcx().sess, sp, E0055,
1958 "reached the recursion limit while auto-dereferencing {:?}",
1960 (fcx.tcx().types.err, 0, None)
1963 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1965 method_call: Option<MethodCall>,
1966 base_expr: Option<&ast::Expr>,
1968 lvalue_pref: LvaluePreference)
1969 -> Option<ty::TypeAndMut<'tcx>>
1971 // Try DerefMut first, if preferred.
1972 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
1973 (PreferMutLvalue, Some(trait_did)) => {
1974 method::lookup_in_trait(fcx, span, base_expr,
1975 token::intern("deref_mut"), trait_did,
1981 // Otherwise, fall back to Deref.
1982 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
1983 (None, Some(trait_did)) => {
1984 method::lookup_in_trait(fcx, span, base_expr,
1985 token::intern("deref"), trait_did,
1988 (method, _) => method
1991 make_overloaded_lvalue_return_type(fcx, method_call, method)
1994 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
1995 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
1996 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
1997 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1998 method_call: Option<MethodCall>,
1999 method: Option<MethodCallee<'tcx>>)
2000 -> Option<ty::TypeAndMut<'tcx>>
2004 // extract method method return type, which will be &T;
2005 // all LB regions should have been instantiated during method lookup
2006 let ret_ty = method.ty.fn_ret();
2007 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2009 if let Some(method_call) = method_call {
2010 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2013 // method returns &T, but the type as visible to user is T, so deref
2014 ret_ty.builtin_deref(true)
2020 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2022 base_expr: &'tcx ast::Expr,
2025 lvalue_pref: LvaluePreference)
2026 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2028 // FIXME(#18741) -- this is almost but not quite the same as the
2029 // autoderef that normal method probing does. They could likely be
2032 let (ty, autoderefs, final_mt) = autoderef(fcx,
2036 UnresolvedTypeAction::Error,
2039 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2040 adj_ty, idx, false, lvalue_pref, idx_ty)
2043 if final_mt.is_some() {
2047 // After we have fully autoderef'd, if the resulting type is [T; n], then
2048 // do a final unsized coercion to yield [T].
2049 if let ty::TyArray(element_ty, _) = ty.sty {
2050 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2051 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2052 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2058 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2059 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2060 /// This loop implements one step in that search; the autoderef loop is implemented by
2061 /// `lookup_indexing`.
2062 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2063 method_call: MethodCall,
2065 base_expr: &'tcx ast::Expr,
2066 adjusted_ty: Ty<'tcx>,
2069 lvalue_pref: LvaluePreference,
2071 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2073 let tcx = fcx.tcx();
2074 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2075 autoderefs={}, unsize={}, index_ty={:?})",
2083 let input_ty = fcx.infcx().next_ty_var();
2085 // First, try built-in indexing.
2086 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2087 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2088 debug!("try_index_step: success, using built-in indexing");
2089 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2091 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2092 return Some((tcx.types.usize, ty));
2097 // Try `IndexMut` first, if preferred.
2098 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2099 (PreferMutLvalue, Some(trait_did)) => {
2100 method::lookup_in_trait_adjusted(fcx,
2103 token::intern("index_mut"),
2108 Some(vec![input_ty]))
2113 // Otherwise, fall back to `Index`.
2114 let method = match (method, tcx.lang_items.index_trait()) {
2115 (None, Some(trait_did)) => {
2116 method::lookup_in_trait_adjusted(fcx,
2119 token::intern("index"),
2124 Some(vec![input_ty]))
2126 (method, _) => method,
2129 // If some lookup succeeds, write callee into table and extract index/element
2130 // type from the method signature.
2131 // If some lookup succeeded, install method in table
2132 method.and_then(|method| {
2133 debug!("try_index_step: success, using overloaded indexing");
2134 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2135 map(|ret| (input_ty, ret.ty))
2139 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2141 method_fn_ty: Ty<'tcx>,
2142 callee_expr: &'tcx ast::Expr,
2143 args_no_rcvr: &'tcx [P<ast::Expr>],
2144 tuple_arguments: TupleArgumentsFlag,
2145 expected: Expectation<'tcx>)
2146 -> ty::FnOutput<'tcx> {
2147 if method_fn_ty.references_error() {
2148 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2150 let err_inputs = match tuple_arguments {
2151 DontTupleArguments => err_inputs,
2152 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2155 check_argument_types(fcx,
2162 ty::FnConverging(fcx.tcx().types.err)
2164 match method_fn_ty.sty {
2165 ty::TyBareFn(_, ref fty) => {
2166 // HACK(eddyb) ignore self in the definition (see above).
2167 let expected_arg_tys = expected_types_for_fn_args(fcx,
2171 &fty.sig.0.inputs[1..]);
2172 check_argument_types(fcx,
2174 &fty.sig.0.inputs[1..],
2175 &expected_arg_tys[..],
2182 fcx.tcx().sess.span_bug(callee_expr.span,
2183 "method without bare fn type");
2189 /// Generic function that factors out common logic from function calls, method calls and overloaded
2191 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2193 fn_inputs: &[Ty<'tcx>],
2194 expected_arg_tys: &[Ty<'tcx>],
2195 args: &'tcx [P<ast::Expr>],
2197 tuple_arguments: TupleArgumentsFlag) {
2198 let tcx = fcx.ccx.tcx;
2200 // Grab the argument types, supplying fresh type variables
2201 // if the wrong number of arguments were supplied
2202 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2208 let mut expected_arg_tys = expected_arg_tys;
2209 let expected_arg_count = fn_inputs.len();
2210 let formal_tys = if tuple_arguments == TupleArguments {
2211 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2212 match tuple_type.sty {
2213 ty::TyTuple(ref arg_types) => {
2214 if arg_types.len() != args.len() {
2215 span_err!(tcx.sess, sp, E0057,
2216 "this function takes {} parameter{} but {} parameter{} supplied",
2218 if arg_types.len() == 1 {""} else {"s"},
2220 if args.len() == 1 {" was"} else {"s were"});
2221 expected_arg_tys = &[];
2222 err_args(fcx.tcx(), args.len())
2224 expected_arg_tys = match expected_arg_tys.get(0) {
2225 Some(&ty) => match ty.sty {
2226 ty::TyTuple(ref tys) => &**tys,
2231 (*arg_types).clone()
2235 span_err!(tcx.sess, sp, E0059,
2236 "cannot use call notation; the first type parameter \
2237 for the function trait is neither a tuple nor unit");
2238 expected_arg_tys = &[];
2239 err_args(fcx.tcx(), args.len())
2242 } else if expected_arg_count == supplied_arg_count {
2244 } else if variadic {
2245 if supplied_arg_count >= expected_arg_count {
2248 span_err!(tcx.sess, sp, E0060,
2249 "this function takes at least {} parameter{} \
2250 but {} parameter{} supplied",
2252 if expected_arg_count == 1 {""} else {"s"},
2254 if supplied_arg_count == 1 {" was"} else {"s were"});
2255 expected_arg_tys = &[];
2256 err_args(fcx.tcx(), supplied_arg_count)
2259 span_err!(tcx.sess, sp, E0061,
2260 "this function takes {} parameter{} but {} parameter{} supplied",
2262 if expected_arg_count == 1 {""} else {"s"},
2264 if supplied_arg_count == 1 {" was"} else {"s were"});
2265 expected_arg_tys = &[];
2266 err_args(fcx.tcx(), supplied_arg_count)
2269 debug!("check_argument_types: formal_tys={:?}",
2270 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2272 // Check the arguments.
2273 // We do this in a pretty awful way: first we typecheck any arguments
2274 // that are not anonymous functions, then we typecheck the anonymous
2275 // functions. This is so that we have more information about the types
2276 // of arguments when we typecheck the functions. This isn't really the
2277 // right way to do this.
2278 let xs = [false, true];
2279 for check_blocks in &xs {
2280 let check_blocks = *check_blocks;
2281 debug!("check_blocks={}", check_blocks);
2283 // More awful hacks: before we check argument types, try to do
2284 // an "opportunistic" vtable resolution of any trait bounds on
2285 // the call. This helps coercions.
2287 fcx.select_new_obligations();
2290 // For variadic functions, we don't have a declared type for all of
2291 // the arguments hence we only do our usual type checking with
2292 // the arguments who's types we do know.
2293 let t = if variadic {
2295 } else if tuple_arguments == TupleArguments {
2300 for (i, arg) in args.iter().take(t).enumerate() {
2301 let is_block = match arg.node {
2302 ast::ExprClosure(..) => true,
2306 if is_block == check_blocks {
2307 debug!("checking the argument");
2308 let formal_ty = formal_tys[i];
2310 // The special-cased logic below has three functions:
2311 // 1. Provide as good of an expected type as possible.
2312 let expected = expected_arg_tys.get(i).map(|&ty| {
2313 Expectation::rvalue_hint(ty)
2316 check_expr_with_unifier(fcx, &**arg,
2317 expected.unwrap_or(ExpectHasType(formal_ty)),
2319 // 2. Coerce to the most detailed type that could be coerced
2320 // to, which is `expected_ty` if `rvalue_hint` returns an
2321 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2322 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2323 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2325 // 3. Relate the expected type and the formal one,
2326 // if the expected type was used for the coercion.
2327 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2333 // We also need to make sure we at least write the ty of the other
2334 // arguments which we skipped above.
2336 for arg in args.iter().skip(expected_arg_count) {
2337 check_expr(fcx, &**arg);
2339 // There are a few types which get autopromoted when passed via varargs
2340 // in C but we just error out instead and require explicit casts.
2341 let arg_ty = structurally_resolved_type(fcx, arg.span,
2342 fcx.expr_ty(&**arg));
2344 ty::TyFloat(ast::TyF32) => {
2345 fcx.type_error_message(arg.span,
2347 format!("can't pass an {} to variadic \
2348 function, cast to c_double", t)
2351 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2352 fcx.type_error_message(arg.span, |t| {
2353 format!("can't pass {} to variadic \
2354 function, cast to c_int",
2358 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2359 fcx.type_error_message(arg.span, |t| {
2360 format!("can't pass {} to variadic \
2361 function, cast to c_uint",
2371 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2372 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2373 (0..len).map(|_| tcx.types.err).collect()
2376 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2377 call_expr: &ast::Expr,
2378 output: ty::FnOutput<'tcx>) {
2379 fcx.write_ty(call_expr.id, match output {
2380 ty::FnConverging(output_ty) => output_ty,
2381 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2385 // AST fragment checking
2386 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2388 expected: Expectation<'tcx>)
2391 let tcx = fcx.ccx.tcx;
2394 ast::LitStr(..) => tcx.mk_static_str(),
2395 ast::LitBinary(ref v) => {
2396 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2397 tcx.mk_array(tcx.types.u8, v.len()))
2399 ast::LitByte(_) => tcx.types.u8,
2400 ast::LitChar(_) => tcx.types.char,
2401 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2402 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2403 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2404 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2406 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2407 ty::TyChar => Some(tcx.types.u8),
2408 ty::TyRawPtr(..) => Some(tcx.types.usize),
2409 ty::TyBareFn(..) => Some(tcx.types.usize),
2413 opt_ty.unwrap_or_else(
2414 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2416 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2417 ast::LitFloatUnsuffixed(_) => {
2418 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2420 ty::TyFloat(_) => Some(ty),
2424 opt_ty.unwrap_or_else(
2425 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2427 ast::LitBool(_) => tcx.types.bool
2431 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2432 expr: &'tcx ast::Expr,
2433 expected: Ty<'tcx>) {
2434 check_expr_with_unifier(
2435 fcx, expr, ExpectHasType(expected), NoPreference,
2436 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2439 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2440 expr: &'tcx ast::Expr,
2441 expected: Ty<'tcx>) {
2442 check_expr_with_unifier(
2443 fcx, expr, ExpectHasType(expected), NoPreference,
2444 || demand::coerce(fcx, expr.span, expected, expr));
2447 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx ast::Expr,
2448 expected: Ty<'tcx>) {
2449 check_expr_with_unifier(
2450 fcx, expr, ExpectHasType(expected), NoPreference,
2454 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2455 expr: &'tcx ast::Expr,
2456 expected: Expectation<'tcx>) {
2457 check_expr_with_unifier(
2458 fcx, expr, expected, NoPreference,
2462 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2463 expr: &'tcx ast::Expr,
2464 expected: Expectation<'tcx>,
2465 lvalue_pref: LvaluePreference)
2467 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2470 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr) {
2471 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2474 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr,
2475 lvalue_pref: LvaluePreference) {
2476 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2479 // determine the `self` type, using fresh variables for all variables
2480 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2481 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2483 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2484 span: Span, // (potential) receiver for this impl
2486 -> TypeAndSubsts<'tcx> {
2487 let tcx = fcx.tcx();
2489 let ity = tcx.lookup_item_type(did);
2490 let (tps, rps, raw_ty) =
2491 (ity.generics.types.get_slice(subst::TypeSpace),
2492 ity.generics.regions.get_slice(subst::TypeSpace),
2495 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2497 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2498 let tps = fcx.inh.infcx.type_vars_for_defs(tps);
2499 let substs = subst::Substs::new_type(tps, rps);
2500 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2502 TypeAndSubsts { substs: substs, ty: substd_ty }
2505 /// Controls whether the arguments are tupled. This is used for the call
2508 /// Tupling means that all call-side arguments are packed into a tuple and
2509 /// passed as a single parameter. For example, if tupling is enabled, this
2512 /// fn f(x: (isize, isize))
2514 /// Can be called as:
2521 #[derive(Clone, Eq, PartialEq)]
2522 enum TupleArgumentsFlag {
2527 /// Unifies the return type with the expected type early, for more coercions
2528 /// and forward type information on the argument expressions.
2529 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2531 expected_ret: Expectation<'tcx>,
2532 formal_ret: ty::FnOutput<'tcx>,
2533 formal_args: &[Ty<'tcx>])
2535 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2536 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2537 fcx.infcx().commit_regions_if_ok(|| {
2538 // Attempt to apply a subtyping relationship between the formal
2539 // return type (likely containing type variables if the function
2540 // is polymorphic) and the expected return type.
2541 // No argument expectations are produced if unification fails.
2542 let origin = infer::Misc(call_span);
2543 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2544 // FIXME(#15760) can't use try! here, FromError doesn't default
2545 // to identity so the resulting type is not constrained.
2546 if let Err(e) = ures {
2550 // Record all the argument types, with the substitutions
2551 // produced from the above subtyping unification.
2552 Ok(formal_args.iter().map(|ty| {
2553 fcx.infcx().resolve_type_vars_if_possible(ty)
2559 }).unwrap_or(vec![]);
2560 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2561 formal_args, formal_ret,
2562 expected_args, expected_ret);
2567 /// If an expression has any sub-expressions that result in a type error,
2568 /// inspecting that expression's type with `ty.references_error()` will return
2569 /// true. Likewise, if an expression is known to diverge, inspecting its
2570 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2571 /// strict, _|_ can appear in the type of an expression that does not,
2572 /// itself, diverge: for example, fn() -> _|_.)
2573 /// Note that inspecting a type's structure *directly* may expose the fact
2574 /// that there are actually multiple representations for `TyError`, so avoid
2575 /// that when err needs to be handled differently.
2576 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2577 expr: &'tcx ast::Expr,
2578 expected: Expectation<'tcx>,
2579 lvalue_pref: LvaluePreference,
2583 debug!(">> typechecking: expr={:?} expected={:?}",
2586 // Checks a method call.
2587 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2588 expr: &'tcx ast::Expr,
2589 method_name: ast::SpannedIdent,
2590 args: &'tcx [P<ast::Expr>],
2592 expected: Expectation<'tcx>,
2593 lvalue_pref: LvaluePreference) {
2594 let rcvr = &*args[0];
2595 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2597 // no need to check for bot/err -- callee does that
2598 let expr_t = structurally_resolved_type(fcx,
2600 fcx.expr_ty(&*rcvr));
2602 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2603 let fn_ty = match method::lookup(fcx,
2605 method_name.node.name,
2611 let method_ty = method.ty;
2612 let method_call = MethodCall::expr(expr.id);
2613 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2617 method::report_error(fcx, method_name.span, expr_t,
2618 method_name.node.name, Some(rcvr), error);
2619 fcx.write_error(expr.id);
2624 // Call the generic checker.
2625 let ret_ty = check_method_argument_types(fcx,
2633 write_call(fcx, expr, ret_ty);
2636 // A generic function for checking the then and else in an if
2638 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2639 cond_expr: &'tcx ast::Expr,
2640 then_blk: &'tcx ast::Block,
2641 opt_else_expr: Option<&'tcx ast::Expr>,
2644 expected: Expectation<'tcx>) {
2645 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2647 let expected = expected.adjust_for_branches(fcx);
2648 check_block_with_expected(fcx, then_blk, expected);
2649 let then_ty = fcx.node_ty(then_blk.id);
2651 let branches_ty = match opt_else_expr {
2652 Some(ref else_expr) => {
2653 check_expr_with_expectation(fcx, &**else_expr, expected);
2654 let else_ty = fcx.expr_ty(&**else_expr);
2655 infer::common_supertype(fcx.infcx(),
2656 infer::IfExpression(sp),
2662 infer::common_supertype(fcx.infcx(),
2663 infer::IfExpressionWithNoElse(sp),
2670 let cond_ty = fcx.expr_ty(cond_expr);
2671 let if_ty = if cond_ty.references_error() {
2677 fcx.write_ty(id, if_ty);
2680 // Check field access expressions
2681 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2682 expr: &'tcx ast::Expr,
2683 lvalue_pref: LvaluePreference,
2684 base: &'tcx ast::Expr,
2685 field: &ast::SpannedIdent) {
2686 let tcx = fcx.ccx.tcx;
2687 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2688 let expr_t = structurally_resolved_type(fcx, expr.span,
2690 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2691 let (_, autoderefs, field_ty) = autoderef(fcx,
2695 UnresolvedTypeAction::Error,
2699 ty::TyStruct(base_id, substs) => {
2700 debug!("struct named {:?}", base_t);
2701 let fields = tcx.lookup_struct_fields(base_id);
2702 fcx.lookup_field_ty(expr.span, base_id, &fields[..],
2703 field.node.name, &(*substs))
2710 fcx.write_ty(expr.id, field_ty);
2711 fcx.write_autoderef_adjustment(base.id, autoderefs);
2717 if method::exists(fcx, field.span, field.node.name, expr_t, expr.id) {
2718 fcx.type_error_message(
2721 format!("attempted to take value of method `{}` on type \
2722 `{}`", token::get_ident(field.node), actual)
2726 tcx.sess.fileline_help(field.span,
2727 "maybe a `()` to call it is missing? \
2728 If not, try an anonymous function");
2730 fcx.type_error_message(
2733 format!("attempted access of field `{}` on \
2734 type `{}`, but no field with that \
2736 token::get_ident(field.node),
2740 if let ty::TyStruct(did, _) = expr_t.sty {
2741 suggest_field_names(did, field, tcx, vec![]);
2745 fcx.write_error(expr.id);
2748 // displays hints about the closest matches in field names
2749 fn suggest_field_names<'tcx>(id : DefId,
2750 field : &ast::SpannedIdent,
2751 tcx : &ty::ctxt<'tcx>,
2753 let ident = token::get_ident(field.node);
2755 // only find fits with at least one matching letter
2756 let mut best_dist = name.len();
2757 let fields = tcx.lookup_struct_fields(id);
2758 let mut best = None;
2759 for elem in &fields {
2760 let n = elem.name.as_str();
2761 // ignore already set fields
2762 if skip.iter().any(|&x| x == n) {
2765 // ignore private fields from non-local crates
2766 if id.krate != ast::LOCAL_CRATE && elem.vis != Visibility::Public {
2769 let dist = lev_distance(n, name);
2770 if dist < best_dist {
2775 if let Some(n) = best {
2776 tcx.sess.span_help(field.span,
2777 &format!("did you mean `{}`?", n));
2781 // Check tuple index expressions
2782 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2783 expr: &'tcx ast::Expr,
2784 lvalue_pref: LvaluePreference,
2785 base: &'tcx ast::Expr,
2786 idx: codemap::Spanned<usize>) {
2787 let tcx = fcx.ccx.tcx;
2788 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2789 let expr_t = structurally_resolved_type(fcx, expr.span,
2791 let mut tuple_like = false;
2792 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2793 let (_, autoderefs, field_ty) = autoderef(fcx,
2797 UnresolvedTypeAction::Error,
2801 ty::TyStruct(base_id, substs) => {
2802 tuple_like = tcx.is_tuple_struct(base_id);
2804 debug!("tuple struct named {:?}", base_t);
2805 let fields = tcx.lookup_struct_fields(base_id);
2806 fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
2807 idx.node, &(*substs))
2812 ty::TyTuple(ref v) => {
2814 if idx.node < v.len() { Some(v[idx.node]) } else { None }
2821 fcx.write_ty(expr.id, field_ty);
2822 fcx.write_autoderef_adjustment(base.id, autoderefs);
2827 fcx.type_error_message(
2831 format!("attempted out-of-bounds tuple index `{}` on \
2836 format!("attempted tuple index `{}` on type `{}`, but the \
2837 type was not a tuple or tuple struct",
2844 fcx.write_error(expr.id);
2847 fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2848 struct_ty: Ty<'tcx>,
2850 class_id: ast::DefId,
2851 node_id: ast::NodeId,
2852 substitutions: &'tcx subst::Substs<'tcx>,
2853 field_types: &[ty::FieldTy],
2854 ast_fields: &'tcx [ast::Field],
2855 check_completeness: bool,
2856 enum_id_opt: Option<ast::DefId>) {
2857 let tcx = fcx.ccx.tcx;
2859 let mut class_field_map = FnvHashMap();
2860 let mut fields_found = 0;
2861 for field in field_types {
2862 class_field_map.insert(field.name, (field.id, false));
2865 let mut error_happened = false;
2867 // Typecheck each field.
2868 for field in ast_fields {
2869 let mut expected_field_type = tcx.types.err;
2871 let pair = class_field_map.get(&field.ident.node.name).cloned();
2874 fcx.type_error_message(
2876 |actual| match enum_id_opt {
2878 let variant_type = tcx.enum_variant_with_id(enum_id,
2880 format!("struct variant `{}::{}` has no field named `{}`",
2881 actual, variant_type.name.as_str(),
2882 token::get_ident(field.ident.node))
2885 format!("structure `{}` has no field named `{}`",
2887 token::get_ident(field.ident.node))
2892 // prevent all specified fields from being suggested
2893 let skip_fields = ast_fields.iter().map(|ref x| x.ident.node.name.as_str());
2894 let actual_id = match enum_id_opt {
2895 Some(_) => class_id,
2896 None => struct_ty.ty_to_def_id().unwrap()
2898 suggest_field_names(actual_id, &field.ident, tcx, skip_fields.collect());
2899 error_happened = true;
2901 Some((_, true)) => {
2902 span_err!(fcx.tcx().sess, field.ident.span, E0062,
2903 "field `{}` specified more than once",
2904 token::get_ident(field.ident.node));
2905 error_happened = true;
2907 Some((field_id, false)) => {
2908 expected_field_type =
2909 tcx.lookup_field_type(class_id, field_id, substitutions);
2910 expected_field_type =
2911 fcx.normalize_associated_types_in(
2912 field.span, &expected_field_type);
2913 class_field_map.insert(
2914 field.ident.node.name, (field_id, true));
2919 // Make sure to give a type to the field even if there's
2920 // an error, so we can continue typechecking
2921 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
2925 fcx.write_error(node_id);
2928 if check_completeness && !error_happened {
2929 // Make sure the programmer specified all the fields.
2930 assert!(fields_found <= field_types.len());
2931 if fields_found < field_types.len() {
2932 let mut missing_fields = Vec::new();
2933 for class_field in field_types {
2934 let name = class_field.name;
2935 let (_, seen) = *class_field_map.get(&name).unwrap();
2937 missing_fields.push(
2938 format!("`{}`", &token::get_name(name)))
2942 span_err!(tcx.sess, span, E0063,
2943 "missing field{}: {}",
2944 if missing_fields.len() == 1 {""} else {"s"},
2945 missing_fields.join(", "));
2949 if !error_happened {
2950 fcx.write_ty(node_id, fcx.ccx.tcx.mk_struct(class_id, substitutions));
2954 fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2956 span: codemap::Span,
2957 class_id: ast::DefId,
2958 fields: &'tcx [ast::Field],
2959 base_expr: Option<&'tcx ast::Expr>) {
2960 let tcx = fcx.ccx.tcx;
2962 // Generate the struct type.
2964 ty: mut struct_type,
2965 substs: struct_substs
2966 } = fcx.instantiate_type(span, class_id);
2968 // Look up and check the fields.
2969 let class_fields = tcx.lookup_struct_fields(class_id);
2970 check_struct_or_variant_fields(fcx,
2975 fcx.ccx.tcx.mk_substs(struct_substs),
2978 base_expr.is_none(),
2980 if fcx.node_ty(id).references_error() {
2981 struct_type = tcx.types.err;
2984 // Check the base expression if necessary.
2987 Some(base_expr) => {
2988 check_expr_has_type(fcx, &*base_expr, struct_type);
2992 // Write in the resulting type.
2993 fcx.write_ty(id, struct_type);
2996 fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2998 span: codemap::Span,
2999 enum_id: ast::DefId,
3000 variant_id: ast::DefId,
3001 fields: &'tcx [ast::Field]) {
3002 let tcx = fcx.ccx.tcx;
3004 // Look up the number of type parameters and the raw type, and
3005 // determine whether the enum is region-parameterized.
3008 substs: substitutions
3009 } = fcx.instantiate_type(span, enum_id);
3011 // Look up and check the enum variant fields.
3012 let variant_fields = tcx.lookup_struct_fields(variant_id);
3013 check_struct_or_variant_fields(fcx,
3018 fcx.ccx.tcx.mk_substs(substitutions),
3019 &variant_fields[..],
3023 fcx.write_ty(id, enum_type);
3026 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3028 fields: &'tcx [ast::Field],
3029 base_expr: &'tcx Option<P<ast::Expr>>) {
3030 // Make sure to still write the types
3031 // otherwise we might ICE
3032 fcx.write_error(id);
3033 for field in fields {
3034 check_expr(fcx, &*field.expr);
3037 Some(ref base) => check_expr(fcx, &**base),
3042 type ExprCheckerWithTy = fn(&FnCtxt, &ast::Expr, Ty);
3044 let tcx = fcx.ccx.tcx;
3047 ast::ExprBox(ref opt_place, ref subexpr) => {
3048 opt_place.as_ref().map(|place|check_expr(fcx, &**place));
3049 check_expr(fcx, &**subexpr);
3051 let mut checked = false;
3052 opt_place.as_ref().map(|place| match place.node {
3053 ast::ExprPath(None, ref path) => {
3054 // FIXME(pcwalton): For now we hardcode the only permissible
3055 // place: the exchange heap.
3056 let definition = lookup_full_def(tcx, path.span, place.id);
3057 let def_id = definition.def_id();
3058 let referent_ty = fcx.expr_ty(&**subexpr);
3059 if tcx.lang_items.exchange_heap() == Some(def_id) {
3060 fcx.write_ty(id, tcx.mk_box(referent_ty));
3068 span_err!(tcx.sess, expr.span, E0066,
3069 "only the exchange heap is currently supported");
3070 fcx.write_ty(id, tcx.types.err);
3074 ast::ExprLit(ref lit) => {
3075 let typ = check_lit(fcx, &**lit, expected);
3076 fcx.write_ty(id, typ);
3078 ast::ExprBinary(op, ref lhs, ref rhs) => {
3079 op::check_binop(fcx, expr, op, lhs, rhs);
3081 ast::ExprAssignOp(op, ref lhs, ref rhs) => {
3082 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3084 ast::ExprUnary(unop, ref oprnd) => {
3085 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3087 ast::UnUniq => match ty.sty {
3089 Expectation::rvalue_hint(ty)
3095 ast::UnNot | ast::UnNeg => {
3103 let lvalue_pref = match unop {
3104 ast::UnDeref => lvalue_pref,
3107 check_expr_with_expectation_and_lvalue_pref(
3108 fcx, &**oprnd, expected_inner, lvalue_pref);
3109 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3111 if !oprnd_t.references_error() {
3114 oprnd_t = tcx.mk_box(oprnd_t);
3117 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3118 oprnd_t = match oprnd_t.builtin_deref(true) {
3120 None => match try_overloaded_deref(fcx, expr.span,
3121 Some(MethodCall::expr(expr.id)),
3122 Some(&**oprnd), oprnd_t, lvalue_pref) {
3125 fcx.type_error_message(expr.span, |actual| {
3126 format!("type `{}` cannot be \
3127 dereferenced", actual)
3135 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3137 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3138 oprnd_t = op::check_user_unop(fcx, "!", "not",
3139 tcx.lang_items.not_trait(),
3140 expr, &**oprnd, oprnd_t, unop);
3144 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3146 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3147 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3148 tcx.lang_items.neg_trait(),
3149 expr, &**oprnd, oprnd_t, unop);
3154 fcx.write_ty(id, oprnd_t);
3156 ast::ExprAddrOf(mutbl, ref oprnd) => {
3157 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3159 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3160 if fcx.tcx().expr_is_lval(&**oprnd) {
3161 // Lvalues may legitimately have unsized types.
3162 // For example, dereferences of a fat pointer and
3163 // the last field of a struct can be unsized.
3164 ExpectHasType(mt.ty)
3166 Expectation::rvalue_hint(mt.ty)
3172 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3173 check_expr_with_expectation_and_lvalue_pref(fcx,
3178 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3179 let oprnd_t = if tm.ty.references_error() {
3182 // Note: at this point, we cannot say what the best lifetime
3183 // is to use for resulting pointer. We want to use the
3184 // shortest lifetime possible so as to avoid spurious borrowck
3185 // errors. Moreover, the longest lifetime will depend on the
3186 // precise details of the value whose address is being taken
3187 // (and how long it is valid), which we don't know yet until type
3188 // inference is complete.
3190 // Therefore, here we simply generate a region variable. The
3191 // region inferencer will then select the ultimate value.
3192 // Finally, borrowck is charged with guaranteeing that the
3193 // value whose address was taken can actually be made to live
3194 // as long as it needs to live.
3195 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3196 tcx.mk_ref(tcx.mk_region(region), tm)
3198 fcx.write_ty(id, oprnd_t);
3200 ast::ExprPath(ref maybe_qself, ref path) => {
3201 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3202 fcx.to_ty(&qself.ty)
3205 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3207 } else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
3208 // Create some fake resolution that can't possibly be a type.
3209 def::PathResolution {
3210 base_def: def::DefMod(local_def(ast::CRATE_NODE_ID)),
3211 last_private: LastMod(AllPublic),
3212 depth: path.segments.len()
3215 tcx.sess.span_bug(expr.span,
3216 &format!("unbound path {:?}", expr))
3219 if let Some((opt_ty, segments, def)) =
3220 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3221 expr.span, expr.id) {
3222 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3225 instantiate_path(fcx,
3235 // We always require that the type provided as the value for
3236 // a type parameter outlives the moment of instantiation.
3237 constrain_path_type_parameters(fcx, expr);
3239 ast::ExprInlineAsm(ref ia) => {
3240 for &(_, ref input) in &ia.inputs {
3241 check_expr(fcx, &**input);
3243 for &(_, ref out, _) in &ia.outputs {
3244 check_expr(fcx, &**out);
3248 ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
3249 ast::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3250 ast::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3251 ast::ExprRet(ref expr_opt) => {
3253 ty::FnConverging(result_type) => {
3256 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3257 result_type, fcx.tcx().mk_nil()) {
3258 span_err!(tcx.sess, expr.span, E0069,
3259 "`return;` in a function whose return type is \
3263 check_expr_coercable_to_type(fcx, &**e, result_type);
3267 ty::FnDiverging => {
3268 if let Some(ref e) = *expr_opt {
3269 check_expr(fcx, &**e);
3271 span_err!(tcx.sess, expr.span, E0166,
3272 "`return` in a function declared as diverging");
3275 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3277 ast::ExprParen(ref a) => {
3278 check_expr_with_expectation_and_lvalue_pref(fcx,
3282 fcx.write_ty(id, fcx.expr_ty(&**a));
3284 ast::ExprAssign(ref lhs, ref rhs) => {
3285 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3287 let tcx = fcx.tcx();
3288 if !tcx.expr_is_lval(&**lhs) {
3289 span_err!(tcx.sess, expr.span, E0070,
3290 "illegal left-hand side expression");
3293 let lhs_ty = fcx.expr_ty(&**lhs);
3294 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3295 let rhs_ty = fcx.expr_ty(&**rhs);
3297 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3299 if lhs_ty.references_error() || rhs_ty.references_error() {
3300 fcx.write_error(id);
3305 ast::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3306 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3307 id, expr.span, expected);
3309 ast::ExprIfLet(..) => {
3310 tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
3312 ast::ExprWhile(ref cond, ref body, _) => {
3313 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3314 check_block_no_value(fcx, &**body);
3315 let cond_ty = fcx.expr_ty(&**cond);
3316 let body_ty = fcx.node_ty(body.id);
3317 if cond_ty.references_error() || body_ty.references_error() {
3318 fcx.write_error(id);
3324 ast::ExprWhileLet(..) => {
3325 tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
3327 ast::ExprForLoop(..) => {
3328 tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
3330 ast::ExprLoop(ref body, _) => {
3331 check_block_no_value(fcx, &**body);
3332 if !may_break(tcx, expr.id, &**body) {
3333 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3338 ast::ExprMatch(ref discrim, ref arms, match_src) => {
3339 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3341 ast::ExprClosure(capture, ref decl, ref body) => {
3342 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3344 ast::ExprBlock(ref b) => {
3345 check_block_with_expected(fcx, &**b, expected);
3346 fcx.write_ty(id, fcx.node_ty(b.id));
3348 ast::ExprCall(ref callee, ref args) => {
3349 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3351 ast::ExprMethodCall(ident, ref tps, ref args) => {
3352 check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref);
3353 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3354 let args_err = arg_tys.fold(false,
3356 rest_err || a.references_error()});
3358 fcx.write_error(id);
3361 ast::ExprCast(ref e, ref t) => {
3362 if let ast::TyFixedLengthVec(_, ref count_expr) = t.node {
3363 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3366 // Find the type of `e`. Supply hints based on the type we are casting to,
3368 let t_cast = fcx.to_ty(t);
3369 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3370 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3371 let t_expr = fcx.expr_ty(e);
3373 // Eagerly check for some obvious errors.
3374 if t_expr.references_error() {
3375 fcx.write_error(id);
3376 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3377 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3379 // Write a type for the whole expression, assuming everything is going
3381 fcx.write_ty(id, t_cast);
3383 // Defer other checks until we're done type checking.
3384 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3385 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3386 deferred_cast_checks.push(cast_check);
3389 ast::ExprVec(ref args) => {
3390 let uty = expected.to_option(fcx).and_then(|uty| {
3392 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3397 let typ = match uty {
3400 check_expr_coercable_to_type(fcx, &**e, uty);
3405 let t: Ty = fcx.infcx().next_ty_var();
3407 check_expr_has_type(fcx, &**e, t);
3412 let typ = tcx.mk_array(typ, args.len());
3413 fcx.write_ty(id, typ);
3415 ast::ExprRepeat(ref element, ref count_expr) => {
3416 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3417 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3419 let uty = match expected {
3420 ExpectHasType(uty) => {
3422 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3429 let (element_ty, t) = match uty {
3431 check_expr_coercable_to_type(fcx, &**element, uty);
3435 let t: Ty = fcx.infcx().next_ty_var();
3436 check_expr_has_type(fcx, &**element, t);
3437 (fcx.expr_ty(&**element), t)
3442 // For [foo, ..n] where n > 1, `foo` must have
3444 fcx.require_type_meets(
3451 if element_ty.references_error() {
3452 fcx.write_error(id);
3454 let t = tcx.mk_array(t, count);
3455 fcx.write_ty(id, t);
3458 ast::ExprTup(ref elts) => {
3459 let flds = expected.only_has_type(fcx).and_then(|ty| {
3461 ty::TyTuple(ref flds) => Some(&flds[..]),
3465 let mut err_field = false;
3467 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3468 let t = match flds {
3469 Some(ref fs) if i < fs.len() => {
3471 check_expr_coercable_to_type(fcx, &**e, ety);
3475 check_expr_with_expectation(fcx, &**e, NoExpectation);
3479 err_field = err_field || t.references_error();
3483 fcx.write_error(id);
3485 let typ = tcx.mk_tup(elt_ts);
3486 fcx.write_ty(id, typ);
3489 ast::ExprStruct(ref path, ref fields, ref base_expr) => {
3490 // Resolve the path.
3491 let def = lookup_full_def(tcx, path.span, id);
3492 let struct_id = match def {
3493 def::DefVariant(enum_id, variant_id, true) => {
3494 if let &Some(ref base_expr) = base_expr {
3495 span_err!(tcx.sess, base_expr.span, E0436,
3496 "functional record update syntax requires a struct");
3497 fcx.write_error(base_expr.id);
3499 check_struct_enum_variant(fcx, id, expr.span, enum_id,
3500 variant_id, &fields[..]);
3503 def::DefTrait(def_id) => {
3504 span_err!(tcx.sess, path.span, E0159,
3505 "use of trait `{}` as a struct constructor",
3506 pprust::path_to_string(path));
3507 check_struct_fields_on_error(fcx,
3514 // Verify that this was actually a struct.
3515 let typ = fcx.ccx.tcx.lookup_item_type(def.def_id());
3517 ty::TyStruct(struct_did, _) => {
3518 check_struct_constructor(fcx,
3523 base_expr.as_ref().map(|e| &**e));
3526 span_err!(tcx.sess, path.span, E0071,
3527 "`{}` does not name a structure",
3528 pprust::path_to_string(path));
3529 check_struct_fields_on_error(fcx,
3540 // Turn the path into a type and verify that that type unifies with
3541 // the resulting structure type. This is needed to handle type
3542 // parameters correctly.
3543 let actual_structure_type = fcx.expr_ty(&*expr);
3544 if !actual_structure_type.references_error() {
3545 let type_and_substs = fcx.instantiate_struct_literal_ty(struct_id, path);
3546 match fcx.mk_subty(false,
3547 infer::Misc(path.span),
3548 actual_structure_type,
3549 type_and_substs.ty) {
3551 Err(type_error) => {
3552 span_err!(fcx.tcx().sess, path.span, E0235,
3553 "structure constructor specifies a \
3554 structure of type `{}`, but this \
3555 structure has type `{}`: {}",
3557 .ty_to_string(type_and_substs.ty),
3560 actual_structure_type),
3562 tcx.note_and_explain_type_err(&type_error, path.span);
3567 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3569 ast::ExprField(ref base, ref field) => {
3570 check_field(fcx, expr, lvalue_pref, &**base, field);
3572 ast::ExprTupField(ref base, idx) => {
3573 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3575 ast::ExprIndex(ref base, ref idx) => {
3576 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3577 check_expr(fcx, &**idx);
3579 let base_t = fcx.expr_ty(&**base);
3580 let idx_t = fcx.expr_ty(&**idx);
3582 if base_t.references_error() {
3583 fcx.write_ty(id, base_t);
3584 } else if idx_t.references_error() {
3585 fcx.write_ty(id, idx_t);
3587 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3588 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3589 Some((index_ty, element_ty)) => {
3590 let idx_expr_ty = fcx.expr_ty(idx);
3591 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3592 fcx.write_ty(id, element_ty);
3595 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3596 fcx.type_error_message(
3599 format!("cannot index a value of type `{}`",
3604 fcx.write_ty(id, fcx.tcx().types.err);
3609 ast::ExprRange(ref start, ref end) => {
3610 let t_start = start.as_ref().map(|e| {
3611 check_expr(fcx, &**e);
3614 let t_end = end.as_ref().map(|e| {
3615 check_expr(fcx, &**e);
3619 let idx_type = match (t_start, t_end) {
3620 (Some(ty), None) | (None, Some(ty)) => {
3623 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3624 t_end.references_error()) => {
3625 Some(fcx.tcx().types.err)
3627 (Some(t_start), Some(t_end)) => {
3628 Some(infer::common_supertype(fcx.infcx(),
3629 infer::RangeExpression(expr.span),
3637 // Note that we don't check the type of start/end satisfy any
3638 // bounds because right now the range structs do not have any. If we add
3639 // some bounds, then we'll need to check `t_start` against them here.
3641 let range_type = match idx_type {
3642 Some(idx_type) if idx_type.references_error() => {
3646 // Find the did from the appropriate lang item.
3647 let did = match (start, end) {
3648 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3649 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3650 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3652 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3656 if let Some(did) = did {
3657 let predicates = tcx.lookup_predicates(did);
3658 let substs = Substs::new_type(vec![idx_type], vec![]);
3659 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3660 fcx.add_obligations_for_parameters(
3661 traits::ObligationCause::new(expr.span,
3663 traits::ItemObligation(did)),
3666 tcx.mk_struct(did, tcx.mk_substs(substs))
3668 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3673 // Neither start nor end => RangeFull
3674 if let Some(did) = tcx.lang_items.range_full_struct() {
3675 let substs = Substs::new_type(vec![], vec![]);
3676 tcx.mk_struct(did, tcx.mk_substs(substs))
3678 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3684 fcx.write_ty(id, range_type);
3689 debug!("type of expr({}) {} is...", expr.id,
3690 syntax::print::pprust::expr_to_string(expr));
3691 debug!("... {:?}, expected is {:?}",
3698 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3699 path_res: def::PathResolution,
3700 opt_self_ty: Option<Ty<'tcx>>,
3701 path: &'a ast::Path,
3703 node_id: ast::NodeId)
3704 -> Option<(Option<Ty<'tcx>>,
3705 &'a [ast::PathSegment],
3709 // Associated constants can't depend on generic types.
3710 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3714 node_id: ast::NodeId) -> bool {
3716 def::DefAssociatedConst(..) => {
3717 if ty.has_param_types() || ty.has_self_ty() {
3718 span_err!(fcx.sess(), span, E0329,
3719 "Associated consts cannot depend \
3720 on type parameters or Self.");
3721 fcx.write_error(node_id);
3730 // If fully resolved already, we don't have to do anything.
3731 if path_res.depth == 0 {
3732 if let Some(ty) = opt_self_ty {
3733 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3738 Some((opt_self_ty, &path.segments, path_res.base_def))
3740 let mut def = path_res.base_def;
3741 let ty_segments = path.segments.split_last().unwrap().1;
3742 let base_ty_end = path.segments.len() - path_res.depth;
3743 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3744 PathParamMode::Optional,
3747 &ty_segments[..base_ty_end],
3748 &ty_segments[base_ty_end..]);
3749 let item_segment = path.segments.last().unwrap();
3750 let item_name = item_segment.identifier.name;
3751 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3753 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3756 // Write back the new resolution.
3757 fcx.ccx.tcx.def_map.borrow_mut()
3758 .insert(node_id, def::PathResolution {
3760 last_private: path_res.last_private.or(lp),
3763 Some((Some(ty), slice::ref_slice(item_segment), def))
3766 method::report_error(fcx, span, ty,
3767 item_name, None, error);
3768 fcx.write_error(node_id);
3775 fn constrain_path_type_parameters(fcx: &FnCtxt,
3778 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3779 fcx.add_default_region_param_bounds(&item_substs.substs, expr);
3783 impl<'tcx> Expectation<'tcx> {
3784 /// Provide an expectation for an rvalue expression given an *optional*
3785 /// hint, which is not required for type safety (the resulting type might
3786 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3787 /// is useful in determining the concrete type.
3789 /// The primary use case is where the expected type is a fat pointer,
3790 /// like `&[isize]`. For example, consider the following statement:
3792 /// let x: &[isize] = &[1, 2, 3];
3794 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3795 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3796 /// expectation `ExpectHasType([isize])`, that would be too strong --
3797 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3798 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3799 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3800 /// which still is useful, because it informs integer literals and the like.
3801 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3802 /// for examples of where this comes up,.
3803 fn rvalue_hint(ty: Ty<'tcx>) -> Expectation<'tcx> {
3805 ty::TySlice(_) | ty::TyTrait(..) => {
3806 ExpectRvalueLikeUnsized(ty)
3808 _ => ExpectHasType(ty)
3812 // Resolves `expected` by a single level if it is a variable. If
3813 // there is no expected type or resolution is not possible (e.g.,
3814 // no constraints yet present), just returns `None`.
3815 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3820 ExpectCastableToType(t) => {
3821 ExpectCastableToType(
3822 fcx.infcx().resolve_type_vars_if_possible(&t))
3824 ExpectHasType(t) => {
3826 fcx.infcx().resolve_type_vars_if_possible(&t))
3828 ExpectRvalueLikeUnsized(t) => {
3829 ExpectRvalueLikeUnsized(
3830 fcx.infcx().resolve_type_vars_if_possible(&t))
3835 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3836 match self.resolve(fcx) {
3837 NoExpectation => None,
3838 ExpectCastableToType(ty) |
3840 ExpectRvalueLikeUnsized(ty) => Some(ty),
3844 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3845 match self.resolve(fcx) {
3846 ExpectHasType(ty) => Some(ty),
3852 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3853 local: &'tcx ast::Local,
3854 init: &'tcx ast::Expr)
3856 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3858 let local_ty = fcx.local_ty(init.span, local.id);
3859 if let Some(m) = ref_bindings {
3860 // Somewhat subtle: if we have a `ref` binding in the pattern,
3861 // we want to avoid introducing coercions for the RHS. This is
3862 // both because it helps preserve sanity and, in the case of
3863 // ref mut, for soundness (issue #23116). In particular, in
3864 // the latter case, we need to be clear that the type of the
3865 // referent for the reference that results is *equal to* the
3866 // type of the lvalue it is referencing, and not some
3867 // supertype thereof.
3868 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3869 let init_ty = fcx.expr_ty(init);
3870 demand::eqtype(fcx, init.span, init_ty, local_ty);
3872 check_expr_coercable_to_type(fcx, init, local_ty)
3876 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local) {
3877 let tcx = fcx.ccx.tcx;
3879 let t = fcx.local_ty(local.span, local.id);
3880 fcx.write_ty(local.id, t);
3882 if let Some(ref init) = local.init {
3883 check_decl_initializer(fcx, local, &**init);
3884 let init_ty = fcx.expr_ty(&**init);
3885 if init_ty.references_error() {
3886 fcx.write_ty(local.id, init_ty);
3890 let pcx = pat_ctxt {
3892 map: pat_id_map(&tcx.def_map, &*local.pat),
3894 _match::check_pat(&pcx, &*local.pat, t);
3895 let pat_ty = fcx.node_ty(local.pat.id);
3896 if pat_ty.references_error() {
3897 fcx.write_ty(local.id, pat_ty);
3901 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
3903 let mut saw_bot = false;
3904 let mut saw_err = false;
3906 ast::StmtDecl(ref decl, id) => {
3909 ast::DeclLocal(ref l) => {
3910 check_decl_local(fcx, &**l);
3911 let l_t = fcx.node_ty(l.id);
3912 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3913 saw_err = saw_err || l_t.references_error();
3915 ast::DeclItem(_) => {/* ignore for now */ }
3918 ast::StmtExpr(ref expr, id) => {
3920 // Check with expected type of ()
3921 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3922 let expr_ty = fcx.expr_ty(&**expr);
3923 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3924 saw_err = saw_err || expr_ty.references_error();
3926 ast::StmtSemi(ref expr, id) => {
3928 check_expr(fcx, &**expr);
3929 let expr_ty = fcx.expr_ty(&**expr);
3930 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3931 saw_err |= expr_ty.references_error();
3933 ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro")
3936 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3939 fcx.write_error(node_id);
3942 fcx.write_nil(node_id)
3946 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) {
3947 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3948 let blkty = fcx.node_ty(blk.id);
3949 if blkty.references_error() {
3950 fcx.write_error(blk.id);
3952 let nilty = fcx.tcx().mk_nil();
3953 demand::suptype(fcx, blk.span, nilty, blkty);
3957 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3958 blk: &'tcx ast::Block,
3959 expected: Expectation<'tcx>) {
3961 let mut fcx_ps = fcx.ps.borrow_mut();
3962 let unsafety_state = fcx_ps.recurse(blk);
3963 replace(&mut *fcx_ps, unsafety_state)
3966 let mut warned = false;
3967 let mut any_diverges = false;
3968 let mut any_err = false;
3969 for s in &blk.stmts {
3970 check_stmt(fcx, &**s);
3971 let s_id = ast_util::stmt_id(&**s);
3972 let s_ty = fcx.node_ty(s_id);
3973 if any_diverges && !warned && match s.node {
3974 ast::StmtDecl(ref decl, _) => {
3976 ast::DeclLocal(_) => true,
3980 ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
3986 .add_lint(lint::builtin::UNREACHABLE_CODE,
3989 "unreachable statement".to_string());
3992 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3993 any_err = any_err || s_ty.references_error();
3996 None => if any_err {
3997 fcx.write_error(blk.id);
3998 } else if any_diverges {
3999 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4001 fcx.write_nil(blk.id);
4004 if any_diverges && !warned {
4008 .add_lint(lint::builtin::UNREACHABLE_CODE,
4011 "unreachable expression".to_string());
4013 let ety = match expected {
4014 ExpectHasType(ety) => {
4015 check_expr_coercable_to_type(fcx, &**e, ety);
4019 check_expr_with_expectation(fcx, &**e, expected);
4025 fcx.write_error(blk.id);
4026 } else if any_diverges {
4027 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4029 fcx.write_ty(blk.id, ety);
4034 *fcx.ps.borrow_mut() = prev;
4037 /// Checks a constant appearing in a type. At the moment this is just the
4038 /// length expression in a fixed-length vector, but someday it might be
4039 /// extended to type-level numeric literals.
4040 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4041 expr: &'tcx ast::Expr,
4042 expected_type: Ty<'tcx>) {
4043 let tables = RefCell::new(ty::Tables::empty());
4044 let inh = static_inherited_fields(ccx, &tables);
4045 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4046 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4049 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4053 let tables = RefCell::new(ty::Tables::empty());
4054 let inh = static_inherited_fields(ccx, &tables);
4055 let rty = ccx.tcx.node_id_to_type(id);
4056 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4057 let declty = fcx.ccx.tcx.lookup_item_type(local_def(id)).ty;
4058 check_const_with_ty(&fcx, sp, e, declty);
4061 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4065 // Gather locals in statics (because of block expressions).
4066 // This is technically unnecessary because locals in static items are forbidden,
4067 // but prevents type checking from blowing up before const checking can properly
4069 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4071 check_expr_with_hint(fcx, e, declty);
4072 demand::coerce(fcx, e.span, declty, e);
4073 fcx.select_all_obligations_or_error();
4075 regionck::regionck_expr(fcx, e);
4076 writeback::resolve_type_vars_in_expr(fcx, e);
4079 /// Checks whether a type can be represented in memory. In particular, it
4080 /// identifies types that contain themselves without indirection through a
4081 /// pointer, which would mean their size is unbounded.
4082 pub fn check_representable(tcx: &ty::ctxt,
4084 item_id: ast::NodeId,
4085 designation: &str) -> bool {
4086 let rty = tcx.node_id_to_type(item_id);
4088 // Check that it is possible to represent this type. This call identifies
4089 // (1) types that contain themselves and (2) types that contain a different
4090 // recursive type. It is only necessary to throw an error on those that
4091 // contain themselves. For case 2, there must be an inner type that will be
4092 // caught by case 1.
4093 match rty.is_representable(tcx, sp) {
4094 ty::SelfRecursive => {
4095 span_err!(tcx.sess, sp, E0072,
4096 "illegal recursive {} type; \
4097 wrap the inner value in a box to make it representable",
4101 ty::Representable | ty::ContainsRecursive => (),
4106 /// Checks whether a type can be constructed at runtime without
4107 /// an existing instance of that type.
4108 pub fn check_instantiable(tcx: &ty::ctxt,
4110 item_id: ast::NodeId) {
4111 let item_ty = tcx.node_id_to_type(item_id);
4112 if !item_ty.is_instantiable(tcx) &&
4113 !tcx.sess.features.borrow().static_recursion {
4114 emit_feature_err(&tcx.sess.parse_sess.span_diagnostic,
4117 "this type cannot be instantiated at runtime \
4118 without an instance of itself");
4122 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4123 let t = tcx.node_id_to_type(id);
4124 if t.needs_subst() {
4125 span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
4129 ty::TyStruct(did, substs) => {
4130 let fields = tcx.lookup_struct_fields(did);
4131 if fields.is_empty() {
4132 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4135 let e = tcx.lookup_field_type(did, fields[0].id, substs);
4136 if !fields.iter().all(
4137 |f| tcx.lookup_field_type(did, f.id, substs) == e) {
4138 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4141 if !e.is_machine() {
4142 span_err!(tcx.sess, sp, E0077,
4143 "SIMD vector element type should be machine type");
4151 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4153 vs: &'tcx [P<ast::Variant>],
4156 fn disr_in_range(ccx: &CrateCtxt,
4158 disr: ty::Disr) -> bool {
4159 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4161 ast::TyU8 => disr as u8 as Disr == disr,
4162 ast::TyU16 => disr as u16 as Disr == disr,
4163 ast::TyU32 => disr as u32 as Disr == disr,
4164 ast::TyU64 => disr as u64 as Disr == disr,
4165 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4168 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4170 ast::TyI8 => disr as i8 as Disr == disr,
4171 ast::TyI16 => disr as i16 as Disr == disr,
4172 ast::TyI32 => disr as i32 as Disr == disr,
4173 ast::TyI64 => disr as i64 as Disr == disr,
4174 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4178 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4179 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4183 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4184 vs: &'tcx [P<ast::Variant>],
4186 hint: attr::ReprAttr) {
4187 #![allow(trivial_numeric_casts)]
4189 let rty = ccx.tcx.node_id_to_type(id);
4190 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4192 let tables = RefCell::new(ty::Tables::empty());
4193 let inh = static_inherited_fields(ccx, &tables);
4194 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4196 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4198 if let Some(ref e) = v.node.disr_expr {
4199 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4203 let def_id = local_def(id);
4205 // ty::enum_variants guards against discriminant overflows, so
4206 // we need not check for that.
4207 let variants = ccx.tcx.enum_variants(def_id);
4209 for (v, variant) in vs.iter().zip(variants.iter()) {
4210 let current_disr_val = variant.disr_val;
4212 // Check for duplicate discriminant values
4213 match disr_vals.iter().position(|&x| x == current_disr_val) {
4215 span_err!(ccx.tcx.sess, v.span, E0081,
4216 "discriminant value `{}` already exists", disr_vals[i]);
4217 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variants[i].id.node),
4218 "conflicting discriminant here")
4222 // Check for unrepresentable discriminant values
4224 attr::ReprAny | attr::ReprExtern => (),
4225 attr::ReprInt(sp, ity) => {
4226 if !disr_in_range(ccx, ity, current_disr_val) {
4227 span_err!(ccx.tcx.sess, v.span, E0082,
4228 "discriminant value outside specified type");
4229 span_note!(ccx.tcx.sess, sp,
4230 "discriminant type specified here");
4233 attr::ReprPacked => {
4234 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4237 disr_vals.push(current_disr_val);
4241 let hint = *ccx.tcx.lookup_repr_hints(ast::DefId { krate: ast::LOCAL_CRATE, node: id })
4242 .get(0).unwrap_or(&attr::ReprAny);
4244 if hint != attr::ReprAny && vs.len() <= 1 {
4246 span_err!(ccx.tcx.sess, sp, E0083,
4247 "unsupported representation for univariant enum");
4249 span_err!(ccx.tcx.sess, sp, E0084,
4250 "unsupported representation for zero-variant enum");
4254 do_check(ccx, vs, id, hint);
4256 check_representable(ccx.tcx, sp, id, "enum");
4257 check_instantiable(ccx.tcx, sp, id);
4260 // Returns the type parameter count and the type for the given definition.
4261 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4264 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4266 def::DefLocal(nid) | def::DefUpvar(nid, _) => {
4267 let typ = fcx.local_ty(sp, nid);
4268 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4269 ty::GenericPredicates::empty())
4271 def::DefFn(id, _) | def::DefMethod(id, _) |
4272 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4273 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
4274 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4278 def::DefAssociatedTy(..) |
4280 def::DefTyParam(..) |
4282 def::DefForeignMod(..) |
4284 def::DefRegion(..) |
4286 def::DefSelfTy(..) => {
4287 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4292 // Instantiates the given path, which must refer to an item with the given
4293 // number of type parameters and type.
4294 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4295 segments: &[ast::PathSegment],
4296 type_scheme: TypeScheme<'tcx>,
4297 type_predicates: &ty::GenericPredicates<'tcx>,
4298 opt_self_ty: Option<Ty<'tcx>>,
4301 node_id: ast::NodeId) {
4302 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4308 // We need to extract the type parameters supplied by the user in
4309 // the path `path`. Due to the current setup, this is a bit of a
4310 // tricky-process; the problem is that resolve only tells us the
4311 // end-point of the path resolution, and not the intermediate steps.
4312 // Luckily, we can (at least for now) deduce the intermediate steps
4313 // just from the end-point.
4315 // There are basically four cases to consider:
4317 // 1. Reference to a *type*, such as a struct or enum:
4319 // mod a { struct Foo<T> { ... } }
4321 // Because we don't allow types to be declared within one
4322 // another, a path that leads to a type will always look like
4323 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4324 // that only the final segment can have type parameters, and
4325 // they are located in the TypeSpace.
4327 // *Note:* Generally speaking, references to types don't
4328 // actually pass through this function, but rather the
4329 // `ast_ty_to_ty` function in `astconv`. However, in the case
4330 // of struct patterns (and maybe literals) we do invoke
4331 // `instantiate_path` to get the general type of an instance of
4332 // a struct. (In these cases, there are actually no type
4333 // parameters permitted at present, but perhaps we will allow
4334 // them in the future.)
4336 // 1b. Reference to a enum variant or tuple-like struct:
4338 // struct foo<T>(...)
4339 // enum E<T> { foo(...) }
4341 // In these cases, the parameters are declared in the type
4344 // 2. Reference to a *fn item*:
4348 // In this case, the path will again always have the form
4349 // `a::b::foo::<T>` where only the final segment should have
4350 // type parameters. However, in this case, those parameters are
4351 // declared on a value, and hence are in the `FnSpace`.
4353 // 3. Reference to a *method*:
4355 // impl<A> SomeStruct<A> {
4359 // Here we can have a path like
4360 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4361 // may appear in two places. The penultimate segment,
4362 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4363 // final segment, `foo::<B>` contains parameters in fn space.
4365 // 4. Reference to an *associated const*:
4367 // impl<A> AnotherStruct<A> {
4368 // const FOO: B = BAR;
4371 // The path in this case will look like
4372 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4373 // only will have parameters in TypeSpace.
4375 // The first step then is to categorize the segments appropriately.
4377 assert!(!segments.is_empty());
4379 let mut ufcs_method = None;
4380 let mut segment_spaces: Vec<_>;
4382 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4383 def::DefSelfTy(..) |
4384 def::DefStruct(..) |
4385 def::DefVariant(..) |
4387 def::DefAssociatedTy(..) |
4389 def::DefPrimTy(..) |
4390 def::DefTyParam(..) => {
4391 // Everything but the final segment should have no
4392 // parameters at all.
4393 segment_spaces = vec![None; segments.len() - 1];
4394 segment_spaces.push(Some(subst::TypeSpace));
4397 // Case 2. Reference to a top-level value.
4400 def::DefStatic(..) => {
4401 segment_spaces = vec![None; segments.len() - 1];
4402 segment_spaces.push(Some(subst::FnSpace));
4405 // Case 3. Reference to a method.
4406 def::DefMethod(_, provenance) => {
4408 def::FromTrait(trait_did) => {
4409 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4411 def::FromImpl(_) => {}
4414 if segments.len() >= 2 {
4415 segment_spaces = vec![None; segments.len() - 2];
4416 segment_spaces.push(Some(subst::TypeSpace));
4417 segment_spaces.push(Some(subst::FnSpace));
4419 // `<T>::method` will end up here, and so can `T::method`.
4420 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4421 segment_spaces = vec![Some(subst::FnSpace)];
4422 ufcs_method = Some((provenance, self_ty));
4426 def::DefAssociatedConst(_, provenance) => {
4428 def::FromTrait(trait_did) => {
4429 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4431 def::FromImpl(_) => {}
4434 if segments.len() >= 2 {
4435 segment_spaces = vec![None; segments.len() - 2];
4436 segment_spaces.push(Some(subst::TypeSpace));
4437 segment_spaces.push(None);
4439 segment_spaces = vec![None];
4443 // Other cases. Various nonsense that really shouldn't show up
4444 // here. If they do, an error will have been reported
4445 // elsewhere. (I hope)
4447 def::DefForeignMod(..) |
4450 def::DefRegion(..) |
4452 def::DefUpvar(..) => {
4453 segment_spaces = vec![None; segments.len()];
4456 assert_eq!(segment_spaces.len(), segments.len());
4458 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4459 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4460 // type parameters are not mandatory.
4461 let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
4463 debug!("segment_spaces={:?}", segment_spaces);
4465 // Next, examine the definition, and determine how many type
4466 // parameters we expect from each space.
4467 let type_defs = &type_scheme.generics.types;
4468 let region_defs = &type_scheme.generics.regions;
4470 // Now that we have categorized what space the parameters for each
4471 // segment belong to, let's sort out the parameters that the user
4472 // provided (if any) into their appropriate spaces. We'll also report
4473 // errors if type parameters are provided in an inappropriate place.
4474 let mut substs = Substs::empty();
4475 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4478 check_path_args(fcx.tcx(), slice::ref_slice(segment),
4479 NO_TPS | NO_REGIONS);
4483 push_explicit_parameters_from_segment_to_substs(fcx,
4493 if let Some(self_ty) = opt_self_ty {
4494 if type_defs.len(subst::SelfSpace) == 1 {
4495 substs.types.push(subst::SelfSpace, self_ty);
4499 // Now we have to compare the types that the user *actually*
4500 // provided against the types that were *expected*. If the user
4501 // did not provide any types, then we want to substitute inference
4502 // variables. If the user provided some types, we may still need
4503 // to add defaults. If the user provided *too many* types, that's
4505 for &space in &ParamSpace::all() {
4506 adjust_type_parameters(fcx, span, space, type_defs,
4507 require_type_space, &mut substs);
4508 assert_eq!(substs.types.len(space), type_defs.len(space));
4510 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4511 assert_eq!(substs.regions().len(space), region_defs.len(space));
4514 // The things we are substituting into the type should not contain
4515 // escaping late-bound regions, and nor should the base type scheme.
4516 assert!(!substs.has_regions_escaping_depth(0));
4517 assert!(!type_scheme.has_escaping_regions());
4519 // Add all the obligations that are required, substituting and
4520 // normalized appropriately.
4521 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4522 fcx.add_obligations_for_parameters(
4523 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4526 // Substitute the values for the type parameters into the type of
4527 // the referenced item.
4528 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4531 if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
4532 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4533 // is inherent, there is no `Self` parameter, instead, the impl needs
4534 // type parameters, which we can infer by unifying the provided `Self`
4535 // with the substituted impl type.
4536 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4537 assert_eq!(substs.types.len(subst::TypeSpace),
4538 impl_scheme.generics.types.len(subst::TypeSpace));
4539 assert_eq!(substs.regions().len(subst::TypeSpace),
4540 impl_scheme.generics.regions.len(subst::TypeSpace));
4542 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4543 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4544 fcx.tcx().sess.span_bug(span,
4546 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4552 fcx.write_ty(node_id, ty_substituted);
4553 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4556 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4557 /// parameters are provided, then reports an error and clears the output vector.
4559 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4560 /// use inference variables. This seems less likely to lead to derived errors.
4562 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4563 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4564 /// here because we can easily use the precise span of the N+1'th parameter.
4565 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4566 fcx: &FnCtxt<'a, 'tcx>,
4567 space: subst::ParamSpace,
4569 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4570 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4571 segment: &ast::PathSegment,
4572 substs: &mut Substs<'tcx>)
4574 match segment.parameters {
4575 ast::AngleBracketedParameters(ref data) => {
4576 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4577 fcx, space, type_defs, region_defs, data, substs);
4580 ast::ParenthesizedParameters(ref data) => {
4581 span_err!(fcx.tcx().sess, span, E0238,
4582 "parenthesized parameters may only be used with a trait");
4583 push_explicit_parenthesized_parameters_from_segment_to_substs(
4584 fcx, space, span, type_defs, data, substs);
4589 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4590 fcx: &FnCtxt<'a, 'tcx>,
4591 space: subst::ParamSpace,
4592 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4593 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4594 data: &ast::AngleBracketedParameterData,
4595 substs: &mut Substs<'tcx>)
4598 let type_count = type_defs.len(space);
4599 assert_eq!(substs.types.len(space), 0);
4600 for (i, typ) in data.types.iter().enumerate() {
4601 let t = fcx.to_ty(&**typ);
4603 substs.types.push(space, t);
4604 } else if i == type_count {
4605 span_err!(fcx.tcx().sess, typ.span, E0087,
4606 "too many type parameters provided: \
4607 expected at most {} parameter{}, \
4608 found {} parameter{}",
4610 if type_count == 1 {""} else {"s"},
4612 if data.types.len() == 1 {""} else {"s"});
4613 substs.types.truncate(space, 0);
4619 if !data.bindings.is_empty() {
4620 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4621 "unexpected binding of associated item in expression path \
4622 (only allowed in type paths)");
4626 let region_count = region_defs.len(space);
4627 assert_eq!(substs.regions().len(space), 0);
4628 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4629 let r = ast_region_to_region(fcx.tcx(), lifetime);
4630 if i < region_count {
4631 substs.mut_regions().push(space, r);
4632 } else if i == region_count {
4633 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4634 "too many lifetime parameters provided: \
4635 expected {} parameter{}, found {} parameter{}",
4637 if region_count == 1 {""} else {"s"},
4638 data.lifetimes.len(),
4639 if data.lifetimes.len() == 1 {""} else {"s"});
4640 substs.mut_regions().truncate(space, 0);
4648 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4649 /// but intended for `Foo(A,B) -> C` form. This expands to
4650 /// roughly the same thing as `Foo<(A,B),C>`. One important
4651 /// difference has to do with the treatment of anonymous
4652 /// regions, which are translated into bound regions (NYI).
4653 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4654 fcx: &FnCtxt<'a, 'tcx>,
4655 space: subst::ParamSpace,
4657 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4658 data: &ast::ParenthesizedParameterData,
4659 substs: &mut Substs<'tcx>)
4661 let type_count = type_defs.len(space);
4663 span_err!(fcx.tcx().sess, span, E0167,
4664 "parenthesized form always supplies 2 type parameters, \
4665 but only {} parameter(s) were expected",
4669 let input_tys: Vec<Ty> =
4670 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4672 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4674 if type_count >= 1 {
4675 substs.types.push(space, tuple_ty);
4678 let output_ty: Option<Ty> =
4679 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4682 output_ty.unwrap_or(fcx.tcx().mk_nil());
4684 if type_count >= 2 {
4685 substs.types.push(space, output_ty);
4689 fn adjust_type_parameters<'a, 'tcx>(
4690 fcx: &FnCtxt<'a, 'tcx>,
4693 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4694 require_type_space: bool,
4695 substs: &mut Substs<'tcx>)
4697 let provided_len = substs.types.len(space);
4698 let desired = defs.get_slice(space);
4699 let required_len = desired.iter()
4700 .take_while(|d| d.default.is_none())
4703 debug!("adjust_type_parameters(space={:?}, \
4712 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4713 assert!(provided_len <= desired.len());
4715 // Nothing specified at all: supply inference variables for
4717 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4718 substs.types.replace(space, fcx.infcx().type_vars_for_defs(&desired[..]));
4722 // Too few parameters specified: report an error and use Err
4724 if provided_len < required_len {
4726 if desired.len() != required_len { "at least " } else { "" };
4727 span_err!(fcx.tcx().sess, span, E0089,
4728 "too few type parameters provided: expected {}{} parameter{}, \
4729 found {} parameter{}",
4730 qualifier, required_len,
4731 if required_len == 1 {""} else {"s"},
4733 if provided_len == 1 {""} else {"s"});
4734 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4738 // Otherwise, add in any optional parameters that the user
4739 // omitted. The case of *too many* parameters is handled
4741 // push_explicit_parameters_from_segment_to_substs(). Note
4742 // that the *default* type are expressed in terms of all prior
4743 // parameters, so we have to substitute as we go with the
4744 // partial substitution that we have built up.
4745 for i in provided_len..desired.len() {
4746 let default = desired[i].default.unwrap();
4747 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4748 substs.types.push(space, default);
4750 assert_eq!(substs.types.len(space), desired.len());
4752 debug!("Final substs: {:?}", substs);
4755 fn adjust_region_parameters(
4759 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4760 substs: &mut Substs)
4762 let provided_len = substs.mut_regions().len(space);
4763 let desired = defs.get_slice(space);
4765 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4766 assert!(provided_len <= desired.len());
4768 // If nothing was provided, just use inference variables.
4769 if provided_len == 0 {
4770 substs.mut_regions().replace(
4772 fcx.infcx().region_vars_for_defs(span, desired));
4776 // If just the right number were provided, everybody is happy.
4777 if provided_len == desired.len() {
4781 // Otherwise, too few were provided. Report an error and then
4782 // use inference variables.
4783 span_err!(fcx.tcx().sess, span, E0090,
4784 "too few lifetime parameters provided: expected {} parameter{}, \
4785 found {} parameter{}",
4787 if desired.len() == 1 {""} else {"s"},
4789 if provided_len == 1 {""} else {"s"});
4791 substs.mut_regions().replace(
4793 fcx.infcx().region_vars_for_defs(span, desired));
4797 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4801 where F: Fn() -> Ty<'tcx>
4803 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4806 let alternative = f();
4809 if alternative.is_ty_var() || alternative.references_error() {
4810 fcx.type_error_message(sp, |_actual| {
4811 "the type of this value must be known in this context".to_string()
4813 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4814 ty = fcx.tcx().types.err;
4816 demand::suptype(fcx, sp, alternative, ty);
4824 // Resolves `typ` by a single level if `typ` is a type variable. If no
4825 // resolution is possible, then an error is reported.
4826 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4831 structurally_resolve_type_or_else(fcx, sp, ty, || {
4836 // Returns true if b contains a break that can exit from b
4837 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
4838 // First: is there an unlabeled break immediately
4840 (loop_query(&*b, |e| {
4842 ast::ExprBreak(None) => true,
4846 // Second: is there a labeled break with label
4847 // <id> nested anywhere inside the loop?
4848 (block_query(b, |e| {
4849 if let ast::ExprBreak(Some(_)) = e.node {
4850 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4857 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4859 tps: &OwnedSlice<ast::TyParam>,
4861 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4864 // make a vector of booleans initially false, set to true when used
4865 if tps.is_empty() { return; }
4866 let mut tps_used = vec![false; tps.len()];
4868 for leaf_ty in ty.walk() {
4869 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4870 debug!("Found use of ty param num {}", idx);
4871 tps_used[idx as usize] = true;
4875 for (i, b) in tps_used.iter().enumerate() {
4877 span_err!(ccx.tcx.sess, span, E0091,
4878 "type parameter `{}` is unused",
4879 token::get_ident(tps[i].ident));
4884 /// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
4885 /// and in libcore/intrinsics.rs
4886 pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
4887 fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
4888 let name = token::intern(&format!("P{}", n));
4889 ccx.tcx.mk_param(subst::FnSpace, n, name)
4893 let name = token::get_ident(it.ident);
4894 let (n_tps, inputs, output) = if name.starts_with("atomic_") {
4895 let split : Vec<&str> = name.split('_').collect();
4896 assert!(split.len() >= 2, "Atomic intrinsic not correct format");
4898 //We only care about the operation here
4899 let (n_tps, inputs, output) = match split[1] {
4900 "cxchg" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)),
4904 "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))),
4906 "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4909 "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" |
4910 "min" | "umax" | "umin" => {
4911 (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4914 "fence" | "singlethreadfence" => {
4915 (0, Vec::new(), tcx.mk_nil())
4918 span_err!(tcx.sess, it.span, E0092,
4919 "unrecognized atomic operation function: `{}`", op);
4923 (n_tps, inputs, ty::FnConverging(output))
4924 } else if &name[..] == "abort" || &name[..] == "unreachable" {
4925 (0, Vec::new(), ty::FnDiverging)
4927 let (n_tps, inputs, output) = match &name[..] {
4928 "breakpoint" => (0, Vec::new(), tcx.mk_nil()),
4930 "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize),
4931 "size_of_val" | "min_align_of_val" => {
4933 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
4936 ], ccx.tcx.types.usize)
4938 "init" | "init_dropped" => (1, Vec::new(), param(ccx, 0)),
4939 "uninit" => (1, Vec::new(), param(ccx, 0)),
4940 "forget" => (1, vec!( param(ccx, 0) ), tcx.mk_nil()),
4941 "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)),
4942 "move_val_init" => {
4945 tcx.mk_mut_ptr(param(ccx, 0)),
4950 "drop_in_place" => {
4951 (1, vec![tcx.mk_mut_ptr(param(ccx, 0))], tcx.mk_nil())
4953 "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool),
4955 "type_name" => (1, Vec::new(), tcx.mk_static_str()),
4956 "type_id" => (1, Vec::new(), ccx.tcx.types.u64),
4957 "offset" | "arith_offset" => {
4960 tcx.mk_ptr(ty::TypeAndMut {
4962 mutbl: ast::MutImmutable
4966 tcx.mk_ptr(ty::TypeAndMut {
4968 mutbl: ast::MutImmutable
4971 "copy" | "copy_nonoverlapping" => {
4974 tcx.mk_ptr(ty::TypeAndMut {
4976 mutbl: ast::MutImmutable
4978 tcx.mk_ptr(ty::TypeAndMut {
4980 mutbl: ast::MutMutable
4986 "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
4989 tcx.mk_ptr(ty::TypeAndMut {
4991 mutbl: ast::MutMutable
4993 tcx.mk_ptr(ty::TypeAndMut {
4995 mutbl: ast::MutImmutable
5001 "write_bytes" | "volatile_set_memory" => {
5004 tcx.mk_ptr(ty::TypeAndMut {
5006 mutbl: ast::MutMutable
5013 "sqrtf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5014 "sqrtf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5017 vec!( tcx.types.f32, tcx.types.i32 ),
5022 vec!( tcx.types.f64, tcx.types.i32 ),
5025 "sinf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5026 "sinf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5027 "cosf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5028 "cosf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5031 vec!( tcx.types.f32, tcx.types.f32 ),
5036 vec!( tcx.types.f64, tcx.types.f64 ),
5039 "expf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5040 "expf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5041 "exp2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5042 "exp2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5043 "logf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5044 "logf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5045 "log10f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5046 "log10f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5047 "log2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5048 "log2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5051 vec!( tcx.types.f32, tcx.types.f32, tcx.types.f32 ),
5056 vec!( tcx.types.f64, tcx.types.f64, tcx.types.f64 ),
5059 "fabsf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5060 "fabsf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5061 "copysignf32" => (0, vec!( tcx.types.f32, tcx.types.f32 ), tcx.types.f32),
5062 "copysignf64" => (0, vec!( tcx.types.f64, tcx.types.f64 ), tcx.types.f64),
5063 "floorf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5064 "floorf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5065 "ceilf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5066 "ceilf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5067 "truncf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5068 "truncf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5069 "rintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5070 "rintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5071 "nearbyintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5072 "nearbyintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5073 "roundf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5074 "roundf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5075 "ctpop8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5076 "ctpop16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5077 "ctpop32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5078 "ctpop64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5079 "ctlz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5080 "ctlz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5081 "ctlz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5082 "ctlz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5083 "cttz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5084 "cttz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5085 "cttz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5086 "cttz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5087 "bswap16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5088 "bswap32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5089 "bswap64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5092 (1, vec!( tcx.mk_imm_ptr(param(ccx, 0)) ), param(ccx, 0)),
5094 (1, vec!( tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ), tcx.mk_nil()),
5096 "i8_add_with_overflow" | "i8_sub_with_overflow" | "i8_mul_with_overflow" =>
5097 (0, vec!(tcx.types.i8, tcx.types.i8),
5098 tcx.mk_tup(vec!(tcx.types.i8, tcx.types.bool))),
5100 "i16_add_with_overflow" | "i16_sub_with_overflow" | "i16_mul_with_overflow" =>
5101 (0, vec!(tcx.types.i16, tcx.types.i16),
5102 tcx.mk_tup(vec!(tcx.types.i16, tcx.types.bool))),
5104 "i32_add_with_overflow" | "i32_sub_with_overflow" | "i32_mul_with_overflow" =>
5105 (0, vec!(tcx.types.i32, tcx.types.i32),
5106 tcx.mk_tup(vec!(tcx.types.i32, tcx.types.bool))),
5108 "i64_add_with_overflow" | "i64_sub_with_overflow" | "i64_mul_with_overflow" =>
5109 (0, vec!(tcx.types.i64, tcx.types.i64),
5110 tcx.mk_tup(vec!(tcx.types.i64, tcx.types.bool))),
5112 "u8_add_with_overflow" | "u8_sub_with_overflow" | "u8_mul_with_overflow" =>
5113 (0, vec!(tcx.types.u8, tcx.types.u8),
5114 tcx.mk_tup(vec!(tcx.types.u8, tcx.types.bool))),
5116 "u16_add_with_overflow" | "u16_sub_with_overflow" | "u16_mul_with_overflow" =>
5117 (0, vec!(tcx.types.u16, tcx.types.u16),
5118 tcx.mk_tup(vec!(tcx.types.u16, tcx.types.bool))),
5120 "u32_add_with_overflow" | "u32_sub_with_overflow" | "u32_mul_with_overflow"=>
5121 (0, vec!(tcx.types.u32, tcx.types.u32),
5122 tcx.mk_tup(vec!(tcx.types.u32, tcx.types.bool))),
5124 "u64_add_with_overflow" | "u64_sub_with_overflow" | "u64_mul_with_overflow" =>
5125 (0, vec!(tcx.types.u64, tcx.types.u64),
5126 tcx.mk_tup(vec!(tcx.types.u64, tcx.types.bool))),
5128 "unchecked_udiv" | "unchecked_sdiv" | "unchecked_urem" | "unchecked_srem" =>
5129 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5131 "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
5132 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5134 "return_address" => (0, vec![], tcx.mk_imm_ptr(tcx.types.u8)),
5136 "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()),
5138 "discriminant_value" => (1, vec![
5139 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
5141 param(ccx, 0))], tcx.types.u64),
5144 let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
5145 let fn_ty = ty::BareFnTy {
5146 unsafety: ast::Unsafety::Normal,
5148 sig: ty::Binder(FnSig {
5149 inputs: vec![mut_u8],
5150 output: ty::FnOutput::FnConverging(tcx.mk_nil()),
5154 let fn_ty = tcx.mk_bare_fn(fn_ty);
5155 (0, vec![tcx.mk_fn(None, fn_ty), mut_u8], mut_u8)
5159 span_err!(tcx.sess, it.span, E0093,
5160 "unrecognized intrinsic function: `{}`", *other);
5164 (n_tps, inputs, ty::FnConverging(output))
5166 let fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy {
5167 unsafety: ast::Unsafety::Unsafe,
5168 abi: abi::RustIntrinsic,
5169 sig: ty::Binder(FnSig {
5175 let i_ty = ccx.tcx.lookup_item_type(local_def(it.id));
5176 let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
5177 if i_n_tps != n_tps {
5178 span_err!(tcx.sess, it.span, E0094,
5179 "intrinsic has wrong number of type \
5180 parameters: found {}, expected {}",
5183 require_same_types(tcx,
5190 format!("intrinsic has wrong type: expected `{}`",