1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function). Inference is used to supply types wherever they are
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
23 - gather: creates type variables to represent the type of each local
24 variable and pattern binding.
26 - main: the main pass does the lion's share of the work: it
27 determines the types of all expressions, resolves
28 methods, checks for most invalid conditions, and so forth. In
29 some cases, where a type is unknown, it may create a type or region
30 variable and use that as the type of an expression.
32 In the process of checking, various constraints will be placed on
33 these type variables through the subtyping relationships requested
34 through the `demand` module. The `infer` module is in charge
35 of resolving those constraints.
37 - regionck: after main is complete, the regionck pass goes over all
38 types looking for regions and making sure that they did not escape
39 into places they are not in scope. This may also influence the
40 final assignments of the various region variables if there is some
43 - vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
46 - writeback: writes the final types within a function body, replacing
47 type variables with their final inferred types. These final types
48 are written into the `tcx.node_types` table, which should *never* contain
49 any reference to a type variable.
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.item_substs`. These types
56 may contain unresolved type variables. After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `ccx.tcx`.
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
68 n.b.: A type variable is not the same thing as a type parameter. A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract. When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`. This variable will
74 eventually be resolved to some concrete type (which might itself be
79 pub use self::LvaluePreference::*;
80 pub use self::Expectation::*;
81 pub use self::compare_method::{compare_impl_method, compare_const_impl};
82 use self::TupleArgumentsFlag::*;
84 use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
85 use check::_match::pat_ctxt;
86 use fmt_macros::{Parser, Piece, Position};
87 use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS};
90 use middle::pat_util::{self, pat_id_map};
91 use middle::privacy::{AllPublic, LastMod};
92 use middle::region::{self, CodeExtent};
93 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
94 use middle::traits::{self, report_fulfillment_errors};
95 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
96 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
97 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
98 use middle::ty::{MethodCall, MethodCallee};
99 use middle::ty_fold::{TypeFolder, TypeFoldable};
100 use require_c_abi_if_variadic;
101 use rscope::{ElisionFailureInfo, RegionScope};
102 use session::Session;
103 use {CrateCtxt, lookup_full_def, require_same_types};
106 use util::common::{block_query, ErrorReported, indenter, loop_query};
107 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
108 use util::lev_distance::lev_distance;
110 use std::cell::{Cell, Ref, RefCell};
111 use std::mem::replace;
113 use syntax::{self, abi, attr};
114 use syntax::attr::AttrMetaMethods;
115 use syntax::ast::{self, DefId, Visibility};
116 use syntax::ast_util::{self, local_def};
117 use syntax::codemap::{self, Span};
118 use syntax::owned_slice::OwnedSlice;
119 use syntax::parse::token;
120 use syntax::print::pprust;
122 use syntax::visit::{self, Visitor};
140 /// closures defined within the function. For example:
143 /// bar(move|| { ... })
146 /// Here, the function `foo()` and the closure passed to
147 /// `bar()` will each have their own `FnCtxt`, but they will
148 /// share the inherited fields.
149 pub struct Inherited<'a, 'tcx: 'a> {
150 infcx: infer::InferCtxt<'a, 'tcx>,
151 locals: RefCell<NodeMap<Ty<'tcx>>>,
153 tables: &'a RefCell<ty::Tables<'tcx>>,
155 // A mapping from each fn's id to its signature, with all bound
156 // regions replaced with free ones. Unlike the other tables, this
157 // one is never copied into the tcx: it is only used by regionck.
158 fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
160 // When we process a call like `c()` where `c` is a closure type,
161 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
162 // `FnOnce` closure. In that case, we defer full resolution of the
163 // call until upvar inference can kick in and make the
164 // decision. We keep these deferred resolutions grouped by the
165 // def-id of the closure, so that once we decide, we can easily go
166 // back and process them.
167 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
169 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
172 trait DeferredCallResolution<'tcx> {
173 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
176 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
178 /// When type-checking an expression, we propagate downward
179 /// whatever type hint we are able in the form of an `Expectation`.
180 #[derive(Copy, Clone, Debug)]
181 pub enum Expectation<'tcx> {
182 /// We know nothing about what type this expression should have.
185 /// This expression should have the type given (or some subtype)
186 ExpectHasType(Ty<'tcx>),
188 /// This expression will be cast to the `Ty`
189 ExpectCastableToType(Ty<'tcx>),
191 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
192 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
193 ExpectRvalueLikeUnsized(Ty<'tcx>),
196 impl<'tcx> Expectation<'tcx> {
197 // Disregard "castable to" expectations because they
198 // can lead us astray. Consider for example `if cond
199 // {22} else {c} as u8` -- if we propagate the
200 // "castable to u8" constraint to 22, it will pick the
201 // type 22u8, which is overly constrained (c might not
202 // be a u8). In effect, the problem is that the
203 // "castable to" expectation is not the tightest thing
204 // we can say, so we want to drop it in this case.
205 // The tightest thing we can say is "must unify with
206 // else branch". Note that in the case of a "has type"
207 // constraint, this limitation does not hold.
209 // If the expected type is just a type variable, then don't use
210 // an expected type. Otherwise, we might write parts of the type
211 // when checking the 'then' block which are incompatible with the
213 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
215 ExpectHasType(ety) => {
216 let ety = fcx.infcx().shallow_resolve(ety);
217 if !ety.is_ty_var() {
223 ExpectRvalueLikeUnsized(ety) => {
224 ExpectRvalueLikeUnsized(ety)
231 #[derive(Copy, Clone)]
232 pub struct UnsafetyState {
233 pub def: ast::NodeId,
234 pub unsafety: ast::Unsafety,
235 pub unsafe_push_count: u32,
240 pub fn function(unsafety: ast::Unsafety, def: ast::NodeId) -> UnsafetyState {
241 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
244 pub fn recurse(&mut self, blk: &ast::Block) -> UnsafetyState {
245 match self.unsafety {
246 // If this unsafe, then if the outer function was already marked as
247 // unsafe we shouldn't attribute the unsafe'ness to the block. This
248 // way the block can be warned about instead of ignoring this
249 // extraneous block (functions are never warned about).
250 ast::Unsafety::Unsafe if self.from_fn => *self,
253 let (unsafety, def, count) = match blk.rules {
254 ast::PushUnsafeBlock(..) =>
255 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
256 ast::PopUnsafeBlock(..) =>
257 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
258 ast::UnsafeBlock(..) =>
259 (ast::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
261 (unsafety, self.def, self.unsafe_push_count),
263 UnsafetyState{ def: def,
265 unsafe_push_count: count,
273 pub struct FnCtxt<'a, 'tcx: 'a> {
274 body_id: ast::NodeId,
276 // This flag is set to true if, during the writeback phase, we encounter
277 // a type error in this function.
278 writeback_errors: Cell<bool>,
280 // Number of errors that had been reported when we started
281 // checking this function. On exit, if we find that *more* errors
282 // have been reported, we will skip regionck and other work that
283 // expects the types within the function to be consistent.
284 err_count_on_creation: usize,
286 ret_ty: ty::FnOutput<'tcx>,
288 ps: RefCell<UnsafetyState>,
290 inh: &'a Inherited<'a, 'tcx>,
292 ccx: &'a CrateCtxt<'a, 'tcx>,
295 impl<'a, 'tcx> Inherited<'a, 'tcx> {
296 fn new(tcx: &'a ty::ctxt<'tcx>,
297 tables: &'a RefCell<ty::Tables<'tcx>>,
298 param_env: ty::ParameterEnvironment<'a, 'tcx>)
299 -> Inherited<'a, 'tcx> {
302 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
303 locals: RefCell::new(NodeMap()),
305 fn_sig_map: RefCell::new(NodeMap()),
306 deferred_call_resolutions: RefCell::new(DefIdMap()),
307 deferred_cast_checks: RefCell::new(Vec::new()),
311 fn normalize_associated_types_in<T>(&self,
313 body_id: ast::NodeId,
316 where T : TypeFoldable<'tcx> + HasTypeFlags
318 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
319 assoc::normalize_associated_types_in(&self.infcx,
328 // Used by check_const and check_enum_variants
329 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
330 inh: &'a Inherited<'a, 'tcx>,
331 rty: ty::FnOutput<'tcx>,
332 body_id: ast::NodeId)
333 -> FnCtxt<'a, 'tcx> {
336 writeback_errors: Cell::new(false),
337 err_count_on_creation: ccx.tcx.sess.err_count(),
339 ps: RefCell::new(UnsafetyState::function(ast::Unsafety::Normal, 0)),
345 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
346 tables: &'a RefCell<ty::Tables<'tcx>>)
347 -> Inherited<'a, 'tcx> {
348 // It's kind of a kludge to manufacture a fake function context
349 // and statement context, but we might as well do write the code only once
350 let param_env = ccx.tcx.empty_parameter_environment();
351 Inherited::new(ccx.tcx, &tables, param_env)
354 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
355 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
357 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
358 fn visit_item(&mut self, i: &'tcx ast::Item) {
359 check_item_type(self.ccx, i);
360 visit::walk_item(self, i);
363 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
365 ast::TyFixedLengthVec(_, ref expr) => {
366 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
371 visit::walk_ty(self, t);
375 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
376 fn visit_item(&mut self, i: &'tcx ast::Item) {
377 check_item_body(self.ccx, i);
378 visit::walk_item(self, i);
382 pub fn check_item_types(ccx: &CrateCtxt) {
383 let krate = ccx.tcx.map.krate();
384 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
385 visit::walk_crate(&mut visit, krate);
387 // If types are not well-formed, it leads to all manner of errors
388 // downstream, so stop reporting errors at this point.
389 ccx.tcx.sess.abort_if_errors();
391 let mut visit = CheckItemTypesVisitor { ccx: ccx };
392 visit::walk_crate(&mut visit, krate);
394 ccx.tcx.sess.abort_if_errors();
396 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
397 visit::walk_crate(&mut visit, krate);
399 ccx.tcx.sess.abort_if_errors();
401 for drop_method_did in ccx.tcx.destructors.borrow().iter() {
402 if drop_method_did.krate == ast::LOCAL_CRATE {
403 let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
404 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
407 assert!(ccx.tcx.sess.has_errors());
413 ccx.tcx.sess.abort_if_errors();
416 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
417 decl: &'tcx ast::FnDecl,
418 body: &'tcx ast::Block,
422 param_env: ty::ParameterEnvironment<'a, 'tcx>)
425 ty::TyBareFn(_, ref fn_ty) => {
426 let tables = RefCell::new(ty::Tables::empty());
427 let inh = Inherited::new(ccx.tcx, &tables, param_env);
429 // Compute the fty from point of view of inside fn.
431 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
433 ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
436 inh.normalize_associated_types_in(body.span,
440 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
441 decl, fn_id, body, &inh);
443 fcx.select_all_obligations_and_apply_defaults();
444 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
445 fcx.select_all_obligations_or_error();
448 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
450 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
451 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
453 _ => ccx.tcx.sess.impossible_case(body.span,
454 "check_bare_fn: function type expected")
458 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
459 fcx: &'a FnCtxt<'a, 'tcx>
462 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
463 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
466 // infer the variable's type
467 let var_ty = self.fcx.infcx().next_ty_var();
468 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
472 // take type that the user specified
473 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
480 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
481 // Add explicitly-declared locals.
482 fn visit_local(&mut self, local: &'tcx ast::Local) {
483 let o_ty = match local.ty {
484 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
487 self.assign(local.span, local.id, o_ty);
488 debug!("Local variable {:?} is assigned type {}",
490 self.fcx.infcx().ty_to_string(
491 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
492 visit::walk_local(self, local);
495 // Add pattern bindings.
496 fn visit_pat(&mut self, p: &'tcx ast::Pat) {
497 if let ast::PatIdent(_, ref path1, _) = p.node {
498 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) {
499 let var_ty = self.assign(p.span, p.id, None);
501 self.fcx.require_type_is_sized(var_ty, p.span,
502 traits::VariableType(p.id));
504 debug!("Pattern binding {} is assigned to {} with type {:?}",
505 token::get_ident(path1.node),
506 self.fcx.infcx().ty_to_string(
507 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
511 visit::walk_pat(self, p);
514 fn visit_block(&mut self, b: &'tcx ast::Block) {
515 // non-obvious: the `blk` variable maps to region lb, so
516 // we have to keep this up-to-date. This
517 // is... unfortunate. It'd be nice to not need this.
518 visit::walk_block(self, b);
521 // Since an expr occurs as part of the type fixed size arrays we
522 // need to record the type for that node
523 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
525 ast::TyFixedLengthVec(ref ty, ref count_expr) => {
526 self.visit_ty(&**ty);
527 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
529 _ => visit::walk_ty(self, t)
533 // Don't descend into fns and items
534 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx ast::FnDecl,
535 _: &'tcx ast::Block, _: Span, _: ast::NodeId) { }
536 fn visit_item(&mut self, _: &ast::Item) { }
540 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
541 /// body and returns the function context used for that purpose, since in the case of a fn item
542 /// there is still a bit more to do.
545 /// * inherited: other fields inherited from the enclosing fn (if any)
546 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
547 unsafety: ast::Unsafety,
548 unsafety_id: ast::NodeId,
549 fn_sig: &ty::FnSig<'tcx>,
550 decl: &'tcx ast::FnDecl,
552 body: &'tcx ast::Block,
553 inherited: &'a Inherited<'a, 'tcx>)
557 let err_count_on_creation = tcx.sess.err_count();
559 let arg_tys = &fn_sig.inputs;
560 let ret_ty = fn_sig.output;
562 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
567 // Create the function context. This is either derived from scratch or,
568 // in the case of function expressions, based on the outer context.
571 writeback_errors: Cell::new(false),
572 err_count_on_creation: err_count_on_creation,
574 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
579 // Remember return type so that regionck can access it later.
580 let mut fn_sig_tys: Vec<Ty> =
585 if let ty::FnConverging(ret_ty) = ret_ty {
586 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
587 fn_sig_tys.push(ret_ty);
590 debug!("fn-sig-map: fn_id={} fn_sig_tys={:?}",
594 inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys);
597 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
599 // Add formal parameters.
600 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
601 // Create type variables for each argument.
602 pat_util::pat_bindings(
605 |_bm, pat_id, sp, _path| {
606 let var_ty = visit.assign(sp, pat_id, None);
607 fcx.require_type_is_sized(var_ty, sp,
608 traits::VariableType(pat_id));
611 // Check the pattern.
614 map: pat_id_map(&tcx.def_map, &*input.pat),
616 _match::check_pat(&pcx, &*input.pat, *arg_ty);
619 visit.visit_block(body);
622 check_block_with_expected(&fcx, body, match ret_ty {
623 ty::FnConverging(result_type) => ExpectHasType(result_type),
624 ty::FnDiverging => NoExpectation
627 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
628 fcx.write_ty(input.id, arg);
634 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
637 check_representable(tcx, span, id, "struct");
638 check_instantiable(tcx, span, id);
640 if tcx.lookup_simd(local_def(id)) {
641 check_simd(tcx, span, id);
645 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
646 debug!("check_item_type(it.id={}, it.ident={})",
648 ccx.tcx.item_path_str(local_def(it.id)));
649 let _indenter = indenter();
651 // Consts can play a role in type-checking, so they are included here.
652 ast::ItemStatic(_, _, ref e) |
653 ast::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
654 ast::ItemEnum(ref enum_definition, _) => {
655 check_enum_variants(ccx,
657 &enum_definition.variants,
660 ast::ItemFn(..) => {} // entirely within check_item_body
661 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
662 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
663 match ccx.tcx.impl_trait_ref(local_def(it.id)) {
664 Some(impl_trait_ref) => {
665 check_impl_items_against_trait(ccx,
673 ast::ItemTrait(_, ref generics, _, _) => {
674 check_trait_on_unimplemented(ccx, generics, it);
676 ast::ItemStruct(..) => {
677 check_struct(ccx, it.id, it.span);
679 ast::ItemTy(ref t, ref generics) => {
680 let pty_ty = ccx.tcx.node_id_to_type(it.id);
681 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
683 ast::ItemForeignMod(ref m) => {
684 if m.abi == abi::RustIntrinsic {
685 for item in &m.items {
686 check_intrinsic_type(ccx, &**item);
689 for item in &m.items {
690 let pty = ccx.tcx.lookup_item_type(local_def(item.id));
691 if !pty.generics.types.is_empty() {
692 span_err!(ccx.tcx.sess, item.span, E0044,
693 "foreign items may not have type parameters");
696 if let ast::ForeignItemFn(ref fn_decl, _) = item.node {
697 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
702 _ => {/* nothing to do */ }
706 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
707 debug!("check_item_body(it.id={}, it.ident={})",
709 ccx.tcx.item_path_str(local_def(it.id)));
710 let _indenter = indenter();
712 ast::ItemFn(ref decl, _, _, _, _, ref body) => {
713 let fn_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
714 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
715 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
717 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
718 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
720 let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
722 for impl_item in impl_items {
723 match impl_item.node {
724 ast::ConstImplItem(_, ref expr) => {
725 check_const(ccx, impl_item.span, &*expr, impl_item.id)
727 ast::MethodImplItem(ref sig, ref body) => {
728 check_method_body(ccx, &impl_pty.generics, sig, body,
729 impl_item.id, impl_item.span);
731 ast::TypeImplItem(_) |
732 ast::MacImplItem(_) => {
733 // Nothing to do here.
738 ast::ItemTrait(_, _, _, ref trait_items) => {
739 let trait_def = ccx.tcx.lookup_trait_def(local_def(it.id));
740 for trait_item in trait_items {
741 match trait_item.node {
742 ast::ConstTraitItem(_, Some(ref expr)) => {
743 check_const(ccx, trait_item.span, &*expr, trait_item.id)
745 ast::MethodTraitItem(ref sig, Some(ref body)) => {
746 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
748 check_method_body(ccx, &trait_def.generics, sig, body,
749 trait_item.id, trait_item.span);
751 ast::MethodTraitItem(ref sig, None) => {
752 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
754 ast::ConstTraitItem(_, None) |
755 ast::TypeTraitItem(..) => {
761 _ => {/* nothing to do */ }
765 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
767 constness: ast::Constness)
770 ast::Constness::NotConst => {
773 ast::Constness::Const => {
774 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
779 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
780 generics: &ast::Generics,
782 if let Some(ref attr) = item.attrs.iter().find(|a| {
783 a.check_name("rustc_on_unimplemented")
785 if let Some(ref istring) = attr.value_str() {
786 let parser = Parser::new(&istring);
787 let types = &*generics.ty_params;
788 for token in parser {
790 Piece::String(_) => (), // Normal string, no need to check it
791 Piece::NextArgument(a) => match a.position {
792 // `{Self}` is allowed
793 Position::ArgumentNamed(s) if s == "Self" => (),
794 // So is `{A}` if A is a type parameter
795 Position::ArgumentNamed(s) => match types.iter().find(|t| {
796 t.ident.as_str() == s
800 span_err!(ccx.tcx.sess, attr.span, E0230,
801 "there is no type parameter \
803 s, item.ident.as_str());
806 // `{:1}` and `{}` are not to be used
807 Position::ArgumentIs(_) | Position::ArgumentNext => {
808 span_err!(ccx.tcx.sess, attr.span, E0231,
809 "only named substitution \
810 parameters are allowed");
816 span_err!(ccx.tcx.sess, attr.span, E0232,
817 "this attribute must have a value, \
818 eg `#[rustc_on_unimplemented = \"foo\"]`")
823 /// Type checks a method body.
827 /// * `item_generics`: generics defined on the impl/trait that contains
829 /// * `self_bound`: bound for the `Self` type parameter, if any
830 /// * `method`: the method definition
831 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
832 item_generics: &ty::Generics<'tcx>,
833 sig: &'tcx ast::MethodSig,
834 body: &'tcx ast::Block,
835 id: ast::NodeId, span: Span) {
836 debug!("check_method_body(item_generics={:?}, id={})",
838 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
840 let fty = ccx.tcx.node_id_to_type(id);
841 debug!("check_method_body: fty={:?}", fty);
843 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
846 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
848 impl_trait_ref: &ty::TraitRef<'tcx>,
849 impl_items: &[P<ast::ImplItem>]) {
850 // Locate trait methods
852 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
853 let mut overridden_associated_type = None;
855 // Check existing impl methods to see if they are both present in trait
856 // and compatible with trait signature
857 for impl_item in impl_items {
858 let ty_impl_item = ccx.tcx.impl_or_trait_item(local_def(impl_item.id));
859 let ty_trait_item = trait_items.iter()
860 .find(|ac| ac.name() == ty_impl_item.name())
862 // This is checked by resolve
863 tcx.sess.span_bug(impl_item.span,
864 &format!("impl-item `{}` is not a member of `{:?}`",
865 token::get_name(ty_impl_item.name()),
868 match impl_item.node {
869 ast::ConstImplItem(..) => {
870 let impl_const = match ty_impl_item {
871 ty::ConstTraitItem(ref cti) => cti,
872 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
875 // Find associated const definition.
876 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
877 compare_const_impl(ccx.tcx,
883 span_err!(tcx.sess, impl_item.span, E0323,
884 "item `{}` is an associated const, \
885 which doesn't match its trait `{:?}`",
886 token::get_name(impl_const.name),
890 ast::MethodImplItem(ref sig, ref body) => {
891 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
893 let impl_method = match ty_impl_item {
894 ty::MethodTraitItem(ref mti) => mti,
895 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
898 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
899 compare_impl_method(ccx.tcx,
906 span_err!(tcx.sess, impl_item.span, E0324,
907 "item `{}` is an associated method, \
908 which doesn't match its trait `{:?}`",
909 token::get_name(impl_method.name),
913 ast::TypeImplItem(_) => {
914 let impl_type = match ty_impl_item {
915 ty::TypeTraitItem(ref tti) => tti,
916 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
919 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
920 if let Some(_) = at.ty {
921 overridden_associated_type = Some(impl_item);
924 span_err!(tcx.sess, impl_item.span, E0325,
925 "item `{}` is an associated type, \
926 which doesn't match its trait `{:?}`",
927 token::get_name(impl_type.name),
931 ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
936 // Check for missing items from trait
937 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
938 let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
939 let mut missing_items = Vec::new();
940 let mut invalidated_items = Vec::new();
941 let associated_type_overridden = overridden_associated_type.is_some();
942 for trait_item in trait_items.iter() {
944 ty::ConstTraitItem(ref associated_const) => {
945 let is_implemented = impl_items.iter().any(|ii| {
947 ast::ConstImplItem(..) => {
948 ii.ident.name == associated_const.name
954 associated_consts.iter().any(|ac| ac.default.is_some() &&
955 ac.name == associated_const.name);
958 missing_items.push(associated_const.name);
959 } else if associated_type_overridden {
960 invalidated_items.push(associated_const.name);
964 ty::MethodTraitItem(ref trait_method) => {
966 impl_items.iter().any(|ii| {
968 ast::MethodImplItem(..) => {
969 ii.ident.name == trait_method.name
975 provided_methods.iter().any(|m| m.name == trait_method.name);
978 missing_items.push(trait_method.name);
979 } else if associated_type_overridden {
980 invalidated_items.push(trait_method.name);
984 ty::TypeTraitItem(ref associated_type) => {
985 let is_implemented = impl_items.iter().any(|ii| {
987 ast::TypeImplItem(_) => {
988 ii.ident.name == associated_type.name
993 let is_provided = associated_type.ty.is_some();
996 missing_items.push(associated_type.name);
997 } else if associated_type_overridden {
998 invalidated_items.push(associated_type.name);
1005 if !missing_items.is_empty() {
1006 span_err!(tcx.sess, impl_span, E0046,
1007 "not all trait items implemented, missing: `{}`",
1008 missing_items.iter()
1009 .map(<ast::Name>::as_str)
1010 .collect::<Vec<_>>().join("`, `"))
1013 if !invalidated_items.is_empty() {
1014 let invalidator = overridden_associated_type.unwrap();
1015 span_err!(tcx.sess, invalidator.span, E0399,
1016 "the following trait items need to be reimplemented \
1017 as `{}` was overridden: `{}`",
1018 invalidator.ident.as_str(),
1019 invalidated_items.iter()
1020 .map(<ast::Name>::as_str)
1021 .collect::<Vec<_>>().join("`, `"))
1025 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1032 let tstr = fcx.infcx().ty_to_string(t_cast);
1033 fcx.type_error_message(span, |actual| {
1034 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1037 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1038 let mtstr = match mt {
1039 ast::MutMutable => "mut ",
1040 ast::MutImmutable => ""
1042 if t_cast.is_trait() {
1043 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1045 fcx.tcx().sess.span_suggestion(t_span,
1046 "try casting to a reference instead:",
1047 format!("&{}{}", mtstr, s));
1050 span_help!(fcx.tcx().sess, t_span,
1051 "did you mean `&{}{}`?", mtstr, tstr),
1054 span_help!(fcx.tcx().sess, span,
1055 "consider using an implicit coercion to `&{}{}` instead",
1060 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1062 fcx.tcx().sess.span_suggestion(t_span,
1063 "try casting to a `Box` instead:",
1064 format!("Box<{}>", s));
1067 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1071 span_help!(fcx.tcx().sess, e_span,
1072 "consider using a box or reference as appropriate");
1075 fcx.write_error(id);
1079 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1080 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1082 fn get_item_type_scheme(&self, _: Span, id: ast::DefId)
1083 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1085 Ok(self.tcx().lookup_item_type(id))
1088 fn get_trait_def(&self, _: Span, id: ast::DefId)
1089 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1091 Ok(self.tcx().lookup_trait_def(id))
1094 fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
1095 // all super predicates are ensured during collect pass
1099 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1100 Some(&self.inh.infcx.parameter_environment.free_substs)
1103 fn get_type_parameter_bounds(&self,
1105 node_id: ast::NodeId)
1106 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1108 let def = self.tcx().type_parameter_def(node_id);
1109 let r = self.inh.infcx.parameter_environment
1112 .filter_map(|predicate| {
1114 ty::Predicate::Trait(ref data) => {
1115 if data.0.self_ty().is_param(def.space, def.index) {
1116 Some(data.to_poly_trait_ref())
1130 fn trait_defines_associated_type_named(&self,
1131 trait_def_id: ast::DefId,
1132 assoc_name: ast::Name)
1135 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1136 trait_def.associated_type_names.contains(&assoc_name)
1139 fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
1140 self.infcx().next_ty_var()
1143 fn projected_ty_from_poly_trait_ref(&self,
1145 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1146 item_name: ast::Name)
1149 let (trait_ref, _) =
1150 self.infcx().replace_late_bound_regions_with_fresh_var(
1152 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1155 self.normalize_associated_type(span, trait_ref, item_name)
1158 fn projected_ty(&self,
1160 trait_ref: ty::TraitRef<'tcx>,
1161 item_name: ast::Name)
1164 self.normalize_associated_type(span, trait_ref, item_name)
1168 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1169 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1171 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1175 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1176 &self.inh.infcx.parameter_environment
1179 pub fn sess(&self) -> &Session {
1183 pub fn err_count_since_creation(&self) -> usize {
1184 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1187 /// Resolves type variables in `ty` if possible. Unlike the infcx
1188 /// version, this version will also select obligations if it seems
1189 /// useful, in an effort to get more type information.
1190 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1191 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1193 // No TyInfer()? Nothing needs doing.
1194 if !ty.has_infer_types() {
1195 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1199 // If `ty` is a type variable, see whether we already know what it is.
1200 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1201 if !ty.has_infer_types() {
1202 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1206 // If not, try resolving any new fcx obligations that have cropped up.
1207 self.select_new_obligations();
1208 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1209 if !ty.has_infer_types() {
1210 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1214 // If not, try resolving *all* pending obligations as much as
1215 // possible. This can help substantially when there are
1216 // indirect dependencies that don't seem worth tracking
1218 self.select_obligations_where_possible();
1219 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1221 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1225 fn record_deferred_call_resolution(&self,
1226 closure_def_id: ast::DefId,
1227 r: DeferredCallResolutionHandler<'tcx>) {
1228 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1229 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1232 fn remove_deferred_call_resolutions(&self,
1233 closure_def_id: ast::DefId)
1234 -> Vec<DeferredCallResolutionHandler<'tcx>>
1236 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1237 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1240 pub fn tag(&self) -> String {
1241 let self_ptr: *const FnCtxt = self;
1242 format!("{:?}", self_ptr)
1245 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1246 match self.inh.locals.borrow().get(&nid) {
1249 self.tcx().sess.span_err(
1251 &format!("no type for local variable {}", nid));
1252 self.tcx().types.err
1257 /// Apply "fallbacks" to some types
1258 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1259 pub fn default_type_parameters(&self) {
1260 use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
1261 for (_, &mut ref ty) in &mut self.inh.tables.borrow_mut().node_types {
1262 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1263 if self.infcx().type_var_diverges(resolved) {
1264 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1266 match self.infcx().type_is_unconstrained_numeric(resolved) {
1267 UnconstrainedInt => {
1268 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1270 UnconstrainedFloat => {
1271 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1280 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1281 debug!("write_ty({}, {:?}) in fcx {}",
1282 node_id, ty, self.tag());
1283 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1286 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1287 if !substs.substs.is_noop() {
1288 debug!("write_substs({}, {:?}) in fcx {}",
1293 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1297 pub fn write_autoderef_adjustment(&self,
1298 node_id: ast::NodeId,
1300 self.write_adjustment(
1302 ty::AdjustDerefRef(ty::AutoDerefRef {
1310 pub fn write_adjustment(&self,
1311 node_id: ast::NodeId,
1312 adj: ty::AutoAdjustment<'tcx>) {
1313 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1315 if adj.is_identity() {
1319 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1322 /// Basically whenever we are converting from a type scheme into
1323 /// the fn body space, we always want to normalize associated
1324 /// types as well. This function combines the two.
1325 fn instantiate_type_scheme<T>(&self,
1327 substs: &Substs<'tcx>,
1330 where T : TypeFoldable<'tcx> + HasTypeFlags
1332 let value = value.subst(self.tcx(), substs);
1333 let result = self.normalize_associated_types_in(span, &value);
1334 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1341 /// As `instantiate_type_scheme`, but for the bounds found in a
1342 /// generic type scheme.
1343 fn instantiate_bounds(&self,
1345 substs: &Substs<'tcx>,
1346 bounds: &ty::GenericPredicates<'tcx>)
1347 -> ty::InstantiatedPredicates<'tcx>
1349 ty::InstantiatedPredicates {
1350 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1355 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1356 where T : TypeFoldable<'tcx> + HasTypeFlags
1358 self.inh.normalize_associated_types_in(span, self.body_id, value)
1361 fn normalize_associated_type(&self,
1363 trait_ref: ty::TraitRef<'tcx>,
1364 item_name: ast::Name)
1367 let cause = traits::ObligationCause::new(span,
1369 traits::ObligationCauseCode::MiscObligation);
1374 .normalize_projection_type(self.infcx(),
1376 trait_ref: trait_ref,
1377 item_name: item_name,
1382 /// Returns the type of `def_id` with all generics replaced by by fresh type/region variables.
1383 /// Also returns the substitution from the type parameters on `def_id` to the fresh variables.
1384 /// Registers any trait obligations specified on `def_id` at the same time.
1386 /// Note that function is only intended to be used with types (notably, not fns). This is
1387 /// because it doesn't do any instantiation of late-bound regions.
1388 pub fn instantiate_type(&self,
1391 -> TypeAndSubsts<'tcx>
1394 self.tcx().lookup_item_type(def_id);
1395 let type_predicates =
1396 self.tcx().lookup_predicates(def_id);
1398 self.infcx().fresh_substs_for_generics(
1400 &type_scheme.generics);
1402 self.instantiate_bounds(span, &substs, &type_predicates);
1403 self.add_obligations_for_parameters(
1404 traits::ObligationCause::new(
1407 traits::ItemObligation(def_id)),
1410 self.instantiate_type_scheme(span, &substs, &type_scheme.ty);
1418 /// Returns the type that this AST path refers to. If the path has no type
1419 /// parameters and the corresponding type has type parameters, fresh type
1420 /// and/or region variables are substituted.
1422 /// This is used when checking the constructor in struct literals.
1423 fn instantiate_struct_literal_ty(&self,
1426 -> TypeAndSubsts<'tcx>
1428 let tcx = self.tcx();
1430 let ty::TypeScheme { generics, ty: decl_ty } =
1431 tcx.lookup_item_type(did);
1433 let substs = astconv::ast_path_substs_for_ty(self, self,
1435 PathParamMode::Optional,
1437 path.segments.last().unwrap());
1439 let ty = self.instantiate_type_scheme(path.span, &substs, &decl_ty);
1441 TypeAndSubsts { substs: substs, ty: ty }
1444 pub fn write_nil(&self, node_id: ast::NodeId) {
1445 self.write_ty(node_id, self.tcx().mk_nil());
1447 pub fn write_error(&self, node_id: ast::NodeId) {
1448 self.write_ty(node_id, self.tcx().types.err);
1451 pub fn require_type_meets(&self,
1454 code: traits::ObligationCauseCode<'tcx>,
1455 bound: ty::BuiltinBound)
1457 self.register_builtin_bound(
1460 traits::ObligationCause::new(span, self.body_id, code));
1463 pub fn require_type_is_sized(&self,
1466 code: traits::ObligationCauseCode<'tcx>)
1468 self.require_type_meets(ty, span, code, ty::BoundSized);
1471 pub fn require_expr_have_sized_type(&self,
1473 code: traits::ObligationCauseCode<'tcx>)
1475 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1478 pub fn type_is_known_to_be_sized(&self,
1483 traits::type_known_to_meet_builtin_bound(self.infcx(),
1489 pub fn register_builtin_bound(&self,
1491 builtin_bound: ty::BuiltinBound,
1492 cause: traits::ObligationCause<'tcx>)
1494 self.inh.infcx.fulfillment_cx.borrow_mut()
1495 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1498 pub fn register_predicate(&self,
1499 obligation: traits::PredicateObligation<'tcx>)
1501 debug!("register_predicate({:?})",
1503 self.inh.infcx.fulfillment_cx
1505 .register_predicate_obligation(self.infcx(), obligation);
1508 pub fn to_ty(&self, ast_t: &ast::Ty) -> Ty<'tcx> {
1509 let t = ast_ty_to_ty(self, self, ast_t);
1511 let mut bounds_checker = wf::BoundsChecker::new(self,
1514 bounds_checker.check_ty(t, ast_t.span);
1519 pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
1520 match self.inh.tables.borrow().node_types.get(&ex.id) {
1523 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1529 /// Apply `adjustment` to the type of `expr`
1530 pub fn adjust_expr_ty(&self,
1532 adjustment: Option<&ty::AutoAdjustment<'tcx>>)
1535 let raw_ty = self.expr_ty(expr);
1536 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1537 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1538 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1539 self.inh.tables.borrow().method_map.get(&method_call)
1540 .map(|method| resolve_ty(method.ty))
1544 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1545 match self.inh.tables.borrow().node_types.get(&id) {
1547 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1549 self.tcx().sess.bug(
1550 &format!("no type for node {}: {} in fcx {}",
1551 id, self.tcx().map.node_to_string(id),
1557 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1558 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1559 // it changes when we upgrade the snapshot compiler
1560 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1561 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1565 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1568 pub fn opt_node_ty_substs<F>(&self,
1571 F: FnOnce(&ty::ItemSubsts<'tcx>),
1573 match self.inh.tables.borrow().item_substs.get(&id) {
1579 pub fn mk_subty(&self,
1580 a_is_expected: bool,
1581 origin: infer::TypeOrigin,
1584 -> Result<(), ty::TypeError<'tcx>> {
1585 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1588 pub fn mk_eqty(&self,
1589 a_is_expected: bool,
1590 origin: infer::TypeOrigin,
1593 -> Result<(), ty::TypeError<'tcx>> {
1594 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1597 pub fn mk_subr(&self,
1598 origin: infer::SubregionOrigin<'tcx>,
1601 infer::mk_subr(self.infcx(), origin, sub, sup)
1604 pub fn type_error_message<M>(&self,
1607 actual_ty: Ty<'tcx>,
1608 err: Option<&ty::TypeError<'tcx>>) where
1609 M: FnOnce(String) -> String,
1611 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1614 pub fn report_mismatched_types(&self,
1618 err: &ty::TypeError<'tcx>) {
1619 self.infcx().report_mismatched_types(sp, e, a, err)
1622 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1623 /// outlive the region `r`.
1624 pub fn register_region_obligation(&self,
1627 cause: traits::ObligationCause<'tcx>)
1629 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1630 fulfillment_cx.register_region_obligation(ty, region, cause);
1633 pub fn add_default_region_param_bounds(&self,
1634 substs: &Substs<'tcx>,
1637 for &ty in &substs.types {
1638 let default_bound = ty::ReScope(CodeExtent::from_node_id(expr.id));
1639 let cause = traits::ObligationCause::new(expr.span, self.body_id,
1640 traits::MiscObligation);
1641 self.register_region_obligation(ty, default_bound, cause);
1645 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1646 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1647 /// trait/region obligations.
1649 /// For example, if there is a function:
1652 /// fn foo<'a,T:'a>(...)
1655 /// and a reference:
1661 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1662 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1663 pub fn add_obligations_for_parameters(&self,
1664 cause: traits::ObligationCause<'tcx>,
1665 predicates: &ty::InstantiatedPredicates<'tcx>)
1667 assert!(!predicates.has_escaping_regions());
1669 debug!("add_obligations_for_parameters(predicates={:?})",
1672 for obligation in traits::predicates_for_generics(cause, predicates) {
1673 self.register_predicate(obligation);
1677 // Only for fields! Returns <none> for methods>
1678 // Indifferent to privacy flags
1679 pub fn lookup_field_ty(&self,
1681 class_id: ast::DefId,
1682 items: &[ty::FieldTy],
1683 fieldname: ast::Name,
1684 substs: &subst::Substs<'tcx>)
1687 let o_field = items.iter().find(|f| f.name == fieldname);
1688 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1689 .map(|t| self.normalize_associated_types_in(span, &t))
1692 pub fn lookup_tup_field_ty(&self,
1694 class_id: ast::DefId,
1695 items: &[ty::FieldTy],
1697 substs: &subst::Substs<'tcx>)
1700 let o_field = if idx < items.len() { Some(&items[idx]) } else { None };
1701 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1702 .map(|t| self.normalize_associated_types_in(span, &t))
1705 fn check_casts(&self) {
1706 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1707 for cast in deferred_cast_checks.drain(..) {
1712 fn select_all_obligations_and_apply_defaults(&self) {
1713 debug!("select_all_obligations_and_apply_defaults");
1715 self.select_obligations_where_possible();
1716 self.default_type_parameters();
1717 self.select_obligations_where_possible();
1720 fn select_all_obligations_or_error(&self) {
1721 debug!("select_all_obligations_or_error");
1723 // upvar inference should have ensured that all deferred call
1724 // resolutions are handled by now.
1725 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1727 self.select_all_obligations_and_apply_defaults();
1728 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1729 match fulfillment_cx.select_all_or_error(self.infcx()) {
1731 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1735 /// Select as many obligations as we can at present.
1736 fn select_obligations_where_possible(&self) {
1738 self.inh.infcx.fulfillment_cx
1740 .select_where_possible(self.infcx())
1743 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1747 /// Try to select any fcx obligation that we haven't tried yet, in an effort
1748 /// to improve inference. You could just call
1749 /// `select_obligations_where_possible` except that it leads to repeated
1751 fn select_new_obligations(&self) {
1753 self.inh.infcx.fulfillment_cx
1755 .select_new_obligations(self.infcx())
1758 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1764 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
1765 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1766 Some(self.base_object_lifetime_default(span))
1769 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1770 // RFC #599 specifies that object lifetime defaults take
1771 // precedence over other defaults. But within a fn body we
1772 // don't have a *default* region, rather we use inference to
1773 // find the *correct* region, which is strictly more general
1774 // (and anyway, within a fn body the right region may not even
1775 // be something the user can write explicitly, since it might
1776 // be some expression).
1777 self.infcx().next_region_var(infer::MiscVariable(span))
1780 fn anon_regions(&self, span: Span, count: usize)
1781 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1782 Ok((0..count).map(|_| {
1783 self.infcx().next_region_var(infer::MiscVariable(span))
1788 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1789 pub enum LvaluePreference {
1794 impl LvaluePreference {
1795 pub fn from_mutbl(m: ast::Mutability) -> Self {
1797 ast::MutMutable => PreferMutLvalue,
1798 ast::MutImmutable => NoPreference,
1803 /// Whether `autoderef` requires types to resolve.
1804 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1805 pub enum UnresolvedTypeAction {
1806 /// Produce an error and return `TyError` whenever a type cannot
1807 /// be resolved (i.e. it is `TyInfer`).
1809 /// Go on without emitting any errors, and return the unresolved
1810 /// type. Useful for probing, e.g. in coercions.
1814 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
1815 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
1817 /// Note: this method does not modify the adjustments table. The caller is responsible for
1818 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
1819 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
1822 opt_expr: Option<&ast::Expr>,
1823 unresolved_type_action: UnresolvedTypeAction,
1824 mut lvalue_pref: LvaluePreference,
1826 -> (Ty<'tcx>, usize, Option<T>)
1827 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
1829 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
1834 let mut t = base_ty;
1835 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
1836 let resolved_t = match unresolved_type_action {
1837 UnresolvedTypeAction::Error => {
1838 structurally_resolved_type(fcx, sp, t)
1840 UnresolvedTypeAction::Ignore => {
1841 // We can continue even when the type cannot be resolved
1842 // (i.e. it is an inference variable) because `Ty::builtin_deref`
1843 // and `try_overloaded_deref` both simply return `None`
1844 // in such a case without producing spurious errors.
1845 fcx.resolve_type_vars_if_possible(t)
1848 if resolved_t.references_error() {
1849 return (resolved_t, autoderefs, None);
1852 match should_stop(resolved_t, autoderefs) {
1853 Some(x) => return (resolved_t, autoderefs, Some(x)),
1857 // Otherwise, deref if type is derefable:
1858 let mt = match resolved_t.builtin_deref(false) {
1859 Some(mt) => Some(mt),
1862 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
1864 // Super subtle: it might seem as though we should
1865 // pass `opt_expr` to `try_overloaded_deref`, so that
1866 // the (implicit) autoref of using an overloaded deref
1867 // would get added to the adjustment table. However we
1868 // do not do that, because it's kind of a
1869 // "meta-adjustment" -- instead, we just leave it
1870 // unrecorded and know that there "will be" an
1871 // autoref. regionck and other bits of the code base,
1872 // when they encounter an overloaded autoderef, have
1873 // to do some reconstructive surgery. This is a pretty
1874 // complex mess that is begging for a proper MIR.
1875 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
1881 if mt.mutbl == ast::MutImmutable {
1882 lvalue_pref = NoPreference;
1885 None => return (resolved_t, autoderefs, None)
1889 // We've reached the recursion limit, error gracefully.
1890 span_err!(fcx.tcx().sess, sp, E0055,
1891 "reached the recursion limit while auto-dereferencing {:?}",
1893 (fcx.tcx().types.err, 0, None)
1896 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1898 method_call: Option<MethodCall>,
1899 base_expr: Option<&ast::Expr>,
1901 lvalue_pref: LvaluePreference)
1902 -> Option<ty::TypeAndMut<'tcx>>
1904 // Try DerefMut first, if preferred.
1905 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
1906 (PreferMutLvalue, Some(trait_did)) => {
1907 method::lookup_in_trait(fcx, span, base_expr,
1908 token::intern("deref_mut"), trait_did,
1914 // Otherwise, fall back to Deref.
1915 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
1916 (None, Some(trait_did)) => {
1917 method::lookup_in_trait(fcx, span, base_expr,
1918 token::intern("deref"), trait_did,
1921 (method, _) => method
1924 make_overloaded_lvalue_return_type(fcx, method_call, method)
1927 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
1928 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
1929 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
1930 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1931 method_call: Option<MethodCall>,
1932 method: Option<MethodCallee<'tcx>>)
1933 -> Option<ty::TypeAndMut<'tcx>>
1937 // extract method method return type, which will be &T;
1938 // all LB regions should have been instantiated during method lookup
1939 let ret_ty = method.ty.fn_ret();
1940 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
1942 if let Some(method_call) = method_call {
1943 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
1946 // method returns &T, but the type as visible to user is T, so deref
1947 ret_ty.builtin_deref(true)
1953 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1955 base_expr: &'tcx ast::Expr,
1958 lvalue_pref: LvaluePreference)
1959 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
1961 // FIXME(#18741) -- this is almost but not quite the same as the
1962 // autoderef that normal method probing does. They could likely be
1965 let (ty, autoderefs, final_mt) = autoderef(fcx,
1969 UnresolvedTypeAction::Error,
1972 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
1973 adj_ty, idx, false, lvalue_pref, idx_ty)
1976 if final_mt.is_some() {
1980 // After we have fully autoderef'd, if the resulting type is [T; n], then
1981 // do a final unsized coercion to yield [T].
1982 if let ty::TyArray(element_ty, _) = ty.sty {
1983 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
1984 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
1985 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
1991 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
1992 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
1993 /// This loop implements one step in that search; the autoderef loop is implemented by
1994 /// `lookup_indexing`.
1995 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1996 method_call: MethodCall,
1998 base_expr: &'tcx ast::Expr,
1999 adjusted_ty: Ty<'tcx>,
2002 lvalue_pref: LvaluePreference,
2004 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2006 let tcx = fcx.tcx();
2007 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2008 autoderefs={}, unsize={}, index_ty={:?})",
2016 let input_ty = fcx.infcx().next_ty_var();
2018 // First, try built-in indexing.
2019 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2020 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2021 debug!("try_index_step: success, using built-in indexing");
2022 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2024 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2025 return Some((tcx.types.usize, ty));
2030 // Try `IndexMut` first, if preferred.
2031 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2032 (PreferMutLvalue, Some(trait_did)) => {
2033 method::lookup_in_trait_adjusted(fcx,
2036 token::intern("index_mut"),
2041 Some(vec![input_ty]))
2046 // Otherwise, fall back to `Index`.
2047 let method = match (method, tcx.lang_items.index_trait()) {
2048 (None, Some(trait_did)) => {
2049 method::lookup_in_trait_adjusted(fcx,
2052 token::intern("index"),
2057 Some(vec![input_ty]))
2059 (method, _) => method,
2062 // If some lookup succeeds, write callee into table and extract index/element
2063 // type from the method signature.
2064 // If some lookup succeeded, install method in table
2065 method.and_then(|method| {
2066 debug!("try_index_step: success, using overloaded indexing");
2067 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2068 map(|ret| (input_ty, ret.ty))
2072 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2074 method_fn_ty: Ty<'tcx>,
2075 callee_expr: &'tcx ast::Expr,
2076 args_no_rcvr: &'tcx [P<ast::Expr>],
2077 tuple_arguments: TupleArgumentsFlag,
2078 expected: Expectation<'tcx>)
2079 -> ty::FnOutput<'tcx> {
2080 if method_fn_ty.references_error() {
2081 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2083 let err_inputs = match tuple_arguments {
2084 DontTupleArguments => err_inputs,
2085 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2088 check_argument_types(fcx,
2095 ty::FnConverging(fcx.tcx().types.err)
2097 match method_fn_ty.sty {
2098 ty::TyBareFn(_, ref fty) => {
2099 // HACK(eddyb) ignore self in the definition (see above).
2100 let expected_arg_tys = expected_types_for_fn_args(fcx,
2104 &fty.sig.0.inputs[1..]);
2105 check_argument_types(fcx,
2107 &fty.sig.0.inputs[1..],
2108 &expected_arg_tys[..],
2115 fcx.tcx().sess.span_bug(callee_expr.span,
2116 "method without bare fn type");
2122 /// Generic function that factors out common logic from function calls, method calls and overloaded
2124 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2126 fn_inputs: &[Ty<'tcx>],
2127 expected_arg_tys: &[Ty<'tcx>],
2128 args: &'tcx [P<ast::Expr>],
2130 tuple_arguments: TupleArgumentsFlag) {
2131 let tcx = fcx.ccx.tcx;
2133 // Grab the argument types, supplying fresh type variables
2134 // if the wrong number of arguments were supplied
2135 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2141 let mut expected_arg_tys = expected_arg_tys;
2142 let expected_arg_count = fn_inputs.len();
2143 let formal_tys = if tuple_arguments == TupleArguments {
2144 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2145 match tuple_type.sty {
2146 ty::TyTuple(ref arg_types) => {
2147 if arg_types.len() != args.len() {
2148 span_err!(tcx.sess, sp, E0057,
2149 "this function takes {} parameter{} but {} parameter{} supplied",
2151 if arg_types.len() == 1 {""} else {"s"},
2153 if args.len() == 1 {" was"} else {"s were"});
2154 expected_arg_tys = &[];
2155 err_args(fcx.tcx(), args.len())
2157 expected_arg_tys = match expected_arg_tys.get(0) {
2158 Some(&ty) => match ty.sty {
2159 ty::TyTuple(ref tys) => &**tys,
2164 (*arg_types).clone()
2168 span_err!(tcx.sess, sp, E0059,
2169 "cannot use call notation; the first type parameter \
2170 for the function trait is neither a tuple nor unit");
2171 expected_arg_tys = &[];
2172 err_args(fcx.tcx(), args.len())
2175 } else if expected_arg_count == supplied_arg_count {
2177 } else if variadic {
2178 if supplied_arg_count >= expected_arg_count {
2181 span_err!(tcx.sess, sp, E0060,
2182 "this function takes at least {} parameter{} \
2183 but {} parameter{} supplied",
2185 if expected_arg_count == 1 {""} else {"s"},
2187 if supplied_arg_count == 1 {" was"} else {"s were"});
2188 expected_arg_tys = &[];
2189 err_args(fcx.tcx(), supplied_arg_count)
2192 span_err!(tcx.sess, sp, E0061,
2193 "this function takes {} parameter{} but {} parameter{} supplied",
2195 if expected_arg_count == 1 {""} else {"s"},
2197 if supplied_arg_count == 1 {" was"} else {"s were"});
2198 expected_arg_tys = &[];
2199 err_args(fcx.tcx(), supplied_arg_count)
2202 debug!("check_argument_types: formal_tys={:?}",
2203 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2205 // Check the arguments.
2206 // We do this in a pretty awful way: first we typecheck any arguments
2207 // that are not anonymous functions, then we typecheck the anonymous
2208 // functions. This is so that we have more information about the types
2209 // of arguments when we typecheck the functions. This isn't really the
2210 // right way to do this.
2211 let xs = [false, true];
2212 for check_blocks in &xs {
2213 let check_blocks = *check_blocks;
2214 debug!("check_blocks={}", check_blocks);
2216 // More awful hacks: before we check argument types, try to do
2217 // an "opportunistic" vtable resolution of any trait bounds on
2218 // the call. This helps coercions.
2220 fcx.select_new_obligations();
2223 // For variadic functions, we don't have a declared type for all of
2224 // the arguments hence we only do our usual type checking with
2225 // the arguments who's types we do know.
2226 let t = if variadic {
2228 } else if tuple_arguments == TupleArguments {
2233 for (i, arg) in args.iter().take(t).enumerate() {
2234 let is_block = match arg.node {
2235 ast::ExprClosure(..) => true,
2239 if is_block == check_blocks {
2240 debug!("checking the argument");
2241 let formal_ty = formal_tys[i];
2243 // The special-cased logic below has three functions:
2244 // 1. Provide as good of an expected type as possible.
2245 let expected = expected_arg_tys.get(i).map(|&ty| {
2246 Expectation::rvalue_hint(ty)
2249 check_expr_with_unifier(fcx, &**arg,
2250 expected.unwrap_or(ExpectHasType(formal_ty)),
2252 // 2. Coerce to the most detailed type that could be coerced
2253 // to, which is `expected_ty` if `rvalue_hint` returns an
2254 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2255 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2256 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2258 // 3. Relate the expected type and the formal one,
2259 // if the expected type was used for the coercion.
2260 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2266 // We also need to make sure we at least write the ty of the other
2267 // arguments which we skipped above.
2269 for arg in args.iter().skip(expected_arg_count) {
2270 check_expr(fcx, &**arg);
2272 // There are a few types which get autopromoted when passed via varargs
2273 // in C but we just error out instead and require explicit casts.
2274 let arg_ty = structurally_resolved_type(fcx, arg.span,
2275 fcx.expr_ty(&**arg));
2277 ty::TyFloat(ast::TyF32) => {
2278 fcx.type_error_message(arg.span,
2280 format!("can't pass an {} to variadic \
2281 function, cast to c_double", t)
2284 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2285 fcx.type_error_message(arg.span, |t| {
2286 format!("can't pass {} to variadic \
2287 function, cast to c_int",
2291 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2292 fcx.type_error_message(arg.span, |t| {
2293 format!("can't pass {} to variadic \
2294 function, cast to c_uint",
2304 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2305 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2306 (0..len).map(|_| tcx.types.err).collect()
2309 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2310 call_expr: &ast::Expr,
2311 output: ty::FnOutput<'tcx>) {
2312 fcx.write_ty(call_expr.id, match output {
2313 ty::FnConverging(output_ty) => output_ty,
2314 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2318 // AST fragment checking
2319 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2321 expected: Expectation<'tcx>)
2324 let tcx = fcx.ccx.tcx;
2327 ast::LitStr(..) => tcx.mk_static_str(),
2328 ast::LitBinary(ref v) => {
2329 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2330 tcx.mk_array(tcx.types.u8, v.len()))
2332 ast::LitByte(_) => tcx.types.u8,
2333 ast::LitChar(_) => tcx.types.char,
2334 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2335 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2336 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2337 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2339 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2340 ty::TyChar => Some(tcx.types.u8),
2341 ty::TyRawPtr(..) => Some(tcx.types.usize),
2342 ty::TyBareFn(..) => Some(tcx.types.usize),
2346 opt_ty.unwrap_or_else(
2347 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2349 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2350 ast::LitFloatUnsuffixed(_) => {
2351 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2353 ty::TyFloat(_) => Some(ty),
2357 opt_ty.unwrap_or_else(
2358 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2360 ast::LitBool(_) => tcx.types.bool
2364 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2365 expr: &'tcx ast::Expr,
2366 expected: Ty<'tcx>) {
2367 check_expr_with_unifier(
2368 fcx, expr, ExpectHasType(expected), NoPreference,
2369 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2372 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2373 expr: &'tcx ast::Expr,
2374 expected: Ty<'tcx>) {
2375 check_expr_with_unifier(
2376 fcx, expr, ExpectHasType(expected), NoPreference,
2377 || demand::coerce(fcx, expr.span, expected, expr));
2380 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx ast::Expr,
2381 expected: Ty<'tcx>) {
2382 check_expr_with_unifier(
2383 fcx, expr, ExpectHasType(expected), NoPreference,
2387 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2388 expr: &'tcx ast::Expr,
2389 expected: Expectation<'tcx>) {
2390 check_expr_with_unifier(
2391 fcx, expr, expected, NoPreference,
2395 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2396 expr: &'tcx ast::Expr,
2397 expected: Expectation<'tcx>,
2398 lvalue_pref: LvaluePreference)
2400 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2403 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr) {
2404 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2407 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr,
2408 lvalue_pref: LvaluePreference) {
2409 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2412 // determine the `self` type, using fresh variables for all variables
2413 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2414 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2416 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2417 span: Span, // (potential) receiver for this impl
2419 -> TypeAndSubsts<'tcx> {
2420 let tcx = fcx.tcx();
2422 let ity = tcx.lookup_item_type(did);
2423 let (n_tps, rps, raw_ty) =
2424 (ity.generics.types.len(subst::TypeSpace),
2425 ity.generics.regions.get_slice(subst::TypeSpace),
2428 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2429 let tps = fcx.inh.infcx.next_ty_vars(n_tps);
2430 let substs = subst::Substs::new_type(tps, rps);
2431 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2433 TypeAndSubsts { substs: substs, ty: substd_ty }
2436 /// Controls whether the arguments are tupled. This is used for the call
2439 /// Tupling means that all call-side arguments are packed into a tuple and
2440 /// passed as a single parameter. For example, if tupling is enabled, this
2443 /// fn f(x: (isize, isize))
2445 /// Can be called as:
2452 #[derive(Clone, Eq, PartialEq)]
2453 enum TupleArgumentsFlag {
2458 /// Unifies the return type with the expected type early, for more coercions
2459 /// and forward type information on the argument expressions.
2460 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2462 expected_ret: Expectation<'tcx>,
2463 formal_ret: ty::FnOutput<'tcx>,
2464 formal_args: &[Ty<'tcx>])
2466 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2467 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2468 fcx.infcx().commit_regions_if_ok(|| {
2469 // Attempt to apply a subtyping relationship between the formal
2470 // return type (likely containing type variables if the function
2471 // is polymorphic) and the expected return type.
2472 // No argument expectations are produced if unification fails.
2473 let origin = infer::Misc(call_span);
2474 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2475 // FIXME(#15760) can't use try! here, FromError doesn't default
2476 // to identity so the resulting type is not constrained.
2477 if let Err(e) = ures {
2481 // Record all the argument types, with the substitutions
2482 // produced from the above subtyping unification.
2483 Ok(formal_args.iter().map(|ty| {
2484 fcx.infcx().resolve_type_vars_if_possible(ty)
2490 }).unwrap_or(vec![]);
2491 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2492 formal_args, formal_ret,
2493 expected_args, expected_ret);
2498 /// If an expression has any sub-expressions that result in a type error,
2499 /// inspecting that expression's type with `ty.references_error()` will return
2500 /// true. Likewise, if an expression is known to diverge, inspecting its
2501 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2502 /// strict, _|_ can appear in the type of an expression that does not,
2503 /// itself, diverge: for example, fn() -> _|_.)
2504 /// Note that inspecting a type's structure *directly* may expose the fact
2505 /// that there are actually multiple representations for `TyError`, so avoid
2506 /// that when err needs to be handled differently.
2507 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2508 expr: &'tcx ast::Expr,
2509 expected: Expectation<'tcx>,
2510 lvalue_pref: LvaluePreference,
2514 debug!(">> typechecking: expr={:?} expected={:?}",
2517 // Checks a method call.
2518 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2519 expr: &'tcx ast::Expr,
2520 method_name: ast::SpannedIdent,
2521 args: &'tcx [P<ast::Expr>],
2523 expected: Expectation<'tcx>,
2524 lvalue_pref: LvaluePreference) {
2525 let rcvr = &*args[0];
2526 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2528 // no need to check for bot/err -- callee does that
2529 let expr_t = structurally_resolved_type(fcx,
2531 fcx.expr_ty(&*rcvr));
2533 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2534 let fn_ty = match method::lookup(fcx,
2536 method_name.node.name,
2542 let method_ty = method.ty;
2543 let method_call = MethodCall::expr(expr.id);
2544 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2548 method::report_error(fcx, method_name.span, expr_t,
2549 method_name.node.name, Some(rcvr), error);
2550 fcx.write_error(expr.id);
2555 // Call the generic checker.
2556 let ret_ty = check_method_argument_types(fcx,
2564 write_call(fcx, expr, ret_ty);
2567 // A generic function for checking the then and else in an if
2569 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2570 cond_expr: &'tcx ast::Expr,
2571 then_blk: &'tcx ast::Block,
2572 opt_else_expr: Option<&'tcx ast::Expr>,
2575 expected: Expectation<'tcx>) {
2576 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2578 let expected = expected.adjust_for_branches(fcx);
2579 check_block_with_expected(fcx, then_blk, expected);
2580 let then_ty = fcx.node_ty(then_blk.id);
2582 let branches_ty = match opt_else_expr {
2583 Some(ref else_expr) => {
2584 check_expr_with_expectation(fcx, &**else_expr, expected);
2585 let else_ty = fcx.expr_ty(&**else_expr);
2586 infer::common_supertype(fcx.infcx(),
2587 infer::IfExpression(sp),
2593 infer::common_supertype(fcx.infcx(),
2594 infer::IfExpressionWithNoElse(sp),
2601 let cond_ty = fcx.expr_ty(cond_expr);
2602 let if_ty = if cond_ty.references_error() {
2608 fcx.write_ty(id, if_ty);
2611 // Check field access expressions
2612 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2613 expr: &'tcx ast::Expr,
2614 lvalue_pref: LvaluePreference,
2615 base: &'tcx ast::Expr,
2616 field: &ast::SpannedIdent) {
2617 let tcx = fcx.ccx.tcx;
2618 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2619 let expr_t = structurally_resolved_type(fcx, expr.span,
2621 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2622 let (_, autoderefs, field_ty) = autoderef(fcx,
2626 UnresolvedTypeAction::Error,
2630 ty::TyStruct(base_id, substs) => {
2631 debug!("struct named {:?}", base_t);
2632 let fields = tcx.lookup_struct_fields(base_id);
2633 fcx.lookup_field_ty(expr.span, base_id, &fields[..],
2634 field.node.name, &(*substs))
2641 fcx.write_ty(expr.id, field_ty);
2642 fcx.write_autoderef_adjustment(base.id, autoderefs);
2648 if method::exists(fcx, field.span, field.node.name, expr_t, expr.id) {
2649 fcx.type_error_message(
2652 format!("attempted to take value of method `{}` on type \
2653 `{}`", token::get_ident(field.node), actual)
2657 tcx.sess.fileline_help(field.span,
2658 "maybe a `()` to call it is missing? \
2659 If not, try an anonymous function");
2661 fcx.type_error_message(
2664 format!("attempted access of field `{}` on \
2665 type `{}`, but no field with that \
2667 token::get_ident(field.node),
2671 if let ty::TyStruct(did, _) = expr_t.sty {
2672 suggest_field_names(did, field, tcx, vec![]);
2676 fcx.write_error(expr.id);
2679 // displays hints about the closest matches in field names
2680 fn suggest_field_names<'tcx>(id : DefId,
2681 field : &ast::SpannedIdent,
2682 tcx : &ty::ctxt<'tcx>,
2684 let ident = token::get_ident(field.node);
2686 // only find fits with at least one matching letter
2687 let mut best_dist = name.len();
2688 let fields = tcx.lookup_struct_fields(id);
2689 let mut best = None;
2690 for elem in &fields {
2691 let n = elem.name.as_str();
2692 // ignore already set fields
2693 if skip.iter().any(|&x| x == n) {
2696 // ignore private fields from non-local crates
2697 if id.krate != ast::LOCAL_CRATE && elem.vis != Visibility::Public {
2700 let dist = lev_distance(n, name);
2701 if dist < best_dist {
2706 if let Some(n) = best {
2707 tcx.sess.span_help(field.span,
2708 &format!("did you mean `{}`?", n));
2712 // Check tuple index expressions
2713 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2714 expr: &'tcx ast::Expr,
2715 lvalue_pref: LvaluePreference,
2716 base: &'tcx ast::Expr,
2717 idx: codemap::Spanned<usize>) {
2718 let tcx = fcx.ccx.tcx;
2719 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2720 let expr_t = structurally_resolved_type(fcx, expr.span,
2722 let mut tuple_like = false;
2723 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2724 let (_, autoderefs, field_ty) = autoderef(fcx,
2728 UnresolvedTypeAction::Error,
2732 ty::TyStruct(base_id, substs) => {
2733 tuple_like = tcx.is_tuple_struct(base_id);
2735 debug!("tuple struct named {:?}", base_t);
2736 let fields = tcx.lookup_struct_fields(base_id);
2737 fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
2738 idx.node, &(*substs))
2743 ty::TyTuple(ref v) => {
2745 if idx.node < v.len() { Some(v[idx.node]) } else { None }
2752 fcx.write_ty(expr.id, field_ty);
2753 fcx.write_autoderef_adjustment(base.id, autoderefs);
2758 fcx.type_error_message(
2762 format!("attempted out-of-bounds tuple index `{}` on \
2767 format!("attempted tuple index `{}` on type `{}`, but the \
2768 type was not a tuple or tuple struct",
2775 fcx.write_error(expr.id);
2778 fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2779 struct_ty: Ty<'tcx>,
2781 class_id: ast::DefId,
2782 node_id: ast::NodeId,
2783 substitutions: &'tcx subst::Substs<'tcx>,
2784 field_types: &[ty::FieldTy],
2785 ast_fields: &'tcx [ast::Field],
2786 check_completeness: bool,
2787 enum_id_opt: Option<ast::DefId>) {
2788 let tcx = fcx.ccx.tcx;
2790 let mut class_field_map = FnvHashMap();
2791 let mut fields_found = 0;
2792 for field in field_types {
2793 class_field_map.insert(field.name, (field.id, false));
2796 let mut error_happened = false;
2798 // Typecheck each field.
2799 for field in ast_fields {
2800 let mut expected_field_type = tcx.types.err;
2802 let pair = class_field_map.get(&field.ident.node.name).cloned();
2805 fcx.type_error_message(
2807 |actual| match enum_id_opt {
2809 let variant_type = tcx.enum_variant_with_id(enum_id,
2811 format!("struct variant `{}::{}` has no field named `{}`",
2812 actual, variant_type.name.as_str(),
2813 token::get_ident(field.ident.node))
2816 format!("structure `{}` has no field named `{}`",
2818 token::get_ident(field.ident.node))
2823 // prevent all specified fields from being suggested
2824 let skip_fields = ast_fields.iter().map(|ref x| x.ident.node.name.as_str());
2825 let actual_id = match enum_id_opt {
2826 Some(_) => class_id,
2827 None => struct_ty.ty_to_def_id().unwrap()
2829 suggest_field_names(actual_id, &field.ident, tcx, skip_fields.collect());
2830 error_happened = true;
2832 Some((_, true)) => {
2833 span_err!(fcx.tcx().sess, field.ident.span, E0062,
2834 "field `{}` specified more than once",
2835 token::get_ident(field.ident.node));
2836 error_happened = true;
2838 Some((field_id, false)) => {
2839 expected_field_type =
2840 tcx.lookup_field_type(class_id, field_id, substitutions);
2841 expected_field_type =
2842 fcx.normalize_associated_types_in(
2843 field.span, &expected_field_type);
2844 class_field_map.insert(
2845 field.ident.node.name, (field_id, true));
2850 // Make sure to give a type to the field even if there's
2851 // an error, so we can continue typechecking
2852 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
2856 fcx.write_error(node_id);
2859 if check_completeness && !error_happened {
2860 // Make sure the programmer specified all the fields.
2861 assert!(fields_found <= field_types.len());
2862 if fields_found < field_types.len() {
2863 let mut missing_fields = Vec::new();
2864 for class_field in field_types {
2865 let name = class_field.name;
2866 let (_, seen) = *class_field_map.get(&name).unwrap();
2868 missing_fields.push(
2869 format!("`{}`", &token::get_name(name)))
2873 span_err!(tcx.sess, span, E0063,
2874 "missing field{}: {}",
2875 if missing_fields.len() == 1 {""} else {"s"},
2876 missing_fields.join(", "));
2880 if !error_happened {
2881 fcx.write_ty(node_id, fcx.ccx.tcx.mk_struct(class_id, substitutions));
2885 fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2887 span: codemap::Span,
2888 class_id: ast::DefId,
2889 fields: &'tcx [ast::Field],
2890 base_expr: Option<&'tcx ast::Expr>) {
2891 let tcx = fcx.ccx.tcx;
2893 // Generate the struct type.
2895 ty: mut struct_type,
2896 substs: struct_substs
2897 } = fcx.instantiate_type(span, class_id);
2899 // Look up and check the fields.
2900 let class_fields = tcx.lookup_struct_fields(class_id);
2901 check_struct_or_variant_fields(fcx,
2906 fcx.ccx.tcx.mk_substs(struct_substs),
2909 base_expr.is_none(),
2911 if fcx.node_ty(id).references_error() {
2912 struct_type = tcx.types.err;
2915 // Check the base expression if necessary.
2918 Some(base_expr) => {
2919 check_expr_has_type(fcx, &*base_expr, struct_type);
2923 // Write in the resulting type.
2924 fcx.write_ty(id, struct_type);
2927 fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2929 span: codemap::Span,
2930 enum_id: ast::DefId,
2931 variant_id: ast::DefId,
2932 fields: &'tcx [ast::Field]) {
2933 let tcx = fcx.ccx.tcx;
2935 // Look up the number of type parameters and the raw type, and
2936 // determine whether the enum is region-parameterized.
2939 substs: substitutions
2940 } = fcx.instantiate_type(span, enum_id);
2942 // Look up and check the enum variant fields.
2943 let variant_fields = tcx.lookup_struct_fields(variant_id);
2944 check_struct_or_variant_fields(fcx,
2949 fcx.ccx.tcx.mk_substs(substitutions),
2950 &variant_fields[..],
2954 fcx.write_ty(id, enum_type);
2957 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2959 fields: &'tcx [ast::Field],
2960 base_expr: &'tcx Option<P<ast::Expr>>) {
2961 // Make sure to still write the types
2962 // otherwise we might ICE
2963 fcx.write_error(id);
2964 for field in fields {
2965 check_expr(fcx, &*field.expr);
2968 Some(ref base) => check_expr(fcx, &**base),
2973 type ExprCheckerWithTy = fn(&FnCtxt, &ast::Expr, Ty);
2975 let tcx = fcx.ccx.tcx;
2978 ast::ExprBox(ref opt_place, ref subexpr) => {
2979 opt_place.as_ref().map(|place|check_expr(fcx, &**place));
2980 check_expr(fcx, &**subexpr);
2982 let mut checked = false;
2983 opt_place.as_ref().map(|place| match place.node {
2984 ast::ExprPath(None, ref path) => {
2985 // FIXME(pcwalton): For now we hardcode the only permissible
2986 // place: the exchange heap.
2987 let definition = lookup_full_def(tcx, path.span, place.id);
2988 let def_id = definition.def_id();
2989 let referent_ty = fcx.expr_ty(&**subexpr);
2990 if tcx.lang_items.exchange_heap() == Some(def_id) {
2991 fcx.write_ty(id, tcx.mk_box(referent_ty));
2999 span_err!(tcx.sess, expr.span, E0066,
3000 "only the exchange heap is currently supported");
3001 fcx.write_ty(id, tcx.types.err);
3005 ast::ExprLit(ref lit) => {
3006 let typ = check_lit(fcx, &**lit, expected);
3007 fcx.write_ty(id, typ);
3009 ast::ExprBinary(op, ref lhs, ref rhs) => {
3010 op::check_binop(fcx, expr, op, lhs, rhs);
3012 ast::ExprAssignOp(op, ref lhs, ref rhs) => {
3013 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3015 ast::ExprUnary(unop, ref oprnd) => {
3016 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3018 ast::UnUniq => match ty.sty {
3020 Expectation::rvalue_hint(ty)
3026 ast::UnNot | ast::UnNeg => {
3034 let lvalue_pref = match unop {
3035 ast::UnDeref => lvalue_pref,
3038 check_expr_with_expectation_and_lvalue_pref(
3039 fcx, &**oprnd, expected_inner, lvalue_pref);
3040 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3042 if !oprnd_t.references_error() {
3045 oprnd_t = tcx.mk_box(oprnd_t);
3048 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3049 oprnd_t = match oprnd_t.builtin_deref(true) {
3051 None => match try_overloaded_deref(fcx, expr.span,
3052 Some(MethodCall::expr(expr.id)),
3053 Some(&**oprnd), oprnd_t, lvalue_pref) {
3056 fcx.type_error_message(expr.span, |actual| {
3057 format!("type `{}` cannot be \
3058 dereferenced", actual)
3066 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3068 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3069 oprnd_t = op::check_user_unop(fcx, "!", "not",
3070 tcx.lang_items.not_trait(),
3071 expr, &**oprnd, oprnd_t, unop);
3075 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3077 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3078 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3079 tcx.lang_items.neg_trait(),
3080 expr, &**oprnd, oprnd_t, unop);
3085 fcx.write_ty(id, oprnd_t);
3087 ast::ExprAddrOf(mutbl, ref oprnd) => {
3088 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3090 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3091 if fcx.tcx().expr_is_lval(&**oprnd) {
3092 // Lvalues may legitimately have unsized types.
3093 // For example, dereferences of a fat pointer and
3094 // the last field of a struct can be unsized.
3095 ExpectHasType(mt.ty)
3097 Expectation::rvalue_hint(mt.ty)
3103 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3104 check_expr_with_expectation_and_lvalue_pref(fcx,
3109 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3110 let oprnd_t = if tm.ty.references_error() {
3113 // Note: at this point, we cannot say what the best lifetime
3114 // is to use for resulting pointer. We want to use the
3115 // shortest lifetime possible so as to avoid spurious borrowck
3116 // errors. Moreover, the longest lifetime will depend on the
3117 // precise details of the value whose address is being taken
3118 // (and how long it is valid), which we don't know yet until type
3119 // inference is complete.
3121 // Therefore, here we simply generate a region variable. The
3122 // region inferencer will then select the ultimate value.
3123 // Finally, borrowck is charged with guaranteeing that the
3124 // value whose address was taken can actually be made to live
3125 // as long as it needs to live.
3126 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3127 tcx.mk_ref(tcx.mk_region(region), tm)
3129 fcx.write_ty(id, oprnd_t);
3131 ast::ExprPath(ref maybe_qself, ref path) => {
3132 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3133 fcx.to_ty(&qself.ty)
3136 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3138 } else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
3139 // Create some fake resolution that can't possibly be a type.
3140 def::PathResolution {
3141 base_def: def::DefMod(local_def(ast::CRATE_NODE_ID)),
3142 last_private: LastMod(AllPublic),
3143 depth: path.segments.len()
3146 tcx.sess.span_bug(expr.span,
3147 &format!("unbound path {:?}", expr))
3150 if let Some((opt_ty, segments, def)) =
3151 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3152 expr.span, expr.id) {
3153 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3156 instantiate_path(fcx,
3166 // We always require that the type provided as the value for
3167 // a type parameter outlives the moment of instantiation.
3168 constrain_path_type_parameters(fcx, expr);
3170 ast::ExprInlineAsm(ref ia) => {
3171 for &(_, ref input) in &ia.inputs {
3172 check_expr(fcx, &**input);
3174 for &(_, ref out, _) in &ia.outputs {
3175 check_expr(fcx, &**out);
3179 ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
3180 ast::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3181 ast::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3182 ast::ExprRet(ref expr_opt) => {
3184 ty::FnConverging(result_type) => {
3187 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3188 result_type, fcx.tcx().mk_nil()) {
3189 span_err!(tcx.sess, expr.span, E0069,
3190 "`return;` in a function whose return type is \
3194 check_expr_coercable_to_type(fcx, &**e, result_type);
3198 ty::FnDiverging => {
3199 if let Some(ref e) = *expr_opt {
3200 check_expr(fcx, &**e);
3202 span_err!(tcx.sess, expr.span, E0166,
3203 "`return` in a function declared as diverging");
3206 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3208 ast::ExprParen(ref a) => {
3209 check_expr_with_expectation_and_lvalue_pref(fcx,
3213 fcx.write_ty(id, fcx.expr_ty(&**a));
3215 ast::ExprAssign(ref lhs, ref rhs) => {
3216 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3218 let tcx = fcx.tcx();
3219 if !tcx.expr_is_lval(&**lhs) {
3220 span_err!(tcx.sess, expr.span, E0070,
3221 "illegal left-hand side expression");
3224 let lhs_ty = fcx.expr_ty(&**lhs);
3225 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3226 let rhs_ty = fcx.expr_ty(&**rhs);
3228 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3230 if lhs_ty.references_error() || rhs_ty.references_error() {
3231 fcx.write_error(id);
3236 ast::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3237 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3238 id, expr.span, expected);
3240 ast::ExprIfLet(..) => {
3241 tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
3243 ast::ExprWhile(ref cond, ref body, _) => {
3244 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3245 check_block_no_value(fcx, &**body);
3246 let cond_ty = fcx.expr_ty(&**cond);
3247 let body_ty = fcx.node_ty(body.id);
3248 if cond_ty.references_error() || body_ty.references_error() {
3249 fcx.write_error(id);
3255 ast::ExprWhileLet(..) => {
3256 tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
3258 ast::ExprForLoop(..) => {
3259 tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
3261 ast::ExprLoop(ref body, _) => {
3262 check_block_no_value(fcx, &**body);
3263 if !may_break(tcx, expr.id, &**body) {
3264 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3269 ast::ExprMatch(ref discrim, ref arms, match_src) => {
3270 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3272 ast::ExprClosure(capture, ref decl, ref body) => {
3273 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3275 ast::ExprBlock(ref b) => {
3276 check_block_with_expected(fcx, &**b, expected);
3277 fcx.write_ty(id, fcx.node_ty(b.id));
3279 ast::ExprCall(ref callee, ref args) => {
3280 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3282 ast::ExprMethodCall(ident, ref tps, ref args) => {
3283 check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref);
3284 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3285 let args_err = arg_tys.fold(false,
3287 rest_err || a.references_error()});
3289 fcx.write_error(id);
3292 ast::ExprCast(ref e, ref t) => {
3293 if let ast::TyFixedLengthVec(_, ref count_expr) = t.node {
3294 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3297 // Find the type of `e`. Supply hints based on the type we are casting to,
3299 let t_cast = fcx.to_ty(t);
3300 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3301 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3302 let t_expr = fcx.expr_ty(e);
3304 // Eagerly check for some obvious errors.
3305 if t_expr.references_error() {
3306 fcx.write_error(id);
3307 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3308 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3310 // Write a type for the whole expression, assuming everything is going
3312 fcx.write_ty(id, t_cast);
3314 // Defer other checks until we're done type checking.
3315 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3316 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3317 deferred_cast_checks.push(cast_check);
3320 ast::ExprVec(ref args) => {
3321 let uty = expected.to_option(fcx).and_then(|uty| {
3323 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3328 let typ = match uty {
3331 check_expr_coercable_to_type(fcx, &**e, uty);
3336 let t: Ty = fcx.infcx().next_ty_var();
3338 check_expr_has_type(fcx, &**e, t);
3343 let typ = tcx.mk_array(typ, args.len());
3344 fcx.write_ty(id, typ);
3346 ast::ExprRepeat(ref element, ref count_expr) => {
3347 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3348 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3350 let uty = match expected {
3351 ExpectHasType(uty) => {
3353 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3360 let (element_ty, t) = match uty {
3362 check_expr_coercable_to_type(fcx, &**element, uty);
3366 let t: Ty = fcx.infcx().next_ty_var();
3367 check_expr_has_type(fcx, &**element, t);
3368 (fcx.expr_ty(&**element), t)
3373 // For [foo, ..n] where n > 1, `foo` must have
3375 fcx.require_type_meets(
3382 if element_ty.references_error() {
3383 fcx.write_error(id);
3385 let t = tcx.mk_array(t, count);
3386 fcx.write_ty(id, t);
3389 ast::ExprTup(ref elts) => {
3390 let flds = expected.only_has_type(fcx).and_then(|ty| {
3392 ty::TyTuple(ref flds) => Some(&flds[..]),
3396 let mut err_field = false;
3398 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3399 let t = match flds {
3400 Some(ref fs) if i < fs.len() => {
3402 check_expr_coercable_to_type(fcx, &**e, ety);
3406 check_expr_with_expectation(fcx, &**e, NoExpectation);
3410 err_field = err_field || t.references_error();
3414 fcx.write_error(id);
3416 let typ = tcx.mk_tup(elt_ts);
3417 fcx.write_ty(id, typ);
3420 ast::ExprStruct(ref path, ref fields, ref base_expr) => {
3421 // Resolve the path.
3422 let def = lookup_full_def(tcx, path.span, id);
3423 let struct_id = match def {
3424 def::DefVariant(enum_id, variant_id, true) => {
3425 if let &Some(ref base_expr) = base_expr {
3426 span_err!(tcx.sess, base_expr.span, E0436,
3427 "functional record update syntax requires a struct");
3428 fcx.write_error(base_expr.id);
3430 check_struct_enum_variant(fcx, id, expr.span, enum_id,
3431 variant_id, &fields[..]);
3434 def::DefTrait(def_id) => {
3435 span_err!(tcx.sess, path.span, E0159,
3436 "use of trait `{}` as a struct constructor",
3437 pprust::path_to_string(path));
3438 check_struct_fields_on_error(fcx,
3445 // Verify that this was actually a struct.
3446 let typ = fcx.ccx.tcx.lookup_item_type(def.def_id());
3448 ty::TyStruct(struct_did, _) => {
3449 check_struct_constructor(fcx,
3454 base_expr.as_ref().map(|e| &**e));
3457 span_err!(tcx.sess, path.span, E0071,
3458 "`{}` does not name a structure",
3459 pprust::path_to_string(path));
3460 check_struct_fields_on_error(fcx,
3471 // Turn the path into a type and verify that that type unifies with
3472 // the resulting structure type. This is needed to handle type
3473 // parameters correctly.
3474 let actual_structure_type = fcx.expr_ty(&*expr);
3475 if !actual_structure_type.references_error() {
3476 let type_and_substs = fcx.instantiate_struct_literal_ty(struct_id, path);
3477 match fcx.mk_subty(false,
3478 infer::Misc(path.span),
3479 actual_structure_type,
3480 type_and_substs.ty) {
3482 Err(type_error) => {
3483 span_err!(fcx.tcx().sess, path.span, E0235,
3484 "structure constructor specifies a \
3485 structure of type `{}`, but this \
3486 structure has type `{}`: {}",
3488 .ty_to_string(type_and_substs.ty),
3491 actual_structure_type),
3493 tcx.note_and_explain_type_err(&type_error, path.span);
3498 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3500 ast::ExprField(ref base, ref field) => {
3501 check_field(fcx, expr, lvalue_pref, &**base, field);
3503 ast::ExprTupField(ref base, idx) => {
3504 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3506 ast::ExprIndex(ref base, ref idx) => {
3507 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3508 check_expr(fcx, &**idx);
3510 let base_t = fcx.expr_ty(&**base);
3511 let idx_t = fcx.expr_ty(&**idx);
3513 if base_t.references_error() {
3514 fcx.write_ty(id, base_t);
3515 } else if idx_t.references_error() {
3516 fcx.write_ty(id, idx_t);
3518 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3519 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3520 Some((index_ty, element_ty)) => {
3521 let idx_expr_ty = fcx.expr_ty(idx);
3522 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3523 fcx.write_ty(id, element_ty);
3526 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3527 fcx.type_error_message(
3530 format!("cannot index a value of type `{}`",
3535 fcx.write_ty(id, fcx.tcx().types.err);
3540 ast::ExprRange(ref start, ref end) => {
3541 let t_start = start.as_ref().map(|e| {
3542 check_expr(fcx, &**e);
3545 let t_end = end.as_ref().map(|e| {
3546 check_expr(fcx, &**e);
3550 let idx_type = match (t_start, t_end) {
3551 (Some(ty), None) | (None, Some(ty)) => {
3554 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3555 t_end.references_error()) => {
3556 Some(fcx.tcx().types.err)
3558 (Some(t_start), Some(t_end)) => {
3559 Some(infer::common_supertype(fcx.infcx(),
3560 infer::RangeExpression(expr.span),
3568 // Note that we don't check the type of start/end satisfy any
3569 // bounds because right now the range structs do not have any. If we add
3570 // some bounds, then we'll need to check `t_start` against them here.
3572 let range_type = match idx_type {
3573 Some(idx_type) if idx_type.references_error() => {
3577 // Find the did from the appropriate lang item.
3578 let did = match (start, end) {
3579 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3580 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3581 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3583 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3587 if let Some(did) = did {
3588 let predicates = tcx.lookup_predicates(did);
3589 let substs = Substs::new_type(vec![idx_type], vec![]);
3590 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3591 fcx.add_obligations_for_parameters(
3592 traits::ObligationCause::new(expr.span,
3594 traits::ItemObligation(did)),
3597 tcx.mk_struct(did, tcx.mk_substs(substs))
3599 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3604 // Neither start nor end => RangeFull
3605 if let Some(did) = tcx.lang_items.range_full_struct() {
3606 let substs = Substs::new_type(vec![], vec![]);
3607 tcx.mk_struct(did, tcx.mk_substs(substs))
3609 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3615 fcx.write_ty(id, range_type);
3620 debug!("type of expr({}) {} is...", expr.id,
3621 syntax::print::pprust::expr_to_string(expr));
3622 debug!("... {:?}, expected is {:?}",
3629 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3630 path_res: def::PathResolution,
3631 opt_self_ty: Option<Ty<'tcx>>,
3632 path: &'a ast::Path,
3634 node_id: ast::NodeId)
3635 -> Option<(Option<Ty<'tcx>>,
3636 &'a [ast::PathSegment],
3640 // Associated constants can't depend on generic types.
3641 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3645 node_id: ast::NodeId) -> bool {
3647 def::DefAssociatedConst(..) => {
3648 if ty.has_param_types() || ty.has_self_ty() {
3649 span_err!(fcx.sess(), span, E0329,
3650 "Associated consts cannot depend \
3651 on type parameters or Self.");
3652 fcx.write_error(node_id);
3661 // If fully resolved already, we don't have to do anything.
3662 if path_res.depth == 0 {
3663 if let Some(ty) = opt_self_ty {
3664 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3669 Some((opt_self_ty, &path.segments, path_res.base_def))
3671 let mut def = path_res.base_def;
3672 let ty_segments = path.segments.split_last().unwrap().1;
3673 let base_ty_end = path.segments.len() - path_res.depth;
3674 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3675 PathParamMode::Optional,
3678 &ty_segments[..base_ty_end],
3679 &ty_segments[base_ty_end..]);
3680 let item_segment = path.segments.last().unwrap();
3681 let item_name = item_segment.identifier.name;
3682 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3684 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3687 // Write back the new resolution.
3688 fcx.ccx.tcx.def_map.borrow_mut()
3689 .insert(node_id, def::PathResolution {
3691 last_private: path_res.last_private.or(lp),
3694 Some((Some(ty), slice::ref_slice(item_segment), def))
3697 method::report_error(fcx, span, ty,
3698 item_name, None, error);
3699 fcx.write_error(node_id);
3706 fn constrain_path_type_parameters(fcx: &FnCtxt,
3709 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3710 fcx.add_default_region_param_bounds(&item_substs.substs, expr);
3714 impl<'tcx> Expectation<'tcx> {
3715 /// Provide an expectation for an rvalue expression given an *optional*
3716 /// hint, which is not required for type safety (the resulting type might
3717 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3718 /// is useful in determining the concrete type.
3720 /// The primary use case is where the expected type is a fat pointer,
3721 /// like `&[isize]`. For example, consider the following statement:
3723 /// let x: &[isize] = &[1, 2, 3];
3725 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3726 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3727 /// expectation `ExpectHasType([isize])`, that would be too strong --
3728 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3729 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3730 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3731 /// which still is useful, because it informs integer literals and the like.
3732 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3733 /// for examples of where this comes up,.
3734 fn rvalue_hint(ty: Ty<'tcx>) -> Expectation<'tcx> {
3736 ty::TySlice(_) | ty::TyTrait(..) => {
3737 ExpectRvalueLikeUnsized(ty)
3739 _ => ExpectHasType(ty)
3743 // Resolves `expected` by a single level if it is a variable. If
3744 // there is no expected type or resolution is not possible (e.g.,
3745 // no constraints yet present), just returns `None`.
3746 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3751 ExpectCastableToType(t) => {
3752 ExpectCastableToType(
3753 fcx.infcx().resolve_type_vars_if_possible(&t))
3755 ExpectHasType(t) => {
3757 fcx.infcx().resolve_type_vars_if_possible(&t))
3759 ExpectRvalueLikeUnsized(t) => {
3760 ExpectRvalueLikeUnsized(
3761 fcx.infcx().resolve_type_vars_if_possible(&t))
3766 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3767 match self.resolve(fcx) {
3768 NoExpectation => None,
3769 ExpectCastableToType(ty) |
3771 ExpectRvalueLikeUnsized(ty) => Some(ty),
3775 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3776 match self.resolve(fcx) {
3777 ExpectHasType(ty) => Some(ty),
3783 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3784 local: &'tcx ast::Local,
3785 init: &'tcx ast::Expr)
3787 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3789 let local_ty = fcx.local_ty(init.span, local.id);
3790 if let Some(m) = ref_bindings {
3791 // Somewhat subtle: if we have a `ref` binding in the pattern,
3792 // we want to avoid introducing coercions for the RHS. This is
3793 // both because it helps preserve sanity and, in the case of
3794 // ref mut, for soundness (issue #23116). In particular, in
3795 // the latter case, we need to be clear that the type of the
3796 // referent for the reference that results is *equal to* the
3797 // type of the lvalue it is referencing, and not some
3798 // supertype thereof.
3799 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3800 let init_ty = fcx.expr_ty(init);
3801 demand::eqtype(fcx, init.span, init_ty, local_ty);
3803 check_expr_coercable_to_type(fcx, init, local_ty)
3807 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local) {
3808 let tcx = fcx.ccx.tcx;
3810 let t = fcx.local_ty(local.span, local.id);
3811 fcx.write_ty(local.id, t);
3813 if let Some(ref init) = local.init {
3814 check_decl_initializer(fcx, local, &**init);
3815 let init_ty = fcx.expr_ty(&**init);
3816 if init_ty.references_error() {
3817 fcx.write_ty(local.id, init_ty);
3821 let pcx = pat_ctxt {
3823 map: pat_id_map(&tcx.def_map, &*local.pat),
3825 _match::check_pat(&pcx, &*local.pat, t);
3826 let pat_ty = fcx.node_ty(local.pat.id);
3827 if pat_ty.references_error() {
3828 fcx.write_ty(local.id, pat_ty);
3832 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
3834 let mut saw_bot = false;
3835 let mut saw_err = false;
3837 ast::StmtDecl(ref decl, id) => {
3840 ast::DeclLocal(ref l) => {
3841 check_decl_local(fcx, &**l);
3842 let l_t = fcx.node_ty(l.id);
3843 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3844 saw_err = saw_err || l_t.references_error();
3846 ast::DeclItem(_) => {/* ignore for now */ }
3849 ast::StmtExpr(ref expr, id) => {
3851 // Check with expected type of ()
3852 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3853 let expr_ty = fcx.expr_ty(&**expr);
3854 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3855 saw_err = saw_err || expr_ty.references_error();
3857 ast::StmtSemi(ref expr, id) => {
3859 check_expr(fcx, &**expr);
3860 let expr_ty = fcx.expr_ty(&**expr);
3861 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3862 saw_err |= expr_ty.references_error();
3864 ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro")
3867 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3870 fcx.write_error(node_id);
3873 fcx.write_nil(node_id)
3877 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) {
3878 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3879 let blkty = fcx.node_ty(blk.id);
3880 if blkty.references_error() {
3881 fcx.write_error(blk.id);
3883 let nilty = fcx.tcx().mk_nil();
3884 demand::suptype(fcx, blk.span, nilty, blkty);
3888 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3889 blk: &'tcx ast::Block,
3890 expected: Expectation<'tcx>) {
3892 let mut fcx_ps = fcx.ps.borrow_mut();
3893 let unsafety_state = fcx_ps.recurse(blk);
3894 replace(&mut *fcx_ps, unsafety_state)
3897 let mut warned = false;
3898 let mut any_diverges = false;
3899 let mut any_err = false;
3900 for s in &blk.stmts {
3901 check_stmt(fcx, &**s);
3902 let s_id = ast_util::stmt_id(&**s);
3903 let s_ty = fcx.node_ty(s_id);
3904 if any_diverges && !warned && match s.node {
3905 ast::StmtDecl(ref decl, _) => {
3907 ast::DeclLocal(_) => true,
3911 ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
3917 .add_lint(lint::builtin::UNREACHABLE_CODE,
3920 "unreachable statement".to_string());
3923 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3924 any_err = any_err || s_ty.references_error();
3927 None => if any_err {
3928 fcx.write_error(blk.id);
3929 } else if any_diverges {
3930 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3932 fcx.write_nil(blk.id);
3935 if any_diverges && !warned {
3939 .add_lint(lint::builtin::UNREACHABLE_CODE,
3942 "unreachable expression".to_string());
3944 let ety = match expected {
3945 ExpectHasType(ety) => {
3946 check_expr_coercable_to_type(fcx, &**e, ety);
3950 check_expr_with_expectation(fcx, &**e, expected);
3956 fcx.write_error(blk.id);
3957 } else if any_diverges {
3958 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3960 fcx.write_ty(blk.id, ety);
3965 *fcx.ps.borrow_mut() = prev;
3968 /// Checks a constant appearing in a type. At the moment this is just the
3969 /// length expression in a fixed-length vector, but someday it might be
3970 /// extended to type-level numeric literals.
3971 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3972 expr: &'tcx ast::Expr,
3973 expected_type: Ty<'tcx>) {
3974 let tables = RefCell::new(ty::Tables::empty());
3975 let inh = static_inherited_fields(ccx, &tables);
3976 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3977 check_const_with_ty(&fcx, expr.span, expr, expected_type);
3980 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3984 let tables = RefCell::new(ty::Tables::empty());
3985 let inh = static_inherited_fields(ccx, &tables);
3986 let rty = ccx.tcx.node_id_to_type(id);
3987 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
3988 let declty = fcx.ccx.tcx.lookup_item_type(local_def(id)).ty;
3989 check_const_with_ty(&fcx, sp, e, declty);
3992 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3996 // Gather locals in statics (because of block expressions).
3997 // This is technically unnecessary because locals in static items are forbidden,
3998 // but prevents type checking from blowing up before const checking can properly
4000 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4002 check_expr_with_hint(fcx, e, declty);
4003 demand::coerce(fcx, e.span, declty, e);
4004 fcx.select_all_obligations_or_error();
4006 regionck::regionck_expr(fcx, e);
4007 writeback::resolve_type_vars_in_expr(fcx, e);
4010 /// Checks whether a type can be represented in memory. In particular, it
4011 /// identifies types that contain themselves without indirection through a
4012 /// pointer, which would mean their size is unbounded. This is different from
4013 /// the question of whether a type can be instantiated. See the definition of
4014 /// `check_instantiable`.
4015 pub fn check_representable(tcx: &ty::ctxt,
4017 item_id: ast::NodeId,
4018 designation: &str) -> bool {
4019 let rty = tcx.node_id_to_type(item_id);
4021 // Check that it is possible to represent this type. This call identifies
4022 // (1) types that contain themselves and (2) types that contain a different
4023 // recursive type. It is only necessary to throw an error on those that
4024 // contain themselves. For case 2, there must be an inner type that will be
4025 // caught by case 1.
4026 match rty.is_representable(tcx, sp) {
4027 ty::SelfRecursive => {
4028 span_err!(tcx.sess, sp, E0072,
4029 "illegal recursive {} type; \
4030 wrap the inner value in a box to make it representable",
4034 ty::Representable | ty::ContainsRecursive => (),
4039 /// Checks whether a type can be created without an instance of itself.
4040 /// This is similar but different from the question of whether a type
4041 /// can be represented. For example, the following type:
4043 /// enum foo { None, Some(foo) }
4045 /// is instantiable but is not representable. Similarly, the type
4047 /// enum foo { Some(@foo) }
4049 /// is representable, but not instantiable.
4050 pub fn check_instantiable(tcx: &ty::ctxt,
4052 item_id: ast::NodeId)
4054 let item_ty = tcx.node_id_to_type(item_id);
4055 if !item_ty.is_instantiable(tcx) {
4056 span_err!(tcx.sess, sp, E0073,
4057 "this type cannot be instantiated without an \
4058 instance of itself");
4059 fileline_help!(tcx.sess, sp, "consider using `Option<{:?}>`",
4067 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4068 let t = tcx.node_id_to_type(id);
4069 if t.needs_subst() {
4070 span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
4074 ty::TyStruct(did, substs) => {
4075 let fields = tcx.lookup_struct_fields(did);
4076 if fields.is_empty() {
4077 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4080 let e = tcx.lookup_field_type(did, fields[0].id, substs);
4081 if !fields.iter().all(
4082 |f| tcx.lookup_field_type(did, f.id, substs) == e) {
4083 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4086 if !e.is_machine() {
4087 span_err!(tcx.sess, sp, E0077,
4088 "SIMD vector element type should be machine type");
4096 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4098 vs: &'tcx [P<ast::Variant>],
4101 fn disr_in_range(ccx: &CrateCtxt,
4103 disr: ty::Disr) -> bool {
4104 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4106 ast::TyU8 => disr as u8 as Disr == disr,
4107 ast::TyU16 => disr as u16 as Disr == disr,
4108 ast::TyU32 => disr as u32 as Disr == disr,
4109 ast::TyU64 => disr as u64 as Disr == disr,
4110 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4113 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4115 ast::TyI8 => disr as i8 as Disr == disr,
4116 ast::TyI16 => disr as i16 as Disr == disr,
4117 ast::TyI32 => disr as i32 as Disr == disr,
4118 ast::TyI64 => disr as i64 as Disr == disr,
4119 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4123 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4124 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4128 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4129 vs: &'tcx [P<ast::Variant>],
4131 hint: attr::ReprAttr) {
4132 #![allow(trivial_numeric_casts)]
4134 let rty = ccx.tcx.node_id_to_type(id);
4135 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4137 let tables = RefCell::new(ty::Tables::empty());
4138 let inh = static_inherited_fields(ccx, &tables);
4139 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4141 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4143 if let Some(ref e) = v.node.disr_expr {
4144 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4148 let def_id = local_def(id);
4150 // ty::enum_variants guards against discriminant overflows, so
4151 // we need not check for that.
4152 let variants = ccx.tcx.enum_variants(def_id);
4154 for (v, variant) in vs.iter().zip(variants.iter()) {
4155 let current_disr_val = variant.disr_val;
4157 // Check for duplicate discriminant values
4158 match disr_vals.iter().position(|&x| x == current_disr_val) {
4160 span_err!(ccx.tcx.sess, v.span, E0081,
4161 "discriminant value `{}` already exists", disr_vals[i]);
4162 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variants[i].id.node),
4163 "conflicting discriminant here")
4167 // Check for unrepresentable discriminant values
4169 attr::ReprAny | attr::ReprExtern => (),
4170 attr::ReprInt(sp, ity) => {
4171 if !disr_in_range(ccx, ity, current_disr_val) {
4172 span_err!(ccx.tcx.sess, v.span, E0082,
4173 "discriminant value outside specified type");
4174 span_note!(ccx.tcx.sess, sp,
4175 "discriminant type specified here");
4178 attr::ReprPacked => {
4179 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4182 disr_vals.push(current_disr_val);
4186 let hint = *ccx.tcx.lookup_repr_hints(ast::DefId { krate: ast::LOCAL_CRATE, node: id })
4187 .get(0).unwrap_or(&attr::ReprAny);
4189 if hint != attr::ReprAny && vs.len() <= 1 {
4191 span_err!(ccx.tcx.sess, sp, E0083,
4192 "unsupported representation for univariant enum");
4194 span_err!(ccx.tcx.sess, sp, E0084,
4195 "unsupported representation for zero-variant enum");
4199 do_check(ccx, vs, id, hint);
4201 check_representable(ccx.tcx, sp, id, "enum");
4203 // Check that it is possible to instantiate this enum:
4205 // This *sounds* like the same that as representable, but it's
4206 // not. See def'n of `check_instantiable()` for details.
4207 check_instantiable(ccx.tcx, sp, id);
4210 // Returns the type parameter count and the type for the given definition.
4211 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4214 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4216 def::DefLocal(nid) | def::DefUpvar(nid, _) => {
4217 let typ = fcx.local_ty(sp, nid);
4218 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4219 ty::GenericPredicates::empty())
4221 def::DefFn(id, _) | def::DefMethod(id, _) |
4222 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4223 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
4224 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4228 def::DefAssociatedTy(..) |
4230 def::DefTyParam(..) |
4232 def::DefForeignMod(..) |
4234 def::DefRegion(..) |
4236 def::DefSelfTy(..) => {
4237 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4242 // Instantiates the given path, which must refer to an item with the given
4243 // number of type parameters and type.
4244 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4245 segments: &[ast::PathSegment],
4246 type_scheme: TypeScheme<'tcx>,
4247 type_predicates: &ty::GenericPredicates<'tcx>,
4248 opt_self_ty: Option<Ty<'tcx>>,
4251 node_id: ast::NodeId) {
4252 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4258 // We need to extract the type parameters supplied by the user in
4259 // the path `path`. Due to the current setup, this is a bit of a
4260 // tricky-process; the problem is that resolve only tells us the
4261 // end-point of the path resolution, and not the intermediate steps.
4262 // Luckily, we can (at least for now) deduce the intermediate steps
4263 // just from the end-point.
4265 // There are basically four cases to consider:
4267 // 1. Reference to a *type*, such as a struct or enum:
4269 // mod a { struct Foo<T> { ... } }
4271 // Because we don't allow types to be declared within one
4272 // another, a path that leads to a type will always look like
4273 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4274 // that only the final segment can have type parameters, and
4275 // they are located in the TypeSpace.
4277 // *Note:* Generally speaking, references to types don't
4278 // actually pass through this function, but rather the
4279 // `ast_ty_to_ty` function in `astconv`. However, in the case
4280 // of struct patterns (and maybe literals) we do invoke
4281 // `instantiate_path` to get the general type of an instance of
4282 // a struct. (In these cases, there are actually no type
4283 // parameters permitted at present, but perhaps we will allow
4284 // them in the future.)
4286 // 1b. Reference to a enum variant or tuple-like struct:
4288 // struct foo<T>(...)
4289 // enum E<T> { foo(...) }
4291 // In these cases, the parameters are declared in the type
4294 // 2. Reference to a *fn item*:
4298 // In this case, the path will again always have the form
4299 // `a::b::foo::<T>` where only the final segment should have
4300 // type parameters. However, in this case, those parameters are
4301 // declared on a value, and hence are in the `FnSpace`.
4303 // 3. Reference to a *method*:
4305 // impl<A> SomeStruct<A> {
4309 // Here we can have a path like
4310 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4311 // may appear in two places. The penultimate segment,
4312 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4313 // final segment, `foo::<B>` contains parameters in fn space.
4315 // 4. Reference to an *associated const*:
4317 // impl<A> AnotherStruct<A> {
4318 // const FOO: B = BAR;
4321 // The path in this case will look like
4322 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4323 // only will have parameters in TypeSpace.
4325 // The first step then is to categorize the segments appropriately.
4327 assert!(!segments.is_empty());
4329 let mut ufcs_method = None;
4330 let mut segment_spaces: Vec<_>;
4332 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4333 def::DefSelfTy(..) |
4334 def::DefStruct(..) |
4335 def::DefVariant(..) |
4337 def::DefAssociatedTy(..) |
4339 def::DefPrimTy(..) |
4340 def::DefTyParam(..) => {
4341 // Everything but the final segment should have no
4342 // parameters at all.
4343 segment_spaces = vec![None; segments.len() - 1];
4344 segment_spaces.push(Some(subst::TypeSpace));
4347 // Case 2. Reference to a top-level value.
4350 def::DefStatic(..) => {
4351 segment_spaces = vec![None; segments.len() - 1];
4352 segment_spaces.push(Some(subst::FnSpace));
4355 // Case 3. Reference to a method.
4356 def::DefMethod(_, provenance) => {
4358 def::FromTrait(trait_did) => {
4359 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4361 def::FromImpl(_) => {}
4364 if segments.len() >= 2 {
4365 segment_spaces = vec![None; segments.len() - 2];
4366 segment_spaces.push(Some(subst::TypeSpace));
4367 segment_spaces.push(Some(subst::FnSpace));
4369 // `<T>::method` will end up here, and so can `T::method`.
4370 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4371 segment_spaces = vec![Some(subst::FnSpace)];
4372 ufcs_method = Some((provenance, self_ty));
4376 def::DefAssociatedConst(_, provenance) => {
4378 def::FromTrait(trait_did) => {
4379 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4381 def::FromImpl(_) => {}
4384 if segments.len() >= 2 {
4385 segment_spaces = vec![None; segments.len() - 2];
4386 segment_spaces.push(Some(subst::TypeSpace));
4387 segment_spaces.push(None);
4389 segment_spaces = vec![None];
4393 // Other cases. Various nonsense that really shouldn't show up
4394 // here. If they do, an error will have been reported
4395 // elsewhere. (I hope)
4397 def::DefForeignMod(..) |
4400 def::DefRegion(..) |
4402 def::DefUpvar(..) => {
4403 segment_spaces = vec![None; segments.len()];
4406 assert_eq!(segment_spaces.len(), segments.len());
4408 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4409 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4410 // type parameters are not mandatory.
4411 let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
4413 debug!("segment_spaces={:?}", segment_spaces);
4415 // Next, examine the definition, and determine how many type
4416 // parameters we expect from each space.
4417 let type_defs = &type_scheme.generics.types;
4418 let region_defs = &type_scheme.generics.regions;
4420 // Now that we have categorized what space the parameters for each
4421 // segment belong to, let's sort out the parameters that the user
4422 // provided (if any) into their appropriate spaces. We'll also report
4423 // errors if type parameters are provided in an inappropriate place.
4424 let mut substs = Substs::empty();
4425 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4428 check_path_args(fcx.tcx(), slice::ref_slice(segment),
4429 NO_TPS | NO_REGIONS);
4433 push_explicit_parameters_from_segment_to_substs(fcx,
4443 if let Some(self_ty) = opt_self_ty {
4444 if type_defs.len(subst::SelfSpace) == 1 {
4445 substs.types.push(subst::SelfSpace, self_ty);
4449 // Now we have to compare the types that the user *actually*
4450 // provided against the types that were *expected*. If the user
4451 // did not provide any types, then we want to substitute inference
4452 // variables. If the user provided some types, we may still need
4453 // to add defaults. If the user provided *too many* types, that's
4455 for &space in &ParamSpace::all() {
4456 adjust_type_parameters(fcx, span, space, type_defs,
4457 require_type_space, &mut substs);
4458 assert_eq!(substs.types.len(space), type_defs.len(space));
4460 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4461 assert_eq!(substs.regions().len(space), region_defs.len(space));
4464 // The things we are substituting into the type should not contain
4465 // escaping late-bound regions, and nor should the base type scheme.
4466 assert!(!substs.has_regions_escaping_depth(0));
4467 assert!(!type_scheme.has_escaping_regions());
4469 // Add all the obligations that are required, substituting and
4470 // normalized appropriately.
4471 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4472 fcx.add_obligations_for_parameters(
4473 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4476 // Substitute the values for the type parameters into the type of
4477 // the referenced item.
4478 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4481 if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
4482 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4483 // is inherent, there is no `Self` parameter, instead, the impl needs
4484 // type parameters, which we can infer by unifying the provided `Self`
4485 // with the substituted impl type.
4486 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4487 assert_eq!(substs.types.len(subst::TypeSpace),
4488 impl_scheme.generics.types.len(subst::TypeSpace));
4489 assert_eq!(substs.regions().len(subst::TypeSpace),
4490 impl_scheme.generics.regions.len(subst::TypeSpace));
4492 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4493 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4494 fcx.tcx().sess.span_bug(span,
4496 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4502 fcx.write_ty(node_id, ty_substituted);
4503 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4506 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4507 /// parameters are provided, then reports an error and clears the output vector.
4509 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4510 /// use inference variables. This seems less likely to lead to derived errors.
4512 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4513 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4514 /// here because we can easily use the precise span of the N+1'th parameter.
4515 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4516 fcx: &FnCtxt<'a, 'tcx>,
4517 space: subst::ParamSpace,
4519 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4520 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4521 segment: &ast::PathSegment,
4522 substs: &mut Substs<'tcx>)
4524 match segment.parameters {
4525 ast::AngleBracketedParameters(ref data) => {
4526 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4527 fcx, space, type_defs, region_defs, data, substs);
4530 ast::ParenthesizedParameters(ref data) => {
4531 span_err!(fcx.tcx().sess, span, E0238,
4532 "parenthesized parameters may only be used with a trait");
4533 push_explicit_parenthesized_parameters_from_segment_to_substs(
4534 fcx, space, span, type_defs, data, substs);
4539 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4540 fcx: &FnCtxt<'a, 'tcx>,
4541 space: subst::ParamSpace,
4542 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4543 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4544 data: &ast::AngleBracketedParameterData,
4545 substs: &mut Substs<'tcx>)
4548 let type_count = type_defs.len(space);
4549 assert_eq!(substs.types.len(space), 0);
4550 for (i, typ) in data.types.iter().enumerate() {
4551 let t = fcx.to_ty(&**typ);
4553 substs.types.push(space, t);
4554 } else if i == type_count {
4555 span_err!(fcx.tcx().sess, typ.span, E0087,
4556 "too many type parameters provided: \
4557 expected at most {} parameter{}, \
4558 found {} parameter{}",
4560 if type_count == 1 {""} else {"s"},
4562 if data.types.len() == 1 {""} else {"s"});
4563 substs.types.truncate(space, 0);
4569 if !data.bindings.is_empty() {
4570 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4571 "unexpected binding of associated item in expression path \
4572 (only allowed in type paths)");
4576 let region_count = region_defs.len(space);
4577 assert_eq!(substs.regions().len(space), 0);
4578 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4579 let r = ast_region_to_region(fcx.tcx(), lifetime);
4580 if i < region_count {
4581 substs.mut_regions().push(space, r);
4582 } else if i == region_count {
4583 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4584 "too many lifetime parameters provided: \
4585 expected {} parameter{}, found {} parameter{}",
4587 if region_count == 1 {""} else {"s"},
4588 data.lifetimes.len(),
4589 if data.lifetimes.len() == 1 {""} else {"s"});
4590 substs.mut_regions().truncate(space, 0);
4598 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4599 /// but intended for `Foo(A,B) -> C` form. This expands to
4600 /// roughly the same thing as `Foo<(A,B),C>`. One important
4601 /// difference has to do with the treatment of anonymous
4602 /// regions, which are translated into bound regions (NYI).
4603 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4604 fcx: &FnCtxt<'a, 'tcx>,
4605 space: subst::ParamSpace,
4607 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4608 data: &ast::ParenthesizedParameterData,
4609 substs: &mut Substs<'tcx>)
4611 let type_count = type_defs.len(space);
4613 span_err!(fcx.tcx().sess, span, E0167,
4614 "parenthesized form always supplies 2 type parameters, \
4615 but only {} parameter(s) were expected",
4619 let input_tys: Vec<Ty> =
4620 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4622 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4624 if type_count >= 1 {
4625 substs.types.push(space, tuple_ty);
4628 let output_ty: Option<Ty> =
4629 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4632 output_ty.unwrap_or(fcx.tcx().mk_nil());
4634 if type_count >= 2 {
4635 substs.types.push(space, output_ty);
4639 fn adjust_type_parameters<'a, 'tcx>(
4640 fcx: &FnCtxt<'a, 'tcx>,
4643 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4644 require_type_space: bool,
4645 substs: &mut Substs<'tcx>)
4647 let provided_len = substs.types.len(space);
4648 let desired = defs.get_slice(space);
4649 let required_len = desired.iter()
4650 .take_while(|d| d.default.is_none())
4653 debug!("adjust_type_parameters(space={:?}, \
4662 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4663 assert!(provided_len <= desired.len());
4665 // Nothing specified at all: supply inference variables for
4667 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4668 substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
4672 // Too few parameters specified: report an error and use Err
4674 if provided_len < required_len {
4676 if desired.len() != required_len { "at least " } else { "" };
4677 span_err!(fcx.tcx().sess, span, E0089,
4678 "too few type parameters provided: expected {}{} parameter{}, \
4679 found {} parameter{}",
4680 qualifier, required_len,
4681 if required_len == 1 {""} else {"s"},
4683 if provided_len == 1 {""} else {"s"});
4684 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4688 // Otherwise, add in any optional parameters that the user
4689 // omitted. The case of *too many* parameters is handled
4691 // push_explicit_parameters_from_segment_to_substs(). Note
4692 // that the *default* type are expressed in terms of all prior
4693 // parameters, so we have to substitute as we go with the
4694 // partial substitution that we have built up.
4695 for i in provided_len..desired.len() {
4696 let default = desired[i].default.unwrap();
4697 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4698 substs.types.push(space, default);
4700 assert_eq!(substs.types.len(space), desired.len());
4702 debug!("Final substs: {:?}", substs);
4705 fn adjust_region_parameters(
4709 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4710 substs: &mut Substs)
4712 let provided_len = substs.mut_regions().len(space);
4713 let desired = defs.get_slice(space);
4715 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4716 assert!(provided_len <= desired.len());
4718 // If nothing was provided, just use inference variables.
4719 if provided_len == 0 {
4720 substs.mut_regions().replace(
4722 fcx.infcx().region_vars_for_defs(span, desired));
4726 // If just the right number were provided, everybody is happy.
4727 if provided_len == desired.len() {
4731 // Otherwise, too few were provided. Report an error and then
4732 // use inference variables.
4733 span_err!(fcx.tcx().sess, span, E0090,
4734 "too few lifetime parameters provided: expected {} parameter{}, \
4735 found {} parameter{}",
4737 if desired.len() == 1 {""} else {"s"},
4739 if provided_len == 1 {""} else {"s"});
4741 substs.mut_regions().replace(
4743 fcx.infcx().region_vars_for_defs(span, desired));
4747 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4751 where F: Fn() -> Ty<'tcx>
4753 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4756 let alternative = f();
4759 if alternative.is_ty_var() || alternative.references_error() {
4760 fcx.type_error_message(sp, |_actual| {
4761 "the type of this value must be known in this context".to_string()
4763 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4764 ty = fcx.tcx().types.err;
4766 demand::suptype(fcx, sp, alternative, ty);
4774 // Resolves `typ` by a single level if `typ` is a type variable. If no
4775 // resolution is possible, then an error is reported.
4776 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4781 structurally_resolve_type_or_else(fcx, sp, ty, || {
4786 // Returns true if b contains a break that can exit from b
4787 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
4788 // First: is there an unlabeled break immediately
4790 (loop_query(&*b, |e| {
4792 ast::ExprBreak(None) => true,
4796 // Second: is there a labeled break with label
4797 // <id> nested anywhere inside the loop?
4798 (block_query(b, |e| {
4799 if let ast::ExprBreak(Some(_)) = e.node {
4800 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4807 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4809 tps: &OwnedSlice<ast::TyParam>,
4811 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4814 // make a vector of booleans initially false, set to true when used
4815 if tps.is_empty() { return; }
4816 let mut tps_used = vec![false; tps.len()];
4818 for leaf_ty in ty.walk() {
4819 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4820 debug!("Found use of ty param num {}", idx);
4821 tps_used[idx as usize] = true;
4825 for (i, b) in tps_used.iter().enumerate() {
4827 span_err!(ccx.tcx.sess, span, E0091,
4828 "type parameter `{}` is unused",
4829 token::get_ident(tps[i].ident));
4834 /// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
4835 /// and in libcore/intrinsics.rs
4836 pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
4837 fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
4838 let name = token::intern(&format!("P{}", n));
4839 ccx.tcx.mk_param(subst::FnSpace, n, name)
4843 let name = token::get_ident(it.ident);
4844 let (n_tps, inputs, output) = if name.starts_with("atomic_") {
4845 let split : Vec<&str> = name.split('_').collect();
4846 assert!(split.len() >= 2, "Atomic intrinsic not correct format");
4848 //We only care about the operation here
4849 let (n_tps, inputs, output) = match split[1] {
4850 "cxchg" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)),
4854 "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))),
4856 "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4859 "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" |
4860 "min" | "umax" | "umin" => {
4861 (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4864 "fence" | "singlethreadfence" => {
4865 (0, Vec::new(), tcx.mk_nil())
4868 span_err!(tcx.sess, it.span, E0092,
4869 "unrecognized atomic operation function: `{}`", op);
4873 (n_tps, inputs, ty::FnConverging(output))
4874 } else if &name[..] == "abort" || &name[..] == "unreachable" {
4875 (0, Vec::new(), ty::FnDiverging)
4877 let (n_tps, inputs, output) = match &name[..] {
4878 "breakpoint" => (0, Vec::new(), tcx.mk_nil()),
4880 "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize),
4881 "size_of_val" | "min_align_of_val" => {
4883 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
4886 ], ccx.tcx.types.usize)
4888 "init" | "init_dropped" => (1, Vec::new(), param(ccx, 0)),
4889 "uninit" => (1, Vec::new(), param(ccx, 0)),
4890 "forget" => (1, vec!( param(ccx, 0) ), tcx.mk_nil()),
4891 "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)),
4892 "move_val_init" => {
4895 tcx.mk_mut_ptr(param(ccx, 0)),
4900 "drop_in_place" => {
4901 (1, vec![tcx.mk_mut_ptr(param(ccx, 0))], tcx.mk_nil())
4903 "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool),
4905 "type_name" => (1, Vec::new(), tcx.mk_static_str()),
4906 "type_id" => (1, Vec::new(), ccx.tcx.types.u64),
4907 "offset" | "arith_offset" => {
4910 tcx.mk_ptr(ty::TypeAndMut {
4912 mutbl: ast::MutImmutable
4916 tcx.mk_ptr(ty::TypeAndMut {
4918 mutbl: ast::MutImmutable
4921 "copy" | "copy_nonoverlapping" => {
4924 tcx.mk_ptr(ty::TypeAndMut {
4926 mutbl: ast::MutImmutable
4928 tcx.mk_ptr(ty::TypeAndMut {
4930 mutbl: ast::MutMutable
4936 "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
4939 tcx.mk_ptr(ty::TypeAndMut {
4941 mutbl: ast::MutMutable
4943 tcx.mk_ptr(ty::TypeAndMut {
4945 mutbl: ast::MutImmutable
4951 "write_bytes" | "volatile_set_memory" => {
4954 tcx.mk_ptr(ty::TypeAndMut {
4956 mutbl: ast::MutMutable
4963 "sqrtf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4964 "sqrtf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4967 vec!( tcx.types.f32, tcx.types.i32 ),
4972 vec!( tcx.types.f64, tcx.types.i32 ),
4975 "sinf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4976 "sinf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4977 "cosf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4978 "cosf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4981 vec!( tcx.types.f32, tcx.types.f32 ),
4986 vec!( tcx.types.f64, tcx.types.f64 ),
4989 "expf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4990 "expf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4991 "exp2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4992 "exp2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4993 "logf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4994 "logf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4995 "log10f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4996 "log10f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4997 "log2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4998 "log2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5001 vec!( tcx.types.f32, tcx.types.f32, tcx.types.f32 ),
5006 vec!( tcx.types.f64, tcx.types.f64, tcx.types.f64 ),
5009 "fabsf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5010 "fabsf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5011 "copysignf32" => (0, vec!( tcx.types.f32, tcx.types.f32 ), tcx.types.f32),
5012 "copysignf64" => (0, vec!( tcx.types.f64, tcx.types.f64 ), tcx.types.f64),
5013 "floorf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5014 "floorf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5015 "ceilf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5016 "ceilf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5017 "truncf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5018 "truncf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5019 "rintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5020 "rintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5021 "nearbyintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5022 "nearbyintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5023 "roundf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5024 "roundf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5025 "ctpop8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5026 "ctpop16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5027 "ctpop32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5028 "ctpop64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5029 "ctlz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5030 "ctlz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5031 "ctlz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5032 "ctlz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5033 "cttz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5034 "cttz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5035 "cttz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5036 "cttz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5037 "bswap16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5038 "bswap32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5039 "bswap64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5042 (1, vec!( tcx.mk_imm_ptr(param(ccx, 0)) ), param(ccx, 0)),
5044 (1, vec!( tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ), tcx.mk_nil()),
5046 "i8_add_with_overflow" | "i8_sub_with_overflow" | "i8_mul_with_overflow" =>
5047 (0, vec!(tcx.types.i8, tcx.types.i8),
5048 tcx.mk_tup(vec!(tcx.types.i8, tcx.types.bool))),
5050 "i16_add_with_overflow" | "i16_sub_with_overflow" | "i16_mul_with_overflow" =>
5051 (0, vec!(tcx.types.i16, tcx.types.i16),
5052 tcx.mk_tup(vec!(tcx.types.i16, tcx.types.bool))),
5054 "i32_add_with_overflow" | "i32_sub_with_overflow" | "i32_mul_with_overflow" =>
5055 (0, vec!(tcx.types.i32, tcx.types.i32),
5056 tcx.mk_tup(vec!(tcx.types.i32, tcx.types.bool))),
5058 "i64_add_with_overflow" | "i64_sub_with_overflow" | "i64_mul_with_overflow" =>
5059 (0, vec!(tcx.types.i64, tcx.types.i64),
5060 tcx.mk_tup(vec!(tcx.types.i64, tcx.types.bool))),
5062 "u8_add_with_overflow" | "u8_sub_with_overflow" | "u8_mul_with_overflow" =>
5063 (0, vec!(tcx.types.u8, tcx.types.u8),
5064 tcx.mk_tup(vec!(tcx.types.u8, tcx.types.bool))),
5066 "u16_add_with_overflow" | "u16_sub_with_overflow" | "u16_mul_with_overflow" =>
5067 (0, vec!(tcx.types.u16, tcx.types.u16),
5068 tcx.mk_tup(vec!(tcx.types.u16, tcx.types.bool))),
5070 "u32_add_with_overflow" | "u32_sub_with_overflow" | "u32_mul_with_overflow"=>
5071 (0, vec!(tcx.types.u32, tcx.types.u32),
5072 tcx.mk_tup(vec!(tcx.types.u32, tcx.types.bool))),
5074 "u64_add_with_overflow" | "u64_sub_with_overflow" | "u64_mul_with_overflow" =>
5075 (0, vec!(tcx.types.u64, tcx.types.u64),
5076 tcx.mk_tup(vec!(tcx.types.u64, tcx.types.bool))),
5078 "unchecked_udiv" | "unchecked_sdiv" | "unchecked_urem" | "unchecked_srem" =>
5079 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5081 "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
5082 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5084 "return_address" => (0, vec![], tcx.mk_imm_ptr(tcx.types.u8)),
5086 "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()),
5088 "discriminant_value" => (1, vec![
5089 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
5091 param(ccx, 0))], tcx.types.u64),
5094 let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
5095 let fn_ty = ty::BareFnTy {
5096 unsafety: ast::Unsafety::Normal,
5098 sig: ty::Binder(FnSig {
5099 inputs: vec![mut_u8],
5100 output: ty::FnOutput::FnConverging(tcx.mk_nil()),
5104 let fn_ty = tcx.mk_bare_fn(fn_ty);
5105 (0, vec![tcx.mk_fn(None, fn_ty), mut_u8], mut_u8)
5109 span_err!(tcx.sess, it.span, E0093,
5110 "unrecognized intrinsic function: `{}`", *other);
5114 (n_tps, inputs, ty::FnConverging(output))
5116 let fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy {
5117 unsafety: ast::Unsafety::Unsafe,
5118 abi: abi::RustIntrinsic,
5119 sig: ty::Binder(FnSig {
5125 let i_ty = ccx.tcx.lookup_item_type(local_def(it.id));
5126 let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
5127 if i_n_tps != n_tps {
5128 span_err!(tcx.sess, it.span, E0094,
5129 "intrinsic has wrong number of type \
5130 parameters: found {}, expected {}",
5133 require_same_types(tcx,
5140 format!("intrinsic has wrong type: expected `{}`",