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 rscope::{ElisionFailureInfo, RegionScope};
101 use session::Session;
102 use {CrateCtxt, lookup_full_def, require_same_types};
105 use util::common::{block_query, ErrorReported, indenter, loop_query};
106 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
107 use util::lev_distance::lev_distance;
109 use std::cell::{Cell, Ref, RefCell};
110 use std::mem::replace;
112 use syntax::{self, abi, attr};
113 use syntax::attr::AttrMetaMethods;
114 use syntax::ast::{self, DefId, Visibility};
115 use syntax::ast_util::{self, local_def};
116 use syntax::codemap::{self, Span};
117 use syntax::feature_gate;
118 use syntax::owned_slice::OwnedSlice;
119 use syntax::parse::token;
120 use syntax::print::pprust;
122 use syntax::visit::{self, Visitor};
140 /// closures defined within the function. For example:
143 /// bar(move|| { ... })
146 /// Here, the function `foo()` and the closure passed to
147 /// `bar()` will each have their own `FnCtxt`, but they will
148 /// share the inherited fields.
149 pub struct Inherited<'a, 'tcx: 'a> {
150 infcx: infer::InferCtxt<'a, 'tcx>,
151 locals: RefCell<NodeMap<Ty<'tcx>>>,
153 tables: &'a RefCell<ty::Tables<'tcx>>,
155 // A mapping from each fn's id to its signature, with all bound
156 // regions replaced with free ones. Unlike the other tables, this
157 // one is never copied into the tcx: it is only used by regionck.
158 fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
160 // When we process a call like `c()` where `c` is a closure type,
161 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
162 // `FnOnce` closure. In that case, we defer full resolution of the
163 // call until upvar inference can kick in and make the
164 // decision. We keep these deferred resolutions grouped by the
165 // def-id of the closure, so that once we decide, we can easily go
166 // back and process them.
167 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
169 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
172 trait DeferredCallResolution<'tcx> {
173 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
176 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
178 /// When type-checking an expression, we propagate downward
179 /// whatever type hint we are able in the form of an `Expectation`.
180 #[derive(Copy, Clone, Debug)]
181 pub enum Expectation<'tcx> {
182 /// We know nothing about what type this expression should have.
185 /// This expression should have the type given (or some subtype)
186 ExpectHasType(Ty<'tcx>),
188 /// This expression will be cast to the `Ty`
189 ExpectCastableToType(Ty<'tcx>),
191 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
192 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
193 ExpectRvalueLikeUnsized(Ty<'tcx>),
196 impl<'tcx> Expectation<'tcx> {
197 // Disregard "castable to" expectations because they
198 // can lead us astray. Consider for example `if cond
199 // {22} else {c} as u8` -- if we propagate the
200 // "castable to u8" constraint to 22, it will pick the
201 // type 22u8, which is overly constrained (c might not
202 // be a u8). In effect, the problem is that the
203 // "castable to" expectation is not the tightest thing
204 // we can say, so we want to drop it in this case.
205 // The tightest thing we can say is "must unify with
206 // else branch". Note that in the case of a "has type"
207 // constraint, this limitation does not hold.
209 // If the expected type is just a type variable, then don't use
210 // an expected type. Otherwise, we might write parts of the type
211 // when checking the 'then' block which are incompatible with the
213 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
215 ExpectHasType(ety) => {
216 let ety = fcx.infcx().shallow_resolve(ety);
217 if !ety.is_ty_var() {
223 ExpectRvalueLikeUnsized(ety) => {
224 ExpectRvalueLikeUnsized(ety)
231 #[derive(Copy, Clone)]
232 pub struct UnsafetyState {
233 pub def: ast::NodeId,
234 pub unsafety: ast::Unsafety,
239 pub fn function(unsafety: ast::Unsafety, def: ast::NodeId) -> UnsafetyState {
240 UnsafetyState { def: def, unsafety: unsafety, from_fn: true }
243 pub fn recurse(&mut self, blk: &ast::Block) -> UnsafetyState {
244 match self.unsafety {
245 // If this unsafe, then if the outer function was already marked as
246 // unsafe we shouldn't attribute the unsafe'ness to the block. This
247 // way the block can be warned about instead of ignoring this
248 // extraneous block (functions are never warned about).
249 ast::Unsafety::Unsafe if self.from_fn => *self,
252 let (unsafety, def) = match blk.rules {
253 ast::UnsafeBlock(..) => (ast::Unsafety::Unsafe, blk.id),
254 ast::DefaultBlock => (unsafety, self.def),
256 UnsafetyState{ def: def,
265 pub struct FnCtxt<'a, 'tcx: 'a> {
266 body_id: ast::NodeId,
268 // This flag is set to true if, during the writeback phase, we encounter
269 // a type error in this function.
270 writeback_errors: Cell<bool>,
272 // Number of errors that had been reported when we started
273 // checking this function. On exit, if we find that *more* errors
274 // have been reported, we will skip regionck and other work that
275 // expects the types within the function to be consistent.
276 err_count_on_creation: usize,
278 ret_ty: ty::FnOutput<'tcx>,
280 ps: RefCell<UnsafetyState>,
282 inh: &'a Inherited<'a, 'tcx>,
284 ccx: &'a CrateCtxt<'a, 'tcx>,
287 impl<'a, 'tcx> Inherited<'a, 'tcx> {
288 fn new(tcx: &'a ty::ctxt<'tcx>,
289 tables: &'a RefCell<ty::Tables<'tcx>>,
290 param_env: ty::ParameterEnvironment<'a, 'tcx>)
291 -> Inherited<'a, 'tcx> {
294 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
295 locals: RefCell::new(NodeMap()),
297 fn_sig_map: RefCell::new(NodeMap()),
298 deferred_call_resolutions: RefCell::new(DefIdMap()),
299 deferred_cast_checks: RefCell::new(Vec::new()),
303 fn normalize_associated_types_in<T>(&self,
305 body_id: ast::NodeId,
308 where T : TypeFoldable<'tcx> + HasTypeFlags
310 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
311 assoc::normalize_associated_types_in(&self.infcx,
320 // Used by check_const and check_enum_variants
321 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
322 inh: &'a Inherited<'a, 'tcx>,
323 rty: ty::FnOutput<'tcx>,
324 body_id: ast::NodeId)
325 -> FnCtxt<'a, 'tcx> {
328 writeback_errors: Cell::new(false),
329 err_count_on_creation: ccx.tcx.sess.err_count(),
331 ps: RefCell::new(UnsafetyState::function(ast::Unsafety::Normal, 0)),
337 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
338 tables: &'a RefCell<ty::Tables<'tcx>>)
339 -> Inherited<'a, 'tcx> {
340 // It's kind of a kludge to manufacture a fake function context
341 // and statement context, but we might as well do write the code only once
342 let param_env = ccx.tcx.empty_parameter_environment();
343 Inherited::new(ccx.tcx, &tables, param_env)
346 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
347 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
349 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
350 fn visit_item(&mut self, i: &'tcx ast::Item) {
351 check_item_type(self.ccx, i);
352 visit::walk_item(self, i);
355 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
357 ast::TyFixedLengthVec(_, ref expr) => {
358 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
363 visit::walk_ty(self, t);
367 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
368 fn visit_item(&mut self, i: &'tcx ast::Item) {
369 check_item_body(self.ccx, i);
370 visit::walk_item(self, i);
374 pub fn check_item_types(ccx: &CrateCtxt) {
375 let krate = ccx.tcx.map.krate();
376 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
377 visit::walk_crate(&mut visit, krate);
379 // If types are not well-formed, it leads to all manner of errors
380 // downstream, so stop reporting errors at this point.
381 ccx.tcx.sess.abort_if_errors();
383 let mut visit = CheckItemTypesVisitor { ccx: ccx };
384 visit::walk_crate(&mut visit, krate);
386 ccx.tcx.sess.abort_if_errors();
388 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
389 visit::walk_crate(&mut visit, krate);
391 ccx.tcx.sess.abort_if_errors();
393 for drop_method_did in ccx.tcx.destructors.borrow().iter() {
394 if drop_method_did.krate == ast::LOCAL_CRATE {
395 let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
396 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
399 assert!(ccx.tcx.sess.has_errors());
405 ccx.tcx.sess.abort_if_errors();
408 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
409 decl: &'tcx ast::FnDecl,
410 body: &'tcx ast::Block,
414 param_env: ty::ParameterEnvironment<'a, 'tcx>)
417 ty::TyBareFn(_, ref fn_ty) => {
418 let tables = RefCell::new(ty::Tables::empty());
419 let inh = Inherited::new(ccx.tcx, &tables, param_env);
421 // Compute the fty from point of view of inside fn.
423 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
425 ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
428 inh.normalize_associated_types_in(body.span,
432 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
433 decl, fn_id, body, &inh);
435 fcx.select_all_obligations_and_apply_defaults();
436 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
437 fcx.select_all_obligations_or_error();
440 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
442 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
443 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
445 _ => ccx.tcx.sess.impossible_case(body.span,
446 "check_bare_fn: function type expected")
450 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
451 fcx: &'a FnCtxt<'a, 'tcx>
454 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
455 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
458 // infer the variable's type
459 let var_ty = self.fcx.infcx().next_ty_var();
460 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
464 // take type that the user specified
465 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
472 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
473 // Add explicitly-declared locals.
474 fn visit_local(&mut self, local: &'tcx ast::Local) {
475 let o_ty = match local.ty {
476 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
479 self.assign(local.span, local.id, o_ty);
480 debug!("Local variable {:?} is assigned type {}",
482 self.fcx.infcx().ty_to_string(
483 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
484 visit::walk_local(self, local);
487 // Add pattern bindings.
488 fn visit_pat(&mut self, p: &'tcx ast::Pat) {
489 if let ast::PatIdent(_, ref path1, _) = p.node {
490 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) {
491 let var_ty = self.assign(p.span, p.id, None);
493 self.fcx.require_type_is_sized(var_ty, p.span,
494 traits::VariableType(p.id));
496 debug!("Pattern binding {} is assigned to {} with type {:?}",
497 token::get_ident(path1.node),
498 self.fcx.infcx().ty_to_string(
499 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
503 visit::walk_pat(self, p);
506 fn visit_block(&mut self, b: &'tcx ast::Block) {
507 // non-obvious: the `blk` variable maps to region lb, so
508 // we have to keep this up-to-date. This
509 // is... unfortunate. It'd be nice to not need this.
510 visit::walk_block(self, b);
513 // Since an expr occurs as part of the type fixed size arrays we
514 // need to record the type for that node
515 fn visit_ty(&mut self, t: &'tcx ast::Ty) {
517 ast::TyFixedLengthVec(ref ty, ref count_expr) => {
518 self.visit_ty(&**ty);
519 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
521 _ => visit::walk_ty(self, t)
525 // Don't descend into fns and items
526 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx ast::FnDecl,
527 _: &'tcx ast::Block, _: Span, _: ast::NodeId) { }
528 fn visit_item(&mut self, _: &ast::Item) { }
532 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
533 /// body and returns the function context used for that purpose, since in the case of a fn item
534 /// there is still a bit more to do.
537 /// * inherited: other fields inherited from the enclosing fn (if any)
538 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
539 unsafety: ast::Unsafety,
540 unsafety_id: ast::NodeId,
541 fn_sig: &ty::FnSig<'tcx>,
542 decl: &'tcx ast::FnDecl,
544 body: &'tcx ast::Block,
545 inherited: &'a Inherited<'a, 'tcx>)
549 let err_count_on_creation = tcx.sess.err_count();
551 let arg_tys = &fn_sig.inputs;
552 let ret_ty = fn_sig.output;
554 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
559 // Create the function context. This is either derived from scratch or,
560 // in the case of function expressions, based on the outer context.
563 writeback_errors: Cell::new(false),
564 err_count_on_creation: err_count_on_creation,
566 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
571 // Remember return type so that regionck can access it later.
572 let mut fn_sig_tys: Vec<Ty> =
577 if let ty::FnConverging(ret_ty) = ret_ty {
578 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
579 fn_sig_tys.push(ret_ty);
582 debug!("fn-sig-map: fn_id={} fn_sig_tys={:?}",
586 inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys);
589 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
591 // Add formal parameters.
592 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
593 // Create type variables for each argument.
594 pat_util::pat_bindings(
597 |_bm, pat_id, sp, _path| {
598 let var_ty = visit.assign(sp, pat_id, None);
599 fcx.require_type_is_sized(var_ty, sp,
600 traits::VariableType(pat_id));
603 // Check the pattern.
606 map: pat_id_map(&tcx.def_map, &*input.pat),
608 _match::check_pat(&pcx, &*input.pat, *arg_ty);
611 visit.visit_block(body);
614 check_block_with_expected(&fcx, body, match ret_ty {
615 ty::FnConverging(result_type) => ExpectHasType(result_type),
616 ty::FnDiverging => NoExpectation
619 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
620 fcx.write_ty(input.id, arg);
626 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
629 check_representable(tcx, span, id, "struct");
630 check_instantiable(tcx, span, id);
632 if tcx.lookup_simd(local_def(id)) {
633 check_simd(tcx, span, id);
637 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
638 debug!("check_item_type(it.id={}, it.ident={})",
640 ccx.tcx.item_path_str(local_def(it.id)));
641 let _indenter = indenter();
643 // Consts can play a role in type-checking, so they are included here.
644 ast::ItemStatic(_, _, ref e) |
645 ast::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
646 ast::ItemEnum(ref enum_definition, _) => {
647 check_enum_variants(ccx,
649 &enum_definition.variants,
652 ast::ItemFn(..) => {} // entirely within check_item_body
653 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
654 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
655 match ccx.tcx.impl_trait_ref(local_def(it.id)) {
656 Some(impl_trait_ref) => {
657 check_impl_items_against_trait(ccx,
665 ast::ItemTrait(_, ref generics, _, _) => {
666 check_trait_on_unimplemented(ccx, generics, it);
668 ast::ItemStruct(..) => {
669 check_struct(ccx, it.id, it.span);
671 ast::ItemTy(ref t, ref generics) => {
672 let pty_ty = ccx.tcx.node_id_to_type(it.id);
673 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
675 ast::ItemForeignMod(ref m) => {
676 if m.abi == abi::RustIntrinsic {
677 for item in &m.items {
678 check_intrinsic_type(ccx, &**item);
681 for item in &m.items {
682 let pty = ccx.tcx.lookup_item_type(local_def(item.id));
683 if !pty.generics.types.is_empty() {
684 span_err!(ccx.tcx.sess, item.span, E0044,
685 "foreign items may not have type parameters");
688 if let ast::ForeignItemFn(ref fn_decl, _) = item.node {
689 if fn_decl.variadic && m.abi != abi::C {
690 span_err!(ccx.tcx.sess, item.span, E0045,
691 "variadic function must have C calling convention");
697 _ => {/* nothing to do */ }
701 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
702 debug!("check_item_body(it.id={}, it.ident={})",
704 ccx.tcx.item_path_str(local_def(it.id)));
705 let _indenter = indenter();
707 ast::ItemFn(ref decl, _, _, _, _, ref body) => {
708 let fn_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
709 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
710 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
712 ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
713 debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
715 let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
717 for impl_item in impl_items {
718 match impl_item.node {
719 ast::ConstImplItem(_, ref expr) => {
720 check_const(ccx, impl_item.span, &*expr, impl_item.id)
722 ast::MethodImplItem(ref sig, ref body) => {
723 check_method_body(ccx, &impl_pty.generics, sig, body,
724 impl_item.id, impl_item.span);
726 ast::TypeImplItem(_) |
727 ast::MacImplItem(_) => {
728 // Nothing to do here.
733 ast::ItemTrait(_, _, _, ref trait_items) => {
734 let trait_def = ccx.tcx.lookup_trait_def(local_def(it.id));
735 for trait_item in trait_items {
736 match trait_item.node {
737 ast::ConstTraitItem(_, Some(ref expr)) => {
738 check_const(ccx, trait_item.span, &*expr, trait_item.id)
740 ast::MethodTraitItem(ref sig, Some(ref body)) => {
741 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
743 check_method_body(ccx, &trait_def.generics, sig, body,
744 trait_item.id, trait_item.span);
746 ast::MethodTraitItem(ref sig, None) => {
747 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
749 ast::ConstTraitItem(_, None) |
750 ast::TypeTraitItem(..) => {
756 _ => {/* nothing to do */ }
760 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
762 constness: ast::Constness)
765 ast::Constness::NotConst => {
768 ast::Constness::Const => {
769 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
774 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
775 generics: &ast::Generics,
777 if let Some(ref attr) = item.attrs.iter().find(|a| {
778 a.check_name("rustc_on_unimplemented")
780 if let Some(ref istring) = attr.value_str() {
781 let parser = Parser::new(&istring);
782 let types = &*generics.ty_params;
783 for token in parser {
785 Piece::String(_) => (), // Normal string, no need to check it
786 Piece::NextArgument(a) => match a.position {
787 // `{Self}` is allowed
788 Position::ArgumentNamed(s) if s == "Self" => (),
789 // So is `{A}` if A is a type parameter
790 Position::ArgumentNamed(s) => match types.iter().find(|t| {
791 t.ident.as_str() == s
795 span_err!(ccx.tcx.sess, attr.span, E0230,
796 "there is no type parameter \
798 s, item.ident.as_str());
801 // `{:1}` and `{}` are not to be used
802 Position::ArgumentIs(_) | Position::ArgumentNext => {
803 span_err!(ccx.tcx.sess, attr.span, E0231,
804 "only named substitution \
805 parameters are allowed");
811 span_err!(ccx.tcx.sess, attr.span, E0232,
812 "this attribute must have a value, \
813 eg `#[rustc_on_unimplemented = \"foo\"]`")
818 /// Type checks a method body.
822 /// * `item_generics`: generics defined on the impl/trait that contains
824 /// * `self_bound`: bound for the `Self` type parameter, if any
825 /// * `method`: the method definition
826 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
827 item_generics: &ty::Generics<'tcx>,
828 sig: &'tcx ast::MethodSig,
829 body: &'tcx ast::Block,
830 id: ast::NodeId, span: Span) {
831 debug!("check_method_body(item_generics={:?}, id={})",
833 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
835 let fty = ccx.tcx.node_id_to_type(id);
836 debug!("check_method_body: fty={:?}", fty);
838 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
841 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
843 impl_trait_ref: &ty::TraitRef<'tcx>,
844 impl_items: &[P<ast::ImplItem>]) {
845 // Locate trait methods
847 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
848 let mut overridden_associated_type = None;
850 // Check existing impl methods to see if they are both present in trait
851 // and compatible with trait signature
852 for impl_item in impl_items {
853 let ty_impl_item = ccx.tcx.impl_or_trait_item(local_def(impl_item.id));
854 let ty_trait_item = trait_items.iter()
855 .find(|ac| ac.name() == ty_impl_item.name())
857 // This is checked by resolve
858 tcx.sess.span_bug(impl_item.span,
859 &format!("impl-item `{}` is not a member of `{:?}`",
860 token::get_name(ty_impl_item.name()),
863 match impl_item.node {
864 ast::ConstImplItem(..) => {
865 let impl_const = match ty_impl_item {
866 ty::ConstTraitItem(ref cti) => cti,
867 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
870 // Find associated const definition.
871 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
872 compare_const_impl(ccx.tcx,
878 span_err!(tcx.sess, impl_item.span, E0323,
879 "item `{}` is an associated const, \
880 which doesn't match its trait `{:?}`",
881 token::get_name(impl_const.name),
885 ast::MethodImplItem(ref sig, ref body) => {
886 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
888 let impl_method = match ty_impl_item {
889 ty::MethodTraitItem(ref mti) => mti,
890 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
893 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
894 compare_impl_method(ccx.tcx,
901 span_err!(tcx.sess, impl_item.span, E0324,
902 "item `{}` is an associated method, \
903 which doesn't match its trait `{:?}`",
904 token::get_name(impl_method.name),
908 ast::TypeImplItem(_) => {
909 let impl_type = match ty_impl_item {
910 ty::TypeTraitItem(ref tti) => tti,
911 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
914 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
915 if let Some(_) = at.ty {
916 overridden_associated_type = Some(impl_item);
919 span_err!(tcx.sess, impl_item.span, E0325,
920 "item `{}` is an associated type, \
921 which doesn't match its trait `{:?}`",
922 token::get_name(impl_type.name),
926 ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
931 // Check for missing items from trait
932 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
933 let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
934 let mut missing_items = Vec::new();
935 let mut invalidated_items = Vec::new();
936 let associated_type_overridden = overridden_associated_type.is_some();
937 for trait_item in trait_items.iter() {
939 ty::ConstTraitItem(ref associated_const) => {
940 let is_implemented = impl_items.iter().any(|ii| {
942 ast::ConstImplItem(..) => {
943 ii.ident.name == associated_const.name
949 associated_consts.iter().any(|ac| ac.default.is_some() &&
950 ac.name == associated_const.name);
953 missing_items.push(associated_const.name);
954 } else if associated_type_overridden {
955 invalidated_items.push(associated_const.name);
959 ty::MethodTraitItem(ref trait_method) => {
961 impl_items.iter().any(|ii| {
963 ast::MethodImplItem(..) => {
964 ii.ident.name == trait_method.name
970 provided_methods.iter().any(|m| m.name == trait_method.name);
973 missing_items.push(trait_method.name);
974 } else if associated_type_overridden {
975 invalidated_items.push(trait_method.name);
979 ty::TypeTraitItem(ref associated_type) => {
980 let is_implemented = impl_items.iter().any(|ii| {
982 ast::TypeImplItem(_) => {
983 ii.ident.name == associated_type.name
988 let is_provided = associated_type.ty.is_some();
991 missing_items.push(associated_type.name);
992 } else if associated_type_overridden {
993 invalidated_items.push(associated_type.name);
1000 if !missing_items.is_empty() {
1001 span_err!(tcx.sess, impl_span, E0046,
1002 "not all trait items implemented, missing: `{}`",
1003 missing_items.iter()
1004 .map(<ast::Name>::as_str)
1005 .collect::<Vec<_>>().join("`, `"))
1008 if !invalidated_items.is_empty() {
1009 let invalidator = overridden_associated_type.unwrap();
1010 span_err!(tcx.sess, invalidator.span, E0399,
1011 "the following trait items need to be reimplemented \
1012 as `{}` was overridden: `{}`",
1013 invalidator.ident.as_str(),
1014 invalidated_items.iter()
1015 .map(<ast::Name>::as_str)
1016 .collect::<Vec<_>>().join("`, `"))
1020 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1027 let tstr = fcx.infcx().ty_to_string(t_cast);
1028 fcx.type_error_message(span, |actual| {
1029 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1032 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1033 let mtstr = match mt {
1034 ast::MutMutable => "mut ",
1035 ast::MutImmutable => ""
1037 if t_cast.is_trait() {
1038 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1040 fcx.tcx().sess.span_suggestion(t_span,
1041 "try casting to a reference instead:",
1042 format!("&{}{}", mtstr, s));
1045 span_help!(fcx.tcx().sess, t_span,
1046 "did you mean `&{}{}`?", mtstr, tstr),
1049 span_help!(fcx.tcx().sess, span,
1050 "consider using an implicit coercion to `&{}{}` instead",
1055 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1057 fcx.tcx().sess.span_suggestion(t_span,
1058 "try casting to a `Box` instead:",
1059 format!("Box<{}>", s));
1062 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1066 span_help!(fcx.tcx().sess, e_span,
1067 "consider using a box or reference as appropriate");
1070 fcx.write_error(id);
1074 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1075 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1077 fn get_item_type_scheme(&self, _: Span, id: ast::DefId)
1078 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1080 Ok(self.tcx().lookup_item_type(id))
1083 fn get_trait_def(&self, _: Span, id: ast::DefId)
1084 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1086 Ok(self.tcx().lookup_trait_def(id))
1089 fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
1090 // all super predicates are ensured during collect pass
1094 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1095 Some(&self.inh.infcx.parameter_environment.free_substs)
1098 fn get_type_parameter_bounds(&self,
1100 node_id: ast::NodeId)
1101 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1103 let def = self.tcx().type_parameter_def(node_id);
1104 let r = self.inh.infcx.parameter_environment
1107 .filter_map(|predicate| {
1109 ty::Predicate::Trait(ref data) => {
1110 if data.0.self_ty().is_param(def.space, def.index) {
1111 Some(data.to_poly_trait_ref())
1125 fn trait_defines_associated_type_named(&self,
1126 trait_def_id: ast::DefId,
1127 assoc_name: ast::Name)
1130 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1131 trait_def.associated_type_names.contains(&assoc_name)
1134 fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
1135 self.infcx().next_ty_var()
1138 fn projected_ty_from_poly_trait_ref(&self,
1140 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1141 item_name: ast::Name)
1144 let (trait_ref, _) =
1145 self.infcx().replace_late_bound_regions_with_fresh_var(
1147 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1150 self.normalize_associated_type(span, trait_ref, item_name)
1153 fn projected_ty(&self,
1155 trait_ref: ty::TraitRef<'tcx>,
1156 item_name: ast::Name)
1159 self.normalize_associated_type(span, trait_ref, item_name)
1163 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1164 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1166 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1170 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1171 &self.inh.infcx.parameter_environment
1174 pub fn sess(&self) -> &Session {
1178 pub fn err_count_since_creation(&self) -> usize {
1179 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1182 /// Resolves type variables in `ty` if possible. Unlike the infcx
1183 /// version, this version will also select obligations if it seems
1184 /// useful, in an effort to get more type information.
1185 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1186 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1188 // No TyInfer()? Nothing needs doing.
1189 if !ty.has_infer_types() {
1190 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1194 // If `ty` is a type variable, see whether we already know what it is.
1195 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1196 if !ty.has_infer_types() {
1197 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1201 // If not, try resolving any new fcx obligations that have cropped up.
1202 self.select_new_obligations();
1203 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1204 if !ty.has_infer_types() {
1205 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1209 // If not, try resolving *all* pending obligations as much as
1210 // possible. This can help substantially when there are
1211 // indirect dependencies that don't seem worth tracking
1213 self.select_obligations_where_possible();
1214 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1216 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1220 fn record_deferred_call_resolution(&self,
1221 closure_def_id: ast::DefId,
1222 r: DeferredCallResolutionHandler<'tcx>) {
1223 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1224 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1227 fn remove_deferred_call_resolutions(&self,
1228 closure_def_id: ast::DefId)
1229 -> Vec<DeferredCallResolutionHandler<'tcx>>
1231 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1232 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1235 pub fn tag(&self) -> String {
1236 let self_ptr: *const FnCtxt = self;
1237 format!("{:?}", self_ptr)
1240 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1241 match self.inh.locals.borrow().get(&nid) {
1244 self.tcx().sess.span_err(
1246 &format!("no type for local variable {}", nid));
1247 self.tcx().types.err
1252 /// Apply "fallbacks" to some types
1253 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1254 pub fn default_type_parameters(&self) {
1255 use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
1256 for (_, &mut ref ty) in &mut self.inh.tables.borrow_mut().node_types {
1257 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1258 if self.infcx().type_var_diverges(resolved) {
1259 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1261 match self.infcx().type_is_unconstrained_numeric(resolved) {
1262 UnconstrainedInt => {
1263 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1265 UnconstrainedFloat => {
1266 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1275 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1276 debug!("write_ty({}, {:?}) in fcx {}",
1277 node_id, ty, self.tag());
1278 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1281 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1282 if !substs.substs.is_noop() {
1283 debug!("write_substs({}, {:?}) in fcx {}",
1288 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1292 pub fn write_autoderef_adjustment(&self,
1293 node_id: ast::NodeId,
1295 self.write_adjustment(
1297 ty::AdjustDerefRef(ty::AutoDerefRef {
1305 pub fn write_adjustment(&self,
1306 node_id: ast::NodeId,
1307 adj: ty::AutoAdjustment<'tcx>) {
1308 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1310 if adj.is_identity() {
1314 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1317 /// Basically whenever we are converting from a type scheme into
1318 /// the fn body space, we always want to normalize associated
1319 /// types as well. This function combines the two.
1320 fn instantiate_type_scheme<T>(&self,
1322 substs: &Substs<'tcx>,
1325 where T : TypeFoldable<'tcx> + HasTypeFlags
1327 let value = value.subst(self.tcx(), substs);
1328 let result = self.normalize_associated_types_in(span, &value);
1329 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1336 /// As `instantiate_type_scheme`, but for the bounds found in a
1337 /// generic type scheme.
1338 fn instantiate_bounds(&self,
1340 substs: &Substs<'tcx>,
1341 bounds: &ty::GenericPredicates<'tcx>)
1342 -> ty::InstantiatedPredicates<'tcx>
1344 ty::InstantiatedPredicates {
1345 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1350 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1351 where T : TypeFoldable<'tcx> + HasTypeFlags
1353 self.inh.normalize_associated_types_in(span, self.body_id, value)
1356 fn normalize_associated_type(&self,
1358 trait_ref: ty::TraitRef<'tcx>,
1359 item_name: ast::Name)
1362 let cause = traits::ObligationCause::new(span,
1364 traits::ObligationCauseCode::MiscObligation);
1369 .normalize_projection_type(self.infcx(),
1371 trait_ref: trait_ref,
1372 item_name: item_name,
1377 /// Returns the type of `def_id` with all generics replaced by by fresh type/region variables.
1378 /// Also returns the substitution from the type parameters on `def_id` to the fresh variables.
1379 /// Registers any trait obligations specified on `def_id` at the same time.
1381 /// Note that function is only intended to be used with types (notably, not fns). This is
1382 /// because it doesn't do any instantiation of late-bound regions.
1383 pub fn instantiate_type(&self,
1386 -> TypeAndSubsts<'tcx>
1389 self.tcx().lookup_item_type(def_id);
1390 let type_predicates =
1391 self.tcx().lookup_predicates(def_id);
1393 self.infcx().fresh_substs_for_generics(
1395 &type_scheme.generics);
1397 self.instantiate_bounds(span, &substs, &type_predicates);
1398 self.add_obligations_for_parameters(
1399 traits::ObligationCause::new(
1402 traits::ItemObligation(def_id)),
1405 self.instantiate_type_scheme(span, &substs, &type_scheme.ty);
1413 /// Returns the type that this AST path refers to. If the path has no type
1414 /// parameters and the corresponding type has type parameters, fresh type
1415 /// and/or region variables are substituted.
1417 /// This is used when checking the constructor in struct literals.
1418 fn instantiate_struct_literal_ty(&self,
1421 -> TypeAndSubsts<'tcx>
1423 let tcx = self.tcx();
1425 let ty::TypeScheme { generics, ty: decl_ty } =
1426 tcx.lookup_item_type(did);
1428 let substs = astconv::ast_path_substs_for_ty(self, self,
1430 PathParamMode::Optional,
1432 path.segments.last().unwrap());
1434 let ty = self.instantiate_type_scheme(path.span, &substs, &decl_ty);
1436 TypeAndSubsts { substs: substs, ty: ty }
1439 pub fn write_nil(&self, node_id: ast::NodeId) {
1440 self.write_ty(node_id, self.tcx().mk_nil());
1442 pub fn write_error(&self, node_id: ast::NodeId) {
1443 self.write_ty(node_id, self.tcx().types.err);
1446 pub fn require_type_meets(&self,
1449 code: traits::ObligationCauseCode<'tcx>,
1450 bound: ty::BuiltinBound)
1452 self.register_builtin_bound(
1455 traits::ObligationCause::new(span, self.body_id, code));
1458 pub fn require_type_is_sized(&self,
1461 code: traits::ObligationCauseCode<'tcx>)
1463 self.require_type_meets(ty, span, code, ty::BoundSized);
1466 pub fn require_expr_have_sized_type(&self,
1468 code: traits::ObligationCauseCode<'tcx>)
1470 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1473 pub fn type_is_known_to_be_sized(&self,
1478 traits::type_known_to_meet_builtin_bound(self.infcx(),
1484 pub fn register_builtin_bound(&self,
1486 builtin_bound: ty::BuiltinBound,
1487 cause: traits::ObligationCause<'tcx>)
1489 self.inh.infcx.fulfillment_cx.borrow_mut()
1490 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1493 pub fn register_predicate(&self,
1494 obligation: traits::PredicateObligation<'tcx>)
1496 debug!("register_predicate({:?})",
1498 self.inh.infcx.fulfillment_cx
1500 .register_predicate_obligation(self.infcx(), obligation);
1503 pub fn to_ty(&self, ast_t: &ast::Ty) -> Ty<'tcx> {
1504 let t = ast_ty_to_ty(self, self, ast_t);
1506 let mut bounds_checker = wf::BoundsChecker::new(self,
1509 bounds_checker.check_ty(t, ast_t.span);
1514 pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
1515 match self.inh.tables.borrow().node_types.get(&ex.id) {
1518 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1524 /// Apply `adjustment` to the type of `expr`
1525 pub fn adjust_expr_ty(&self,
1527 adjustment: Option<&ty::AutoAdjustment<'tcx>>)
1530 let raw_ty = self.expr_ty(expr);
1531 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1532 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1533 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1534 self.inh.tables.borrow().method_map.get(&method_call)
1535 .map(|method| resolve_ty(method.ty))
1539 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1540 match self.inh.tables.borrow().node_types.get(&id) {
1542 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1544 self.tcx().sess.bug(
1545 &format!("no type for node {}: {} in fcx {}",
1546 id, self.tcx().map.node_to_string(id),
1552 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1553 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1554 // it changes when we upgrade the snapshot compiler
1555 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1556 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1560 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1563 pub fn opt_node_ty_substs<F>(&self,
1566 F: FnOnce(&ty::ItemSubsts<'tcx>),
1568 match self.inh.tables.borrow().item_substs.get(&id) {
1574 pub fn mk_subty(&self,
1575 a_is_expected: bool,
1576 origin: infer::TypeOrigin,
1579 -> Result<(), ty::TypeError<'tcx>> {
1580 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1583 pub fn mk_eqty(&self,
1584 a_is_expected: bool,
1585 origin: infer::TypeOrigin,
1588 -> Result<(), ty::TypeError<'tcx>> {
1589 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1592 pub fn mk_subr(&self,
1593 origin: infer::SubregionOrigin<'tcx>,
1596 infer::mk_subr(self.infcx(), origin, sub, sup)
1599 pub fn type_error_message<M>(&self,
1602 actual_ty: Ty<'tcx>,
1603 err: Option<&ty::TypeError<'tcx>>) where
1604 M: FnOnce(String) -> String,
1606 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1609 pub fn report_mismatched_types(&self,
1613 err: &ty::TypeError<'tcx>) {
1614 self.infcx().report_mismatched_types(sp, e, a, err)
1617 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1618 /// outlive the region `r`.
1619 pub fn register_region_obligation(&self,
1622 cause: traits::ObligationCause<'tcx>)
1624 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1625 fulfillment_cx.register_region_obligation(ty, region, cause);
1628 pub fn add_default_region_param_bounds(&self,
1629 substs: &Substs<'tcx>,
1632 for &ty in &substs.types {
1633 let default_bound = ty::ReScope(CodeExtent::from_node_id(expr.id));
1634 let cause = traits::ObligationCause::new(expr.span, self.body_id,
1635 traits::MiscObligation);
1636 self.register_region_obligation(ty, default_bound, cause);
1640 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1641 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1642 /// trait/region obligations.
1644 /// For example, if there is a function:
1647 /// fn foo<'a,T:'a>(...)
1650 /// and a reference:
1656 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1657 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1658 pub fn add_obligations_for_parameters(&self,
1659 cause: traits::ObligationCause<'tcx>,
1660 predicates: &ty::InstantiatedPredicates<'tcx>)
1662 assert!(!predicates.has_escaping_regions());
1664 debug!("add_obligations_for_parameters(predicates={:?})",
1667 for obligation in traits::predicates_for_generics(cause, predicates) {
1668 self.register_predicate(obligation);
1672 // Only for fields! Returns <none> for methods>
1673 // Indifferent to privacy flags
1674 pub fn lookup_field_ty(&self,
1676 class_id: ast::DefId,
1677 items: &[ty::FieldTy],
1678 fieldname: ast::Name,
1679 substs: &subst::Substs<'tcx>)
1682 let o_field = items.iter().find(|f| f.name == fieldname);
1683 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1684 .map(|t| self.normalize_associated_types_in(span, &t))
1687 pub fn lookup_tup_field_ty(&self,
1689 class_id: ast::DefId,
1690 items: &[ty::FieldTy],
1692 substs: &subst::Substs<'tcx>)
1695 let o_field = if idx < items.len() { Some(&items[idx]) } else { None };
1696 o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
1697 .map(|t| self.normalize_associated_types_in(span, &t))
1700 fn check_casts(&self) {
1701 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1702 for cast in deferred_cast_checks.drain(..) {
1707 fn select_all_obligations_and_apply_defaults(&self) {
1708 debug!("select_all_obligations_and_apply_defaults");
1710 self.select_obligations_where_possible();
1711 self.default_type_parameters();
1712 self.select_obligations_where_possible();
1715 fn select_all_obligations_or_error(&self) {
1716 debug!("select_all_obligations_or_error");
1718 // upvar inference should have ensured that all deferred call
1719 // resolutions are handled by now.
1720 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1722 self.select_all_obligations_and_apply_defaults();
1723 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1724 match fulfillment_cx.select_all_or_error(self.infcx()) {
1726 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1730 /// Select as many obligations as we can at present.
1731 fn select_obligations_where_possible(&self) {
1733 self.inh.infcx.fulfillment_cx
1735 .select_where_possible(self.infcx())
1738 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1742 /// Try to select any fcx obligation that we haven't tried yet, in an effort
1743 /// to improve inference. You could just call
1744 /// `select_obligations_where_possible` except that it leads to repeated
1746 fn select_new_obligations(&self) {
1748 self.inh.infcx.fulfillment_cx
1750 .select_new_obligations(self.infcx())
1753 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1759 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
1760 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1761 Some(self.base_object_lifetime_default(span))
1764 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1765 // RFC #599 specifies that object lifetime defaults take
1766 // precedence over other defaults. But within a fn body we
1767 // don't have a *default* region, rather we use inference to
1768 // find the *correct* region, which is strictly more general
1769 // (and anyway, within a fn body the right region may not even
1770 // be something the user can write explicitly, since it might
1771 // be some expression).
1772 self.infcx().next_region_var(infer::MiscVariable(span))
1775 fn anon_regions(&self, span: Span, count: usize)
1776 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1777 Ok((0..count).map(|_| {
1778 self.infcx().next_region_var(infer::MiscVariable(span))
1783 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1784 pub enum LvaluePreference {
1789 impl LvaluePreference {
1790 pub fn from_mutbl(m: ast::Mutability) -> Self {
1792 ast::MutMutable => PreferMutLvalue,
1793 ast::MutImmutable => NoPreference,
1798 /// Whether `autoderef` requires types to resolve.
1799 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1800 pub enum UnresolvedTypeAction {
1801 /// Produce an error and return `TyError` whenever a type cannot
1802 /// be resolved (i.e. it is `TyInfer`).
1804 /// Go on without emitting any errors, and return the unresolved
1805 /// type. Useful for probing, e.g. in coercions.
1809 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
1810 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
1812 /// Note: this method does not modify the adjustments table. The caller is responsible for
1813 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
1814 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
1817 opt_expr: Option<&ast::Expr>,
1818 unresolved_type_action: UnresolvedTypeAction,
1819 mut lvalue_pref: LvaluePreference,
1821 -> (Ty<'tcx>, usize, Option<T>)
1822 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
1824 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
1829 let mut t = base_ty;
1830 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
1831 let resolved_t = match unresolved_type_action {
1832 UnresolvedTypeAction::Error => {
1833 structurally_resolved_type(fcx, sp, t)
1835 UnresolvedTypeAction::Ignore => {
1836 // We can continue even when the type cannot be resolved
1837 // (i.e. it is an inference variable) because `Ty::builtin_deref`
1838 // and `try_overloaded_deref` both simply return `None`
1839 // in such a case without producing spurious errors.
1840 fcx.resolve_type_vars_if_possible(t)
1843 if resolved_t.references_error() {
1844 return (resolved_t, autoderefs, None);
1847 match should_stop(resolved_t, autoderefs) {
1848 Some(x) => return (resolved_t, autoderefs, Some(x)),
1852 // Otherwise, deref if type is derefable:
1853 let mt = match resolved_t.builtin_deref(false) {
1854 Some(mt) => Some(mt),
1857 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
1859 // Super subtle: it might seem as though we should
1860 // pass `opt_expr` to `try_overloaded_deref`, so that
1861 // the (implicit) autoref of using an overloaded deref
1862 // would get added to the adjustment table. However we
1863 // do not do that, because it's kind of a
1864 // "meta-adjustment" -- instead, we just leave it
1865 // unrecorded and know that there "will be" an
1866 // autoref. regionck and other bits of the code base,
1867 // when they encounter an overloaded autoderef, have
1868 // to do some reconstructive surgery. This is a pretty
1869 // complex mess that is begging for a proper MIR.
1870 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
1876 if mt.mutbl == ast::MutImmutable {
1877 lvalue_pref = NoPreference;
1880 None => return (resolved_t, autoderefs, None)
1884 // We've reached the recursion limit, error gracefully.
1885 span_err!(fcx.tcx().sess, sp, E0055,
1886 "reached the recursion limit while auto-dereferencing {:?}",
1888 (fcx.tcx().types.err, 0, None)
1891 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1893 method_call: Option<MethodCall>,
1894 base_expr: Option<&ast::Expr>,
1896 lvalue_pref: LvaluePreference)
1897 -> Option<ty::TypeAndMut<'tcx>>
1899 // Try DerefMut first, if preferred.
1900 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
1901 (PreferMutLvalue, Some(trait_did)) => {
1902 method::lookup_in_trait(fcx, span, base_expr,
1903 token::intern("deref_mut"), trait_did,
1909 // Otherwise, fall back to Deref.
1910 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
1911 (None, Some(trait_did)) => {
1912 method::lookup_in_trait(fcx, span, base_expr,
1913 token::intern("deref"), trait_did,
1916 (method, _) => method
1919 make_overloaded_lvalue_return_type(fcx, method_call, method)
1922 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
1923 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
1924 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
1925 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1926 method_call: Option<MethodCall>,
1927 method: Option<MethodCallee<'tcx>>)
1928 -> Option<ty::TypeAndMut<'tcx>>
1932 // extract method method return type, which will be &T;
1933 // all LB regions should have been instantiated during method lookup
1934 let ret_ty = method.ty.fn_ret();
1935 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
1937 if let Some(method_call) = method_call {
1938 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
1941 // method returns &T, but the type as visible to user is T, so deref
1942 ret_ty.builtin_deref(true)
1948 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1950 base_expr: &'tcx ast::Expr,
1953 lvalue_pref: LvaluePreference)
1954 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
1956 // FIXME(#18741) -- this is almost but not quite the same as the
1957 // autoderef that normal method probing does. They could likely be
1960 let (ty, autoderefs, final_mt) = autoderef(fcx,
1964 UnresolvedTypeAction::Error,
1967 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
1968 adj_ty, idx, false, lvalue_pref, idx_ty)
1971 if final_mt.is_some() {
1975 // After we have fully autoderef'd, if the resulting type is [T; n], then
1976 // do a final unsized coercion to yield [T].
1977 if let ty::TyArray(element_ty, _) = ty.sty {
1978 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
1979 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
1980 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
1986 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
1987 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
1988 /// This loop implements one step in that search; the autoderef loop is implemented by
1989 /// `lookup_indexing`.
1990 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1991 method_call: MethodCall,
1993 base_expr: &'tcx ast::Expr,
1994 adjusted_ty: Ty<'tcx>,
1997 lvalue_pref: LvaluePreference,
1999 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2001 let tcx = fcx.tcx();
2002 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2003 autoderefs={}, unsize={}, index_ty={:?})",
2011 let input_ty = fcx.infcx().next_ty_var();
2013 // First, try built-in indexing.
2014 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2015 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2016 debug!("try_index_step: success, using built-in indexing");
2017 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2019 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2020 return Some((tcx.types.usize, ty));
2025 // Try `IndexMut` first, if preferred.
2026 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2027 (PreferMutLvalue, Some(trait_did)) => {
2028 method::lookup_in_trait_adjusted(fcx,
2031 token::intern("index_mut"),
2036 Some(vec![input_ty]))
2041 // Otherwise, fall back to `Index`.
2042 let method = match (method, tcx.lang_items.index_trait()) {
2043 (None, Some(trait_did)) => {
2044 method::lookup_in_trait_adjusted(fcx,
2047 token::intern("index"),
2052 Some(vec![input_ty]))
2054 (method, _) => method,
2057 // If some lookup succeeds, write callee into table and extract index/element
2058 // type from the method signature.
2059 // If some lookup succeeded, install method in table
2060 method.and_then(|method| {
2061 debug!("try_index_step: success, using overloaded indexing");
2062 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2063 map(|ret| (input_ty, ret.ty))
2067 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2069 method_fn_ty: Ty<'tcx>,
2070 callee_expr: &'tcx ast::Expr,
2071 args_no_rcvr: &'tcx [P<ast::Expr>],
2072 tuple_arguments: TupleArgumentsFlag,
2073 expected: Expectation<'tcx>)
2074 -> ty::FnOutput<'tcx> {
2075 if method_fn_ty.references_error() {
2076 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2078 let err_inputs = match tuple_arguments {
2079 DontTupleArguments => err_inputs,
2080 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2083 check_argument_types(fcx,
2090 ty::FnConverging(fcx.tcx().types.err)
2092 match method_fn_ty.sty {
2093 ty::TyBareFn(_, ref fty) => {
2094 // HACK(eddyb) ignore self in the definition (see above).
2095 let expected_arg_tys = expected_types_for_fn_args(fcx,
2099 &fty.sig.0.inputs[1..]);
2100 check_argument_types(fcx,
2102 &fty.sig.0.inputs[1..],
2103 &expected_arg_tys[..],
2110 fcx.tcx().sess.span_bug(callee_expr.span,
2111 "method without bare fn type");
2117 /// Generic function that factors out common logic from function calls, method calls and overloaded
2119 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2121 fn_inputs: &[Ty<'tcx>],
2122 expected_arg_tys: &[Ty<'tcx>],
2123 args: &'tcx [P<ast::Expr>],
2125 tuple_arguments: TupleArgumentsFlag) {
2126 let tcx = fcx.ccx.tcx;
2128 // Grab the argument types, supplying fresh type variables
2129 // if the wrong number of arguments were supplied
2130 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2136 let mut expected_arg_tys = expected_arg_tys;
2137 let expected_arg_count = fn_inputs.len();
2138 let formal_tys = if tuple_arguments == TupleArguments {
2139 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2140 match tuple_type.sty {
2141 ty::TyTuple(ref arg_types) => {
2142 if arg_types.len() != args.len() {
2143 span_err!(tcx.sess, sp, E0057,
2144 "this function takes {} parameter{} but {} parameter{} supplied",
2146 if arg_types.len() == 1 {""} else {"s"},
2148 if args.len() == 1 {" was"} else {"s were"});
2149 expected_arg_tys = &[];
2150 err_args(fcx.tcx(), args.len())
2152 expected_arg_tys = match expected_arg_tys.get(0) {
2153 Some(&ty) => match ty.sty {
2154 ty::TyTuple(ref tys) => &**tys,
2159 (*arg_types).clone()
2163 span_err!(tcx.sess, sp, E0059,
2164 "cannot use call notation; the first type parameter \
2165 for the function trait is neither a tuple nor unit");
2166 expected_arg_tys = &[];
2167 err_args(fcx.tcx(), args.len())
2170 } else if expected_arg_count == supplied_arg_count {
2172 } else if variadic {
2173 if supplied_arg_count >= expected_arg_count {
2176 span_err!(tcx.sess, sp, E0060,
2177 "this function takes at least {} parameter{} \
2178 but {} parameter{} supplied",
2180 if expected_arg_count == 1 {""} else {"s"},
2182 if supplied_arg_count == 1 {" was"} else {"s were"});
2183 expected_arg_tys = &[];
2184 err_args(fcx.tcx(), supplied_arg_count)
2187 span_err!(tcx.sess, sp, E0061,
2188 "this function takes {} parameter{} but {} parameter{} supplied",
2190 if expected_arg_count == 1 {""} else {"s"},
2192 if supplied_arg_count == 1 {" was"} else {"s were"});
2193 expected_arg_tys = &[];
2194 err_args(fcx.tcx(), supplied_arg_count)
2197 debug!("check_argument_types: formal_tys={:?}",
2198 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2200 // Check the arguments.
2201 // We do this in a pretty awful way: first we typecheck any arguments
2202 // that are not anonymous functions, then we typecheck the anonymous
2203 // functions. This is so that we have more information about the types
2204 // of arguments when we typecheck the functions. This isn't really the
2205 // right way to do this.
2206 let xs = [false, true];
2207 for check_blocks in &xs {
2208 let check_blocks = *check_blocks;
2209 debug!("check_blocks={}", check_blocks);
2211 // More awful hacks: before we check argument types, try to do
2212 // an "opportunistic" vtable resolution of any trait bounds on
2213 // the call. This helps coercions.
2215 fcx.select_new_obligations();
2218 // For variadic functions, we don't have a declared type for all of
2219 // the arguments hence we only do our usual type checking with
2220 // the arguments who's types we do know.
2221 let t = if variadic {
2223 } else if tuple_arguments == TupleArguments {
2228 for (i, arg) in args.iter().take(t).enumerate() {
2229 let is_block = match arg.node {
2230 ast::ExprClosure(..) => true,
2234 if is_block == check_blocks {
2235 debug!("checking the argument");
2236 let formal_ty = formal_tys[i];
2238 // The special-cased logic below has three functions:
2239 // 1. Provide as good of an expected type as possible.
2240 let expected = expected_arg_tys.get(i).map(|&ty| {
2241 Expectation::rvalue_hint(ty)
2244 check_expr_with_unifier(fcx, &**arg,
2245 expected.unwrap_or(ExpectHasType(formal_ty)),
2247 // 2. Coerce to the most detailed type that could be coerced
2248 // to, which is `expected_ty` if `rvalue_hint` returns an
2249 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2250 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2251 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2253 // 3. Relate the expected type and the formal one,
2254 // if the expected type was used for the coercion.
2255 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2261 // We also need to make sure we at least write the ty of the other
2262 // arguments which we skipped above.
2264 for arg in args.iter().skip(expected_arg_count) {
2265 check_expr(fcx, &**arg);
2267 // There are a few types which get autopromoted when passed via varargs
2268 // in C but we just error out instead and require explicit casts.
2269 let arg_ty = structurally_resolved_type(fcx, arg.span,
2270 fcx.expr_ty(&**arg));
2272 ty::TyFloat(ast::TyF32) => {
2273 fcx.type_error_message(arg.span,
2275 format!("can't pass an {} to variadic \
2276 function, cast to c_double", t)
2279 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2280 fcx.type_error_message(arg.span, |t| {
2281 format!("can't pass {} to variadic \
2282 function, cast to c_int",
2286 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2287 fcx.type_error_message(arg.span, |t| {
2288 format!("can't pass {} to variadic \
2289 function, cast to c_uint",
2299 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2300 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2301 (0..len).map(|_| tcx.types.err).collect()
2304 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2305 call_expr: &ast::Expr,
2306 output: ty::FnOutput<'tcx>) {
2307 fcx.write_ty(call_expr.id, match output {
2308 ty::FnConverging(output_ty) => output_ty,
2309 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2313 // AST fragment checking
2314 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2316 expected: Expectation<'tcx>)
2319 let tcx = fcx.ccx.tcx;
2322 ast::LitStr(..) => tcx.mk_static_str(),
2323 ast::LitBinary(ref v) => {
2324 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2325 tcx.mk_array(tcx.types.u8, v.len()))
2327 ast::LitByte(_) => tcx.types.u8,
2328 ast::LitChar(_) => tcx.types.char,
2329 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2330 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2331 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2332 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2334 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2335 ty::TyChar => Some(tcx.types.u8),
2336 ty::TyRawPtr(..) => Some(tcx.types.usize),
2337 ty::TyBareFn(..) => Some(tcx.types.usize),
2341 opt_ty.unwrap_or_else(
2342 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2344 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2345 ast::LitFloatUnsuffixed(_) => {
2346 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2348 ty::TyFloat(_) => Some(ty),
2352 opt_ty.unwrap_or_else(
2353 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2355 ast::LitBool(_) => tcx.types.bool
2359 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2360 expr: &'tcx ast::Expr,
2361 expected: Ty<'tcx>) {
2362 check_expr_with_unifier(
2363 fcx, expr, ExpectHasType(expected), NoPreference,
2364 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2367 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2368 expr: &'tcx ast::Expr,
2369 expected: Ty<'tcx>) {
2370 check_expr_with_unifier(
2371 fcx, expr, ExpectHasType(expected), NoPreference,
2372 || demand::coerce(fcx, expr.span, expected, expr));
2375 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx ast::Expr,
2376 expected: Ty<'tcx>) {
2377 check_expr_with_unifier(
2378 fcx, expr, ExpectHasType(expected), NoPreference,
2382 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2383 expr: &'tcx ast::Expr,
2384 expected: Expectation<'tcx>) {
2385 check_expr_with_unifier(
2386 fcx, expr, expected, NoPreference,
2390 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2391 expr: &'tcx ast::Expr,
2392 expected: Expectation<'tcx>,
2393 lvalue_pref: LvaluePreference)
2395 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2398 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr) {
2399 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2402 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr,
2403 lvalue_pref: LvaluePreference) {
2404 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2407 // determine the `self` type, using fresh variables for all variables
2408 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2409 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2411 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2412 span: Span, // (potential) receiver for this impl
2414 -> TypeAndSubsts<'tcx> {
2415 let tcx = fcx.tcx();
2417 let ity = tcx.lookup_item_type(did);
2418 let (n_tps, rps, raw_ty) =
2419 (ity.generics.types.len(subst::TypeSpace),
2420 ity.generics.regions.get_slice(subst::TypeSpace),
2423 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2424 let tps = fcx.inh.infcx.next_ty_vars(n_tps);
2425 let substs = subst::Substs::new_type(tps, rps);
2426 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2428 TypeAndSubsts { substs: substs, ty: substd_ty }
2431 /// Controls whether the arguments are tupled. This is used for the call
2434 /// Tupling means that all call-side arguments are packed into a tuple and
2435 /// passed as a single parameter. For example, if tupling is enabled, this
2438 /// fn f(x: (isize, isize))
2440 /// Can be called as:
2447 #[derive(Clone, Eq, PartialEq)]
2448 enum TupleArgumentsFlag {
2453 /// Unifies the return type with the expected type early, for more coercions
2454 /// and forward type information on the argument expressions.
2455 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2457 expected_ret: Expectation<'tcx>,
2458 formal_ret: ty::FnOutput<'tcx>,
2459 formal_args: &[Ty<'tcx>])
2461 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2462 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2463 fcx.infcx().commit_regions_if_ok(|| {
2464 // Attempt to apply a subtyping relationship between the formal
2465 // return type (likely containing type variables if the function
2466 // is polymorphic) and the expected return type.
2467 // No argument expectations are produced if unification fails.
2468 let origin = infer::Misc(call_span);
2469 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2470 // FIXME(#15760) can't use try! here, FromError doesn't default
2471 // to identity so the resulting type is not constrained.
2472 if let Err(e) = ures {
2476 // Record all the argument types, with the substitutions
2477 // produced from the above subtyping unification.
2478 Ok(formal_args.iter().map(|ty| {
2479 fcx.infcx().resolve_type_vars_if_possible(ty)
2485 }).unwrap_or(vec![]);
2486 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2487 formal_args, formal_ret,
2488 expected_args, expected_ret);
2493 /// If an expression has any sub-expressions that result in a type error,
2494 /// inspecting that expression's type with `ty.references_error()` will return
2495 /// true. Likewise, if an expression is known to diverge, inspecting its
2496 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2497 /// strict, _|_ can appear in the type of an expression that does not,
2498 /// itself, diverge: for example, fn() -> _|_.)
2499 /// Note that inspecting a type's structure *directly* may expose the fact
2500 /// that there are actually multiple representations for `TyError`, so avoid
2501 /// that when err needs to be handled differently.
2502 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2503 expr: &'tcx ast::Expr,
2504 expected: Expectation<'tcx>,
2505 lvalue_pref: LvaluePreference,
2509 debug!(">> typechecking: expr={:?} expected={:?}",
2512 // Checks a method call.
2513 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2514 expr: &'tcx ast::Expr,
2515 method_name: ast::SpannedIdent,
2516 args: &'tcx [P<ast::Expr>],
2518 expected: Expectation<'tcx>,
2519 lvalue_pref: LvaluePreference) {
2520 let rcvr = &*args[0];
2521 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2523 // no need to check for bot/err -- callee does that
2524 let expr_t = structurally_resolved_type(fcx,
2526 fcx.expr_ty(&*rcvr));
2528 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2529 let fn_ty = match method::lookup(fcx,
2531 method_name.node.name,
2537 let method_ty = method.ty;
2538 let method_call = MethodCall::expr(expr.id);
2539 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2543 method::report_error(fcx, method_name.span, expr_t,
2544 method_name.node.name, Some(rcvr), error);
2545 fcx.write_error(expr.id);
2550 // Call the generic checker.
2551 let ret_ty = check_method_argument_types(fcx,
2559 write_call(fcx, expr, ret_ty);
2562 // A generic function for checking the then and else in an if
2564 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2565 cond_expr: &'tcx ast::Expr,
2566 then_blk: &'tcx ast::Block,
2567 opt_else_expr: Option<&'tcx ast::Expr>,
2570 expected: Expectation<'tcx>) {
2571 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2573 let expected = expected.adjust_for_branches(fcx);
2574 check_block_with_expected(fcx, then_blk, expected);
2575 let then_ty = fcx.node_ty(then_blk.id);
2577 let branches_ty = match opt_else_expr {
2578 Some(ref else_expr) => {
2579 check_expr_with_expectation(fcx, &**else_expr, expected);
2580 let else_ty = fcx.expr_ty(&**else_expr);
2581 infer::common_supertype(fcx.infcx(),
2582 infer::IfExpression(sp),
2588 infer::common_supertype(fcx.infcx(),
2589 infer::IfExpressionWithNoElse(sp),
2596 let cond_ty = fcx.expr_ty(cond_expr);
2597 let if_ty = if cond_ty.references_error() {
2603 fcx.write_ty(id, if_ty);
2606 // Check field access expressions
2607 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2608 expr: &'tcx ast::Expr,
2609 lvalue_pref: LvaluePreference,
2610 base: &'tcx ast::Expr,
2611 field: &ast::SpannedIdent) {
2612 let tcx = fcx.ccx.tcx;
2613 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2614 let expr_t = structurally_resolved_type(fcx, expr.span,
2616 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2617 let (_, autoderefs, field_ty) = autoderef(fcx,
2621 UnresolvedTypeAction::Error,
2625 ty::TyStruct(base_id, substs) => {
2626 debug!("struct named {:?}", base_t);
2627 let fields = tcx.lookup_struct_fields(base_id);
2628 fcx.lookup_field_ty(expr.span, base_id, &fields[..],
2629 field.node.name, &(*substs))
2636 fcx.write_ty(expr.id, field_ty);
2637 fcx.write_autoderef_adjustment(base.id, autoderefs);
2643 if method::exists(fcx, field.span, field.node.name, expr_t, expr.id) {
2644 fcx.type_error_message(
2647 format!("attempted to take value of method `{}` on type \
2648 `{}`", token::get_ident(field.node), actual)
2652 tcx.sess.fileline_help(field.span,
2653 "maybe a `()` to call it is missing? \
2654 If not, try an anonymous function");
2656 fcx.type_error_message(
2659 format!("attempted access of field `{}` on \
2660 type `{}`, but no field with that \
2662 token::get_ident(field.node),
2666 if let ty::TyStruct(did, _) = expr_t.sty {
2667 suggest_field_names(did, field, tcx, vec![]);
2671 fcx.write_error(expr.id);
2674 // displays hints about the closest matches in field names
2675 fn suggest_field_names<'tcx>(id : DefId,
2676 field : &ast::SpannedIdent,
2677 tcx : &ty::ctxt<'tcx>,
2679 let ident = token::get_ident(field.node);
2681 // only find fits with at least one matching letter
2682 let mut best_dist = name.len();
2683 let fields = tcx.lookup_struct_fields(id);
2684 let mut best = None;
2685 for elem in &fields {
2686 let n = elem.name.as_str();
2687 // ignore already set fields
2688 if skip.iter().any(|&x| x == n) {
2691 // ignore private fields from non-local crates
2692 if id.krate != ast::LOCAL_CRATE && elem.vis != Visibility::Public {
2695 let dist = lev_distance(n, name);
2696 if dist < best_dist {
2701 if let Some(n) = best {
2702 tcx.sess.span_help(field.span,
2703 &format!("did you mean `{}`?", n));
2707 // Check tuple index expressions
2708 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2709 expr: &'tcx ast::Expr,
2710 lvalue_pref: LvaluePreference,
2711 base: &'tcx ast::Expr,
2712 idx: codemap::Spanned<usize>) {
2713 let tcx = fcx.ccx.tcx;
2714 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2715 let expr_t = structurally_resolved_type(fcx, expr.span,
2717 let mut tuple_like = false;
2718 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2719 let (_, autoderefs, field_ty) = autoderef(fcx,
2723 UnresolvedTypeAction::Error,
2727 ty::TyStruct(base_id, substs) => {
2728 tuple_like = tcx.is_tuple_struct(base_id);
2730 debug!("tuple struct named {:?}", base_t);
2731 let fields = tcx.lookup_struct_fields(base_id);
2732 fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
2733 idx.node, &(*substs))
2738 ty::TyTuple(ref v) => {
2740 if idx.node < v.len() { Some(v[idx.node]) } else { None }
2747 fcx.write_ty(expr.id, field_ty);
2748 fcx.write_autoderef_adjustment(base.id, autoderefs);
2753 fcx.type_error_message(
2757 format!("attempted out-of-bounds tuple index `{}` on \
2762 format!("attempted tuple index `{}` on type `{}`, but the \
2763 type was not a tuple or tuple struct",
2770 fcx.write_error(expr.id);
2773 fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2774 struct_ty: Ty<'tcx>,
2776 class_id: ast::DefId,
2777 node_id: ast::NodeId,
2778 substitutions: &'tcx subst::Substs<'tcx>,
2779 field_types: &[ty::FieldTy],
2780 ast_fields: &'tcx [ast::Field],
2781 check_completeness: bool,
2782 enum_id_opt: Option<ast::DefId>) {
2783 let tcx = fcx.ccx.tcx;
2785 let mut class_field_map = FnvHashMap();
2786 let mut fields_found = 0;
2787 for field in field_types {
2788 class_field_map.insert(field.name, (field.id, false));
2791 let mut error_happened = false;
2793 // Typecheck each field.
2794 for field in ast_fields {
2795 let mut expected_field_type = tcx.types.err;
2797 let pair = class_field_map.get(&field.ident.node.name).cloned();
2800 fcx.type_error_message(
2802 |actual| match enum_id_opt {
2804 let variant_type = tcx.enum_variant_with_id(enum_id,
2806 format!("struct variant `{}::{}` has no field named `{}`",
2807 actual, variant_type.name.as_str(),
2808 token::get_ident(field.ident.node))
2811 format!("structure `{}` has no field named `{}`",
2813 token::get_ident(field.ident.node))
2818 // prevent all specified fields from being suggested
2819 let skip_fields = ast_fields.iter().map(|ref x| x.ident.node.name.as_str());
2820 let actual_id = match enum_id_opt {
2821 Some(_) => class_id,
2822 None => struct_ty.ty_to_def_id().unwrap()
2824 suggest_field_names(actual_id, &field.ident, tcx, skip_fields.collect());
2825 error_happened = true;
2827 Some((_, true)) => {
2828 span_err!(fcx.tcx().sess, field.ident.span, E0062,
2829 "field `{}` specified more than once",
2830 token::get_ident(field.ident.node));
2831 error_happened = true;
2833 Some((field_id, false)) => {
2834 expected_field_type =
2835 tcx.lookup_field_type(class_id, field_id, substitutions);
2836 expected_field_type =
2837 fcx.normalize_associated_types_in(
2838 field.span, &expected_field_type);
2839 class_field_map.insert(
2840 field.ident.node.name, (field_id, true));
2845 // Make sure to give a type to the field even if there's
2846 // an error, so we can continue typechecking
2847 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
2851 fcx.write_error(node_id);
2854 if check_completeness && !error_happened {
2855 // Make sure the programmer specified all the fields.
2856 assert!(fields_found <= field_types.len());
2857 if fields_found < field_types.len() {
2858 let mut missing_fields = Vec::new();
2859 for class_field in field_types {
2860 let name = class_field.name;
2861 let (_, seen) = *class_field_map.get(&name).unwrap();
2863 missing_fields.push(
2864 format!("`{}`", &token::get_name(name)))
2868 span_err!(tcx.sess, span, E0063,
2869 "missing field{}: {}",
2870 if missing_fields.len() == 1 {""} else {"s"},
2871 missing_fields.join(", "));
2875 if !error_happened {
2876 fcx.write_ty(node_id, fcx.ccx.tcx.mk_struct(class_id, substitutions));
2880 fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2882 span: codemap::Span,
2883 class_id: ast::DefId,
2884 fields: &'tcx [ast::Field],
2885 base_expr: Option<&'tcx ast::Expr>) {
2886 let tcx = fcx.ccx.tcx;
2888 // Generate the struct type.
2890 ty: mut struct_type,
2891 substs: struct_substs
2892 } = fcx.instantiate_type(span, class_id);
2894 // Look up and check the fields.
2895 let class_fields = tcx.lookup_struct_fields(class_id);
2896 check_struct_or_variant_fields(fcx,
2901 fcx.ccx.tcx.mk_substs(struct_substs),
2904 base_expr.is_none(),
2906 if fcx.node_ty(id).references_error() {
2907 struct_type = tcx.types.err;
2910 // Check the base expression if necessary.
2913 Some(base_expr) => {
2914 check_expr_has_type(fcx, &*base_expr, struct_type);
2918 // Write in the resulting type.
2919 fcx.write_ty(id, struct_type);
2922 fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2924 span: codemap::Span,
2925 enum_id: ast::DefId,
2926 variant_id: ast::DefId,
2927 fields: &'tcx [ast::Field]) {
2928 let tcx = fcx.ccx.tcx;
2930 // Look up the number of type parameters and the raw type, and
2931 // determine whether the enum is region-parameterized.
2934 substs: substitutions
2935 } = fcx.instantiate_type(span, enum_id);
2937 // Look up and check the enum variant fields.
2938 let variant_fields = tcx.lookup_struct_fields(variant_id);
2939 check_struct_or_variant_fields(fcx,
2944 fcx.ccx.tcx.mk_substs(substitutions),
2945 &variant_fields[..],
2949 fcx.write_ty(id, enum_type);
2952 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2954 fields: &'tcx [ast::Field],
2955 base_expr: &'tcx Option<P<ast::Expr>>) {
2956 // Make sure to still write the types
2957 // otherwise we might ICE
2958 fcx.write_error(id);
2959 for field in fields {
2960 check_expr(fcx, &*field.expr);
2963 Some(ref base) => check_expr(fcx, &**base),
2968 type ExprCheckerWithTy = fn(&FnCtxt, &ast::Expr, Ty);
2970 let tcx = fcx.ccx.tcx;
2973 ast::ExprBox(ref opt_place, ref subexpr) => {
2974 opt_place.as_ref().map(|place|check_expr(fcx, &**place));
2975 check_expr(fcx, &**subexpr);
2977 let mut checked = false;
2978 opt_place.as_ref().map(|place| match place.node {
2979 ast::ExprPath(None, ref path) => {
2980 // FIXME(pcwalton): For now we hardcode the only permissible
2981 // place: the exchange heap.
2982 let definition = lookup_full_def(tcx, path.span, place.id);
2983 let def_id = definition.def_id();
2984 let referent_ty = fcx.expr_ty(&**subexpr);
2985 if tcx.lang_items.exchange_heap() == Some(def_id) {
2986 fcx.write_ty(id, tcx.mk_box(referent_ty));
2994 span_err!(tcx.sess, expr.span, E0066,
2995 "only the exchange heap is currently supported");
2996 fcx.write_ty(id, tcx.types.err);
3000 ast::ExprLit(ref lit) => {
3001 let typ = check_lit(fcx, &**lit, expected);
3002 fcx.write_ty(id, typ);
3004 ast::ExprBinary(op, ref lhs, ref rhs) => {
3005 op::check_binop(fcx, expr, op, lhs, rhs);
3007 ast::ExprAssignOp(op, ref lhs, ref rhs) => {
3008 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3010 ast::ExprUnary(unop, ref oprnd) => {
3011 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3013 ast::UnUniq => match ty.sty {
3015 Expectation::rvalue_hint(ty)
3021 ast::UnNot | ast::UnNeg => {
3029 let lvalue_pref = match unop {
3030 ast::UnDeref => lvalue_pref,
3033 check_expr_with_expectation_and_lvalue_pref(
3034 fcx, &**oprnd, expected_inner, lvalue_pref);
3035 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3037 if !oprnd_t.references_error() {
3040 oprnd_t = tcx.mk_box(oprnd_t);
3043 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3044 oprnd_t = match oprnd_t.builtin_deref(true) {
3046 None => match try_overloaded_deref(fcx, expr.span,
3047 Some(MethodCall::expr(expr.id)),
3048 Some(&**oprnd), oprnd_t, lvalue_pref) {
3051 fcx.type_error_message(expr.span, |actual| {
3052 format!("type `{}` cannot be \
3053 dereferenced", actual)
3061 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3063 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3064 oprnd_t = op::check_user_unop(fcx, "!", "not",
3065 tcx.lang_items.not_trait(),
3066 expr, &**oprnd, oprnd_t, unop);
3070 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3072 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3073 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3074 tcx.lang_items.neg_trait(),
3075 expr, &**oprnd, oprnd_t, unop);
3077 if let ty::TyUint(_) = oprnd_t.sty {
3078 if !tcx.sess.features.borrow().negate_unsigned {
3079 feature_gate::emit_feature_err(
3080 &tcx.sess.parse_sess.span_diagnostic,
3083 "unary negation of unsigned integers may be removed in the future");
3089 fcx.write_ty(id, oprnd_t);
3091 ast::ExprAddrOf(mutbl, ref oprnd) => {
3092 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3094 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3095 if fcx.tcx().expr_is_lval(&**oprnd) {
3096 // Lvalues may legitimately have unsized types.
3097 // For example, dereferences of a fat pointer and
3098 // the last field of a struct can be unsized.
3099 ExpectHasType(mt.ty)
3101 Expectation::rvalue_hint(mt.ty)
3107 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3108 check_expr_with_expectation_and_lvalue_pref(fcx,
3113 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3114 let oprnd_t = if tm.ty.references_error() {
3117 // Note: at this point, we cannot say what the best lifetime
3118 // is to use for resulting pointer. We want to use the
3119 // shortest lifetime possible so as to avoid spurious borrowck
3120 // errors. Moreover, the longest lifetime will depend on the
3121 // precise details of the value whose address is being taken
3122 // (and how long it is valid), which we don't know yet until type
3123 // inference is complete.
3125 // Therefore, here we simply generate a region variable. The
3126 // region inferencer will then select the ultimate value.
3127 // Finally, borrowck is charged with guaranteeing that the
3128 // value whose address was taken can actually be made to live
3129 // as long as it needs to live.
3130 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3131 tcx.mk_ref(tcx.mk_region(region), tm)
3133 fcx.write_ty(id, oprnd_t);
3135 ast::ExprPath(ref maybe_qself, ref path) => {
3136 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3137 fcx.to_ty(&qself.ty)
3140 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3142 } else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
3143 // Create some fake resolution that can't possibly be a type.
3144 def::PathResolution {
3145 base_def: def::DefMod(local_def(ast::CRATE_NODE_ID)),
3146 last_private: LastMod(AllPublic),
3147 depth: path.segments.len()
3150 tcx.sess.span_bug(expr.span,
3151 &format!("unbound path {:?}", expr))
3154 if let Some((opt_ty, segments, def)) =
3155 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3156 expr.span, expr.id) {
3157 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3160 instantiate_path(fcx,
3170 // We always require that the type provided as the value for
3171 // a type parameter outlives the moment of instantiation.
3172 constrain_path_type_parameters(fcx, expr);
3174 ast::ExprInlineAsm(ref ia) => {
3175 for &(_, ref input) in &ia.inputs {
3176 check_expr(fcx, &**input);
3178 for &(_, ref out, _) in &ia.outputs {
3179 check_expr(fcx, &**out);
3183 ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
3184 ast::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3185 ast::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3186 ast::ExprRet(ref expr_opt) => {
3188 ty::FnConverging(result_type) => {
3191 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3192 result_type, fcx.tcx().mk_nil()) {
3193 span_err!(tcx.sess, expr.span, E0069,
3194 "`return;` in a function whose return type is \
3198 check_expr_coercable_to_type(fcx, &**e, result_type);
3202 ty::FnDiverging => {
3203 if let Some(ref e) = *expr_opt {
3204 check_expr(fcx, &**e);
3206 span_err!(tcx.sess, expr.span, E0166,
3207 "`return` in a function declared as diverging");
3210 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3212 ast::ExprParen(ref a) => {
3213 check_expr_with_expectation_and_lvalue_pref(fcx,
3217 fcx.write_ty(id, fcx.expr_ty(&**a));
3219 ast::ExprAssign(ref lhs, ref rhs) => {
3220 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3222 let tcx = fcx.tcx();
3223 if !tcx.expr_is_lval(&**lhs) {
3224 span_err!(tcx.sess, expr.span, E0070,
3225 "illegal left-hand side expression");
3228 let lhs_ty = fcx.expr_ty(&**lhs);
3229 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3230 let rhs_ty = fcx.expr_ty(&**rhs);
3232 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3234 if lhs_ty.references_error() || rhs_ty.references_error() {
3235 fcx.write_error(id);
3240 ast::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3241 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3242 id, expr.span, expected);
3244 ast::ExprIfLet(..) => {
3245 tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
3247 ast::ExprWhile(ref cond, ref body, _) => {
3248 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3249 check_block_no_value(fcx, &**body);
3250 let cond_ty = fcx.expr_ty(&**cond);
3251 let body_ty = fcx.node_ty(body.id);
3252 if cond_ty.references_error() || body_ty.references_error() {
3253 fcx.write_error(id);
3259 ast::ExprWhileLet(..) => {
3260 tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
3262 ast::ExprForLoop(..) => {
3263 tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
3265 ast::ExprLoop(ref body, _) => {
3266 check_block_no_value(fcx, &**body);
3267 if !may_break(tcx, expr.id, &**body) {
3268 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3273 ast::ExprMatch(ref discrim, ref arms, match_src) => {
3274 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3276 ast::ExprClosure(capture, ref decl, ref body) => {
3277 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3279 ast::ExprBlock(ref b) => {
3280 check_block_with_expected(fcx, &**b, expected);
3281 fcx.write_ty(id, fcx.node_ty(b.id));
3283 ast::ExprCall(ref callee, ref args) => {
3284 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3286 ast::ExprMethodCall(ident, ref tps, ref args) => {
3287 check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref);
3288 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3289 let args_err = arg_tys.fold(false,
3291 rest_err || a.references_error()});
3293 fcx.write_error(id);
3296 ast::ExprCast(ref e, ref t) => {
3297 if let ast::TyFixedLengthVec(_, ref count_expr) = t.node {
3298 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3301 // Find the type of `e`. Supply hints based on the type we are casting to,
3303 let t_cast = fcx.to_ty(t);
3304 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3305 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3306 let t_expr = fcx.expr_ty(e);
3308 // Eagerly check for some obvious errors.
3309 if t_expr.references_error() {
3310 fcx.write_error(id);
3311 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3312 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3314 // Write a type for the whole expression, assuming everything is going
3316 fcx.write_ty(id, t_cast);
3318 // Defer other checks until we're done type checking.
3319 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3320 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3321 deferred_cast_checks.push(cast_check);
3324 ast::ExprVec(ref args) => {
3325 let uty = expected.to_option(fcx).and_then(|uty| {
3327 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3332 let typ = match uty {
3335 check_expr_coercable_to_type(fcx, &**e, uty);
3340 let t: Ty = fcx.infcx().next_ty_var();
3342 check_expr_has_type(fcx, &**e, t);
3347 let typ = tcx.mk_array(typ, args.len());
3348 fcx.write_ty(id, typ);
3350 ast::ExprRepeat(ref element, ref count_expr) => {
3351 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3352 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3354 let uty = match expected {
3355 ExpectHasType(uty) => {
3357 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3364 let (element_ty, t) = match uty {
3366 check_expr_coercable_to_type(fcx, &**element, uty);
3370 let t: Ty = fcx.infcx().next_ty_var();
3371 check_expr_has_type(fcx, &**element, t);
3372 (fcx.expr_ty(&**element), t)
3377 // For [foo, ..n] where n > 1, `foo` must have
3379 fcx.require_type_meets(
3386 if element_ty.references_error() {
3387 fcx.write_error(id);
3389 let t = tcx.mk_array(t, count);
3390 fcx.write_ty(id, t);
3393 ast::ExprTup(ref elts) => {
3394 let flds = expected.only_has_type(fcx).and_then(|ty| {
3396 ty::TyTuple(ref flds) => Some(&flds[..]),
3400 let mut err_field = false;
3402 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3403 let t = match flds {
3404 Some(ref fs) if i < fs.len() => {
3406 check_expr_coercable_to_type(fcx, &**e, ety);
3410 check_expr_with_expectation(fcx, &**e, NoExpectation);
3414 err_field = err_field || t.references_error();
3418 fcx.write_error(id);
3420 let typ = tcx.mk_tup(elt_ts);
3421 fcx.write_ty(id, typ);
3424 ast::ExprStruct(ref path, ref fields, ref base_expr) => {
3425 // Resolve the path.
3426 let def = lookup_full_def(tcx, path.span, id);
3427 let struct_id = match def {
3428 def::DefVariant(enum_id, variant_id, true) => {
3429 check_struct_enum_variant(fcx, id, expr.span, enum_id,
3430 variant_id, &fields[..]);
3433 def::DefTrait(def_id) => {
3434 span_err!(tcx.sess, path.span, E0159,
3435 "use of trait `{}` as a struct constructor",
3436 pprust::path_to_string(path));
3437 check_struct_fields_on_error(fcx,
3444 // Verify that this was actually a struct.
3445 let typ = fcx.ccx.tcx.lookup_item_type(def.def_id());
3447 ty::TyStruct(struct_did, _) => {
3448 check_struct_constructor(fcx,
3453 base_expr.as_ref().map(|e| &**e));
3456 span_err!(tcx.sess, path.span, E0071,
3457 "`{}` does not name a structure",
3458 pprust::path_to_string(path));
3459 check_struct_fields_on_error(fcx,
3470 // Turn the path into a type and verify that that type unifies with
3471 // the resulting structure type. This is needed to handle type
3472 // parameters correctly.
3473 let actual_structure_type = fcx.expr_ty(&*expr);
3474 if !actual_structure_type.references_error() {
3475 let type_and_substs = fcx.instantiate_struct_literal_ty(struct_id, path);
3476 match fcx.mk_subty(false,
3477 infer::Misc(path.span),
3478 actual_structure_type,
3479 type_and_substs.ty) {
3481 Err(type_error) => {
3482 span_err!(fcx.tcx().sess, path.span, E0235,
3483 "structure constructor specifies a \
3484 structure of type `{}`, but this \
3485 structure has type `{}`: {}",
3487 .ty_to_string(type_and_substs.ty),
3490 actual_structure_type),
3492 tcx.note_and_explain_type_err(&type_error, path.span);
3497 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3499 ast::ExprField(ref base, ref field) => {
3500 check_field(fcx, expr, lvalue_pref, &**base, field);
3502 ast::ExprTupField(ref base, idx) => {
3503 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3505 ast::ExprIndex(ref base, ref idx) => {
3506 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3507 check_expr(fcx, &**idx);
3509 let base_t = fcx.expr_ty(&**base);
3510 let idx_t = fcx.expr_ty(&**idx);
3512 if base_t.references_error() {
3513 fcx.write_ty(id, base_t);
3514 } else if idx_t.references_error() {
3515 fcx.write_ty(id, idx_t);
3517 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3518 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3519 Some((index_ty, element_ty)) => {
3520 let idx_expr_ty = fcx.expr_ty(idx);
3521 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3522 fcx.write_ty(id, element_ty);
3525 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3526 fcx.type_error_message(
3529 format!("cannot index a value of type `{}`",
3534 fcx.write_ty(id, fcx.tcx().types.err);
3539 ast::ExprRange(ref start, ref end) => {
3540 let t_start = start.as_ref().map(|e| {
3541 check_expr(fcx, &**e);
3544 let t_end = end.as_ref().map(|e| {
3545 check_expr(fcx, &**e);
3549 let idx_type = match (t_start, t_end) {
3550 (Some(ty), None) | (None, Some(ty)) => {
3553 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3554 t_end.references_error()) => {
3555 Some(fcx.tcx().types.err)
3557 (Some(t_start), Some(t_end)) => {
3558 Some(infer::common_supertype(fcx.infcx(),
3559 infer::RangeExpression(expr.span),
3567 // Note that we don't check the type of start/end satisfy any
3568 // bounds because right now the range structs do not have any. If we add
3569 // some bounds, then we'll need to check `t_start` against them here.
3571 let range_type = match idx_type {
3572 Some(idx_type) if idx_type.references_error() => {
3576 // Find the did from the appropriate lang item.
3577 let did = match (start, end) {
3578 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3579 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3580 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3582 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3586 if let Some(did) = did {
3587 let predicates = tcx.lookup_predicates(did);
3588 let substs = Substs::new_type(vec![idx_type], vec![]);
3589 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3590 fcx.add_obligations_for_parameters(
3591 traits::ObligationCause::new(expr.span,
3593 traits::ItemObligation(did)),
3596 tcx.mk_struct(did, tcx.mk_substs(substs))
3598 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3603 // Neither start nor end => RangeFull
3604 if let Some(did) = tcx.lang_items.range_full_struct() {
3605 let substs = Substs::new_type(vec![], vec![]);
3606 tcx.mk_struct(did, tcx.mk_substs(substs))
3608 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3614 fcx.write_ty(id, range_type);
3619 debug!("type of expr({}) {} is...", expr.id,
3620 syntax::print::pprust::expr_to_string(expr));
3621 debug!("... {:?}, expected is {:?}",
3628 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3629 path_res: def::PathResolution,
3630 opt_self_ty: Option<Ty<'tcx>>,
3631 path: &'a ast::Path,
3633 node_id: ast::NodeId)
3634 -> Option<(Option<Ty<'tcx>>,
3635 &'a [ast::PathSegment],
3639 // Associated constants can't depend on generic types.
3640 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3644 node_id: ast::NodeId) -> bool {
3646 def::DefAssociatedConst(..) => {
3647 if ty.has_param_types() || ty.has_self_ty() {
3648 span_err!(fcx.sess(), span, E0329,
3649 "Associated consts cannot depend \
3650 on type parameters or Self.");
3651 fcx.write_error(node_id);
3660 // If fully resolved already, we don't have to do anything.
3661 if path_res.depth == 0 {
3662 if let Some(ty) = opt_self_ty {
3663 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3668 Some((opt_self_ty, &path.segments, path_res.base_def))
3670 let mut def = path_res.base_def;
3671 let ty_segments = path.segments.split_last().unwrap().1;
3672 let base_ty_end = path.segments.len() - path_res.depth;
3673 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3674 PathParamMode::Optional,
3677 &ty_segments[..base_ty_end],
3678 &ty_segments[base_ty_end..]);
3679 let item_segment = path.segments.last().unwrap();
3680 let item_name = item_segment.identifier.name;
3681 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3683 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3686 // Write back the new resolution.
3687 fcx.ccx.tcx.def_map.borrow_mut()
3688 .insert(node_id, def::PathResolution {
3690 last_private: path_res.last_private.or(lp),
3693 Some((Some(ty), slice::ref_slice(item_segment), def))
3696 method::report_error(fcx, span, ty,
3697 item_name, None, error);
3698 fcx.write_error(node_id);
3705 fn constrain_path_type_parameters(fcx: &FnCtxt,
3708 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3709 fcx.add_default_region_param_bounds(&item_substs.substs, expr);
3713 impl<'tcx> Expectation<'tcx> {
3714 /// Provide an expectation for an rvalue expression given an *optional*
3715 /// hint, which is not required for type safety (the resulting type might
3716 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3717 /// is useful in determining the concrete type.
3719 /// The primary use case is where the expected type is a fat pointer,
3720 /// like `&[isize]`. For example, consider the following statement:
3722 /// let x: &[isize] = &[1, 2, 3];
3724 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3725 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3726 /// expectation `ExpectHasType([isize])`, that would be too strong --
3727 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3728 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3729 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3730 /// which still is useful, because it informs integer literals and the like.
3731 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3732 /// for examples of where this comes up,.
3733 fn rvalue_hint(ty: Ty<'tcx>) -> Expectation<'tcx> {
3735 ty::TySlice(_) | ty::TyTrait(..) => {
3736 ExpectRvalueLikeUnsized(ty)
3738 _ => ExpectHasType(ty)
3742 // Resolves `expected` by a single level if it is a variable. If
3743 // there is no expected type or resolution is not possible (e.g.,
3744 // no constraints yet present), just returns `None`.
3745 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3750 ExpectCastableToType(t) => {
3751 ExpectCastableToType(
3752 fcx.infcx().resolve_type_vars_if_possible(&t))
3754 ExpectHasType(t) => {
3756 fcx.infcx().resolve_type_vars_if_possible(&t))
3758 ExpectRvalueLikeUnsized(t) => {
3759 ExpectRvalueLikeUnsized(
3760 fcx.infcx().resolve_type_vars_if_possible(&t))
3765 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3766 match self.resolve(fcx) {
3767 NoExpectation => None,
3768 ExpectCastableToType(ty) |
3770 ExpectRvalueLikeUnsized(ty) => Some(ty),
3774 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3775 match self.resolve(fcx) {
3776 ExpectHasType(ty) => Some(ty),
3782 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3783 local: &'tcx ast::Local,
3784 init: &'tcx ast::Expr)
3786 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3788 let local_ty = fcx.local_ty(init.span, local.id);
3789 if let Some(m) = ref_bindings {
3790 // Somewhat subtle: if we have a `ref` binding in the pattern,
3791 // we want to avoid introducing coercions for the RHS. This is
3792 // both because it helps preserve sanity and, in the case of
3793 // ref mut, for soundness (issue #23116). In particular, in
3794 // the latter case, we need to be clear that the type of the
3795 // referent for the reference that results is *equal to* the
3796 // type of the lvalue it is referencing, and not some
3797 // supertype thereof.
3798 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3799 let init_ty = fcx.expr_ty(init);
3800 demand::eqtype(fcx, init.span, init_ty, local_ty);
3802 check_expr_coercable_to_type(fcx, init, local_ty)
3806 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local) {
3807 let tcx = fcx.ccx.tcx;
3809 let t = fcx.local_ty(local.span, local.id);
3810 fcx.write_ty(local.id, t);
3812 if let Some(ref init) = local.init {
3813 check_decl_initializer(fcx, local, &**init);
3814 let init_ty = fcx.expr_ty(&**init);
3815 if init_ty.references_error() {
3816 fcx.write_ty(local.id, init_ty);
3820 let pcx = pat_ctxt {
3822 map: pat_id_map(&tcx.def_map, &*local.pat),
3824 _match::check_pat(&pcx, &*local.pat, t);
3825 let pat_ty = fcx.node_ty(local.pat.id);
3826 if pat_ty.references_error() {
3827 fcx.write_ty(local.id, pat_ty);
3831 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
3833 let mut saw_bot = false;
3834 let mut saw_err = false;
3836 ast::StmtDecl(ref decl, id) => {
3839 ast::DeclLocal(ref l) => {
3840 check_decl_local(fcx, &**l);
3841 let l_t = fcx.node_ty(l.id);
3842 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3843 saw_err = saw_err || l_t.references_error();
3845 ast::DeclItem(_) => {/* ignore for now */ }
3848 ast::StmtExpr(ref expr, id) => {
3850 // Check with expected type of ()
3851 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3852 let expr_ty = fcx.expr_ty(&**expr);
3853 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3854 saw_err = saw_err || expr_ty.references_error();
3856 ast::StmtSemi(ref expr, id) => {
3858 check_expr(fcx, &**expr);
3859 let expr_ty = fcx.expr_ty(&**expr);
3860 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3861 saw_err |= expr_ty.references_error();
3863 ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro")
3866 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3869 fcx.write_error(node_id);
3872 fcx.write_nil(node_id)
3876 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) {
3877 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3878 let blkty = fcx.node_ty(blk.id);
3879 if blkty.references_error() {
3880 fcx.write_error(blk.id);
3882 let nilty = fcx.tcx().mk_nil();
3883 demand::suptype(fcx, blk.span, nilty, blkty);
3887 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3888 blk: &'tcx ast::Block,
3889 expected: Expectation<'tcx>) {
3891 let mut fcx_ps = fcx.ps.borrow_mut();
3892 let unsafety_state = fcx_ps.recurse(blk);
3893 replace(&mut *fcx_ps, unsafety_state)
3896 let mut warned = false;
3897 let mut any_diverges = false;
3898 let mut any_err = false;
3899 for s in &blk.stmts {
3900 check_stmt(fcx, &**s);
3901 let s_id = ast_util::stmt_id(&**s);
3902 let s_ty = fcx.node_ty(s_id);
3903 if any_diverges && !warned && match s.node {
3904 ast::StmtDecl(ref decl, _) => {
3906 ast::DeclLocal(_) => true,
3910 ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
3916 .add_lint(lint::builtin::UNREACHABLE_CODE,
3919 "unreachable statement".to_string());
3922 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3923 any_err = any_err || s_ty.references_error();
3926 None => if any_err {
3927 fcx.write_error(blk.id);
3928 } else if any_diverges {
3929 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3931 fcx.write_nil(blk.id);
3934 if any_diverges && !warned {
3938 .add_lint(lint::builtin::UNREACHABLE_CODE,
3941 "unreachable expression".to_string());
3943 let ety = match expected {
3944 ExpectHasType(ety) => {
3945 check_expr_coercable_to_type(fcx, &**e, ety);
3949 check_expr_with_expectation(fcx, &**e, expected);
3955 fcx.write_error(blk.id);
3956 } else if any_diverges {
3957 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3959 fcx.write_ty(blk.id, ety);
3964 *fcx.ps.borrow_mut() = prev;
3967 /// Checks a constant appearing in a type. At the moment this is just the
3968 /// length expression in a fixed-length vector, but someday it might be
3969 /// extended to type-level numeric literals.
3970 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3971 expr: &'tcx ast::Expr,
3972 expected_type: Ty<'tcx>) {
3973 let tables = RefCell::new(ty::Tables::empty());
3974 let inh = static_inherited_fields(ccx, &tables);
3975 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3976 check_const_with_ty(&fcx, expr.span, expr, expected_type);
3979 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3983 let tables = RefCell::new(ty::Tables::empty());
3984 let inh = static_inherited_fields(ccx, &tables);
3985 let rty = ccx.tcx.node_id_to_type(id);
3986 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
3987 let declty = fcx.ccx.tcx.lookup_item_type(local_def(id)).ty;
3988 check_const_with_ty(&fcx, sp, e, declty);
3991 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3995 // Gather locals in statics (because of block expressions).
3996 // This is technically unnecessary because locals in static items are forbidden,
3997 // but prevents type checking from blowing up before const checking can properly
3999 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4001 check_expr_with_hint(fcx, e, declty);
4002 demand::coerce(fcx, e.span, declty, e);
4003 fcx.select_all_obligations_or_error();
4005 regionck::regionck_expr(fcx, e);
4006 writeback::resolve_type_vars_in_expr(fcx, e);
4009 /// Checks whether a type can be represented in memory. In particular, it
4010 /// identifies types that contain themselves without indirection through a
4011 /// pointer, which would mean their size is unbounded. This is different from
4012 /// the question of whether a type can be instantiated. See the definition of
4013 /// `check_instantiable`.
4014 pub fn check_representable(tcx: &ty::ctxt,
4016 item_id: ast::NodeId,
4017 designation: &str) -> bool {
4018 let rty = tcx.node_id_to_type(item_id);
4020 // Check that it is possible to represent this type. This call identifies
4021 // (1) types that contain themselves and (2) types that contain a different
4022 // recursive type. It is only necessary to throw an error on those that
4023 // contain themselves. For case 2, there must be an inner type that will be
4024 // caught by case 1.
4025 match rty.is_representable(tcx, sp) {
4026 ty::SelfRecursive => {
4027 span_err!(tcx.sess, sp, E0072,
4028 "illegal recursive {} type; \
4029 wrap the inner value in a box to make it representable",
4033 ty::Representable | ty::ContainsRecursive => (),
4038 /// Checks whether a type can be created without an instance of itself.
4039 /// This is similar but different from the question of whether a type
4040 /// can be represented. For example, the following type:
4042 /// enum foo { None, Some(foo) }
4044 /// is instantiable but is not representable. Similarly, the type
4046 /// enum foo { Some(@foo) }
4048 /// is representable, but not instantiable.
4049 pub fn check_instantiable(tcx: &ty::ctxt,
4051 item_id: ast::NodeId)
4053 let item_ty = tcx.node_id_to_type(item_id);
4054 if !item_ty.is_instantiable(tcx) {
4055 span_err!(tcx.sess, sp, E0073,
4056 "this type cannot be instantiated without an \
4057 instance of itself");
4058 fileline_help!(tcx.sess, sp, "consider using `Option<{:?}>`",
4066 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4067 let t = tcx.node_id_to_type(id);
4068 if t.needs_subst() {
4069 span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
4073 ty::TyStruct(did, substs) => {
4074 let fields = tcx.lookup_struct_fields(did);
4075 if fields.is_empty() {
4076 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4079 let e = tcx.lookup_field_type(did, fields[0].id, substs);
4080 if !fields.iter().all(
4081 |f| tcx.lookup_field_type(did, f.id, substs) == e) {
4082 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4085 if !e.is_machine() {
4086 span_err!(tcx.sess, sp, E0077,
4087 "SIMD vector element type should be machine type");
4095 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4097 vs: &'tcx [P<ast::Variant>],
4100 fn disr_in_range(ccx: &CrateCtxt,
4102 disr: ty::Disr) -> bool {
4103 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4105 ast::TyU8 => disr as u8 as Disr == disr,
4106 ast::TyU16 => disr as u16 as Disr == disr,
4107 ast::TyU32 => disr as u32 as Disr == disr,
4108 ast::TyU64 => disr as u64 as Disr == disr,
4109 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4112 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4114 ast::TyI8 => disr as i8 as Disr == disr,
4115 ast::TyI16 => disr as i16 as Disr == disr,
4116 ast::TyI32 => disr as i32 as Disr == disr,
4117 ast::TyI64 => disr as i64 as Disr == disr,
4118 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4122 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4123 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4127 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4128 vs: &'tcx [P<ast::Variant>],
4130 hint: attr::ReprAttr) {
4131 #![allow(trivial_numeric_casts)]
4133 let rty = ccx.tcx.node_id_to_type(id);
4134 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4136 let tables = RefCell::new(ty::Tables::empty());
4137 let inh = static_inherited_fields(ccx, &tables);
4138 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4140 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4142 if let Some(ref e) = v.node.disr_expr {
4143 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4147 let def_id = local_def(id);
4149 // ty::enum_variants guards against discriminant overflows, so
4150 // we need not check for that.
4151 let variants = ccx.tcx.enum_variants(def_id);
4153 for (v, variant) in vs.iter().zip(variants.iter()) {
4154 let current_disr_val = variant.disr_val;
4156 // Check for duplicate discriminant values
4157 match disr_vals.iter().position(|&x| x == current_disr_val) {
4159 span_err!(ccx.tcx.sess, v.span, E0081,
4160 "discriminant value `{}` already exists", disr_vals[i]);
4161 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variants[i].id.node),
4162 "conflicting discriminant here")
4166 // Check for unrepresentable discriminant values
4168 attr::ReprAny | attr::ReprExtern => (),
4169 attr::ReprInt(sp, ity) => {
4170 if !disr_in_range(ccx, ity, current_disr_val) {
4171 span_err!(ccx.tcx.sess, v.span, E0082,
4172 "discriminant value outside specified type");
4173 span_note!(ccx.tcx.sess, sp,
4174 "discriminant type specified here");
4177 attr::ReprPacked => {
4178 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4181 disr_vals.push(current_disr_val);
4185 let hint = *ccx.tcx.lookup_repr_hints(ast::DefId { krate: ast::LOCAL_CRATE, node: id })
4186 .get(0).unwrap_or(&attr::ReprAny);
4188 if hint != attr::ReprAny && vs.len() <= 1 {
4190 span_err!(ccx.tcx.sess, sp, E0083,
4191 "unsupported representation for univariant enum");
4193 span_err!(ccx.tcx.sess, sp, E0084,
4194 "unsupported representation for zero-variant enum");
4198 do_check(ccx, vs, id, hint);
4200 check_representable(ccx.tcx, sp, id, "enum");
4202 // Check that it is possible to instantiate this enum:
4204 // This *sounds* like the same that as representable, but it's
4205 // not. See def'n of `check_instantiable()` for details.
4206 check_instantiable(ccx.tcx, sp, id);
4209 // Returns the type parameter count and the type for the given definition.
4210 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4213 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4215 def::DefLocal(nid) | def::DefUpvar(nid, _) => {
4216 let typ = fcx.local_ty(sp, nid);
4217 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4218 ty::GenericPredicates::empty())
4220 def::DefFn(id, _) | def::DefMethod(id, _) |
4221 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4222 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
4223 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4227 def::DefAssociatedTy(..) |
4229 def::DefTyParam(..) |
4231 def::DefForeignMod(..) |
4233 def::DefRegion(..) |
4235 def::DefSelfTy(..) => {
4236 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4241 // Instantiates the given path, which must refer to an item with the given
4242 // number of type parameters and type.
4243 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4244 segments: &[ast::PathSegment],
4245 type_scheme: TypeScheme<'tcx>,
4246 type_predicates: &ty::GenericPredicates<'tcx>,
4247 opt_self_ty: Option<Ty<'tcx>>,
4250 node_id: ast::NodeId) {
4251 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4257 // We need to extract the type parameters supplied by the user in
4258 // the path `path`. Due to the current setup, this is a bit of a
4259 // tricky-process; the problem is that resolve only tells us the
4260 // end-point of the path resolution, and not the intermediate steps.
4261 // Luckily, we can (at least for now) deduce the intermediate steps
4262 // just from the end-point.
4264 // There are basically four cases to consider:
4266 // 1. Reference to a *type*, such as a struct or enum:
4268 // mod a { struct Foo<T> { ... } }
4270 // Because we don't allow types to be declared within one
4271 // another, a path that leads to a type will always look like
4272 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4273 // that only the final segment can have type parameters, and
4274 // they are located in the TypeSpace.
4276 // *Note:* Generally speaking, references to types don't
4277 // actually pass through this function, but rather the
4278 // `ast_ty_to_ty` function in `astconv`. However, in the case
4279 // of struct patterns (and maybe literals) we do invoke
4280 // `instantiate_path` to get the general type of an instance of
4281 // a struct. (In these cases, there are actually no type
4282 // parameters permitted at present, but perhaps we will allow
4283 // them in the future.)
4285 // 1b. Reference to a enum variant or tuple-like struct:
4287 // struct foo<T>(...)
4288 // enum E<T> { foo(...) }
4290 // In these cases, the parameters are declared in the type
4293 // 2. Reference to a *fn item*:
4297 // In this case, the path will again always have the form
4298 // `a::b::foo::<T>` where only the final segment should have
4299 // type parameters. However, in this case, those parameters are
4300 // declared on a value, and hence are in the `FnSpace`.
4302 // 3. Reference to a *method*:
4304 // impl<A> SomeStruct<A> {
4308 // Here we can have a path like
4309 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4310 // may appear in two places. The penultimate segment,
4311 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4312 // final segment, `foo::<B>` contains parameters in fn space.
4314 // 4. Reference to an *associated const*:
4316 // impl<A> AnotherStruct<A> {
4317 // const FOO: B = BAR;
4320 // The path in this case will look like
4321 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4322 // only will have parameters in TypeSpace.
4324 // The first step then is to categorize the segments appropriately.
4326 assert!(!segments.is_empty());
4328 let mut ufcs_method = None;
4329 let mut segment_spaces: Vec<_>;
4331 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4332 def::DefSelfTy(..) |
4333 def::DefStruct(..) |
4334 def::DefVariant(..) |
4336 def::DefAssociatedTy(..) |
4338 def::DefPrimTy(..) |
4339 def::DefTyParam(..) => {
4340 // Everything but the final segment should have no
4341 // parameters at all.
4342 segment_spaces = vec![None; segments.len() - 1];
4343 segment_spaces.push(Some(subst::TypeSpace));
4346 // Case 2. Reference to a top-level value.
4349 def::DefStatic(..) => {
4350 segment_spaces = vec![None; segments.len() - 1];
4351 segment_spaces.push(Some(subst::FnSpace));
4354 // Case 3. Reference to a method.
4355 def::DefMethod(_, provenance) => {
4357 def::FromTrait(trait_did) => {
4358 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4360 def::FromImpl(_) => {}
4363 if segments.len() >= 2 {
4364 segment_spaces = vec![None; segments.len() - 2];
4365 segment_spaces.push(Some(subst::TypeSpace));
4366 segment_spaces.push(Some(subst::FnSpace));
4368 // `<T>::method` will end up here, and so can `T::method`.
4369 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4370 segment_spaces = vec![Some(subst::FnSpace)];
4371 ufcs_method = Some((provenance, self_ty));
4375 def::DefAssociatedConst(_, provenance) => {
4377 def::FromTrait(trait_did) => {
4378 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4380 def::FromImpl(_) => {}
4383 if segments.len() >= 2 {
4384 segment_spaces = vec![None; segments.len() - 2];
4385 segment_spaces.push(Some(subst::TypeSpace));
4386 segment_spaces.push(None);
4388 segment_spaces = vec![None];
4392 // Other cases. Various nonsense that really shouldn't show up
4393 // here. If they do, an error will have been reported
4394 // elsewhere. (I hope)
4396 def::DefForeignMod(..) |
4399 def::DefRegion(..) |
4401 def::DefUpvar(..) => {
4402 segment_spaces = vec![None; segments.len()];
4405 assert_eq!(segment_spaces.len(), segments.len());
4407 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4408 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4409 // type parameters are not mandatory.
4410 let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
4412 debug!("segment_spaces={:?}", segment_spaces);
4414 // Next, examine the definition, and determine how many type
4415 // parameters we expect from each space.
4416 let type_defs = &type_scheme.generics.types;
4417 let region_defs = &type_scheme.generics.regions;
4419 // Now that we have categorized what space the parameters for each
4420 // segment belong to, let's sort out the parameters that the user
4421 // provided (if any) into their appropriate spaces. We'll also report
4422 // errors if type parameters are provided in an inappropriate place.
4423 let mut substs = Substs::empty();
4424 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4427 check_path_args(fcx.tcx(), slice::ref_slice(segment),
4428 NO_TPS | NO_REGIONS);
4432 push_explicit_parameters_from_segment_to_substs(fcx,
4442 if let Some(self_ty) = opt_self_ty {
4443 if type_defs.len(subst::SelfSpace) == 1 {
4444 substs.types.push(subst::SelfSpace, self_ty);
4448 // Now we have to compare the types that the user *actually*
4449 // provided against the types that were *expected*. If the user
4450 // did not provide any types, then we want to substitute inference
4451 // variables. If the user provided some types, we may still need
4452 // to add defaults. If the user provided *too many* types, that's
4454 for &space in &ParamSpace::all() {
4455 adjust_type_parameters(fcx, span, space, type_defs,
4456 require_type_space, &mut substs);
4457 assert_eq!(substs.types.len(space), type_defs.len(space));
4459 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4460 assert_eq!(substs.regions().len(space), region_defs.len(space));
4463 // The things we are substituting into the type should not contain
4464 // escaping late-bound regions, and nor should the base type scheme.
4465 assert!(!substs.has_regions_escaping_depth(0));
4466 assert!(!type_scheme.has_escaping_regions());
4468 // Add all the obligations that are required, substituting and
4469 // normalized appropriately.
4470 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4471 fcx.add_obligations_for_parameters(
4472 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4475 // Substitute the values for the type parameters into the type of
4476 // the referenced item.
4477 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4480 if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
4481 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4482 // is inherent, there is no `Self` parameter, instead, the impl needs
4483 // type parameters, which we can infer by unifying the provided `Self`
4484 // with the substituted impl type.
4485 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4486 assert_eq!(substs.types.len(subst::TypeSpace),
4487 impl_scheme.generics.types.len(subst::TypeSpace));
4488 assert_eq!(substs.regions().len(subst::TypeSpace),
4489 impl_scheme.generics.regions.len(subst::TypeSpace));
4491 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4492 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4493 fcx.tcx().sess.span_bug(span,
4495 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4501 fcx.write_ty(node_id, ty_substituted);
4502 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4505 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4506 /// parameters are provided, then reports an error and clears the output vector.
4508 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4509 /// use inference variables. This seems less likely to lead to derived errors.
4511 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4512 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4513 /// here because we can easily use the precise span of the N+1'th parameter.
4514 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4515 fcx: &FnCtxt<'a, 'tcx>,
4516 space: subst::ParamSpace,
4518 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4519 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4520 segment: &ast::PathSegment,
4521 substs: &mut Substs<'tcx>)
4523 match segment.parameters {
4524 ast::AngleBracketedParameters(ref data) => {
4525 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4526 fcx, space, type_defs, region_defs, data, substs);
4529 ast::ParenthesizedParameters(ref data) => {
4530 span_err!(fcx.tcx().sess, span, E0238,
4531 "parenthesized parameters may only be used with a trait");
4532 push_explicit_parenthesized_parameters_from_segment_to_substs(
4533 fcx, space, span, type_defs, data, substs);
4538 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4539 fcx: &FnCtxt<'a, 'tcx>,
4540 space: subst::ParamSpace,
4541 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4542 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4543 data: &ast::AngleBracketedParameterData,
4544 substs: &mut Substs<'tcx>)
4547 let type_count = type_defs.len(space);
4548 assert_eq!(substs.types.len(space), 0);
4549 for (i, typ) in data.types.iter().enumerate() {
4550 let t = fcx.to_ty(&**typ);
4552 substs.types.push(space, t);
4553 } else if i == type_count {
4554 span_err!(fcx.tcx().sess, typ.span, E0087,
4555 "too many type parameters provided: \
4556 expected at most {} parameter{}, \
4557 found {} parameter{}",
4559 if type_count == 1 {""} else {"s"},
4561 if data.types.len() == 1 {""} else {"s"});
4562 substs.types.truncate(space, 0);
4568 if !data.bindings.is_empty() {
4569 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4570 "unexpected binding of associated item in expression path \
4571 (only allowed in type paths)");
4575 let region_count = region_defs.len(space);
4576 assert_eq!(substs.regions().len(space), 0);
4577 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4578 let r = ast_region_to_region(fcx.tcx(), lifetime);
4579 if i < region_count {
4580 substs.mut_regions().push(space, r);
4581 } else if i == region_count {
4582 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4583 "too many lifetime parameters provided: \
4584 expected {} parameter{}, found {} parameter{}",
4586 if region_count == 1 {""} else {"s"},
4587 data.lifetimes.len(),
4588 if data.lifetimes.len() == 1 {""} else {"s"});
4589 substs.mut_regions().truncate(space, 0);
4597 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4598 /// but intended for `Foo(A,B) -> C` form. This expands to
4599 /// roughly the same thing as `Foo<(A,B),C>`. One important
4600 /// difference has to do with the treatment of anonymous
4601 /// regions, which are translated into bound regions (NYI).
4602 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4603 fcx: &FnCtxt<'a, 'tcx>,
4604 space: subst::ParamSpace,
4606 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4607 data: &ast::ParenthesizedParameterData,
4608 substs: &mut Substs<'tcx>)
4610 let type_count = type_defs.len(space);
4612 span_err!(fcx.tcx().sess, span, E0167,
4613 "parenthesized form always supplies 2 type parameters, \
4614 but only {} parameter(s) were expected",
4618 let input_tys: Vec<Ty> =
4619 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4621 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4623 if type_count >= 1 {
4624 substs.types.push(space, tuple_ty);
4627 let output_ty: Option<Ty> =
4628 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4631 output_ty.unwrap_or(fcx.tcx().mk_nil());
4633 if type_count >= 2 {
4634 substs.types.push(space, output_ty);
4638 fn adjust_type_parameters<'a, 'tcx>(
4639 fcx: &FnCtxt<'a, 'tcx>,
4642 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4643 require_type_space: bool,
4644 substs: &mut Substs<'tcx>)
4646 let provided_len = substs.types.len(space);
4647 let desired = defs.get_slice(space);
4648 let required_len = desired.iter()
4649 .take_while(|d| d.default.is_none())
4652 debug!("adjust_type_parameters(space={:?}, \
4661 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4662 assert!(provided_len <= desired.len());
4664 // Nothing specified at all: supply inference variables for
4666 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4667 substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
4671 // Too few parameters specified: report an error and use Err
4673 if provided_len < required_len {
4675 if desired.len() != required_len { "at least " } else { "" };
4676 span_err!(fcx.tcx().sess, span, E0089,
4677 "too few type parameters provided: expected {}{} parameter{}, \
4678 found {} parameter{}",
4679 qualifier, required_len,
4680 if required_len == 1 {""} else {"s"},
4682 if provided_len == 1 {""} else {"s"});
4683 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4687 // Otherwise, add in any optional parameters that the user
4688 // omitted. The case of *too many* parameters is handled
4690 // push_explicit_parameters_from_segment_to_substs(). Note
4691 // that the *default* type are expressed in terms of all prior
4692 // parameters, so we have to substitute as we go with the
4693 // partial substitution that we have built up.
4694 for i in provided_len..desired.len() {
4695 let default = desired[i].default.unwrap();
4696 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4697 substs.types.push(space, default);
4699 assert_eq!(substs.types.len(space), desired.len());
4701 debug!("Final substs: {:?}", substs);
4704 fn adjust_region_parameters(
4708 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4709 substs: &mut Substs)
4711 let provided_len = substs.mut_regions().len(space);
4712 let desired = defs.get_slice(space);
4714 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4715 assert!(provided_len <= desired.len());
4717 // If nothing was provided, just use inference variables.
4718 if provided_len == 0 {
4719 substs.mut_regions().replace(
4721 fcx.infcx().region_vars_for_defs(span, desired));
4725 // If just the right number were provided, everybody is happy.
4726 if provided_len == desired.len() {
4730 // Otherwise, too few were provided. Report an error and then
4731 // use inference variables.
4732 span_err!(fcx.tcx().sess, span, E0090,
4733 "too few lifetime parameters provided: expected {} parameter{}, \
4734 found {} parameter{}",
4736 if desired.len() == 1 {""} else {"s"},
4738 if provided_len == 1 {""} else {"s"});
4740 substs.mut_regions().replace(
4742 fcx.infcx().region_vars_for_defs(span, desired));
4746 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4750 where F: Fn() -> Ty<'tcx>
4752 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4755 let alternative = f();
4758 if alternative.is_ty_var() || alternative.references_error() {
4759 fcx.type_error_message(sp, |_actual| {
4760 "the type of this value must be known in this context".to_string()
4762 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4763 ty = fcx.tcx().types.err;
4765 demand::suptype(fcx, sp, alternative, ty);
4773 // Resolves `typ` by a single level if `typ` is a type variable. If no
4774 // resolution is possible, then an error is reported.
4775 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4780 structurally_resolve_type_or_else(fcx, sp, ty, || {
4785 // Returns true if b contains a break that can exit from b
4786 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
4787 // First: is there an unlabeled break immediately
4789 (loop_query(&*b, |e| {
4791 ast::ExprBreak(None) => true,
4795 // Second: is there a labeled break with label
4796 // <id> nested anywhere inside the loop?
4797 (block_query(b, |e| {
4798 if let ast::ExprBreak(Some(_)) = e.node {
4799 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4806 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4808 tps: &OwnedSlice<ast::TyParam>,
4810 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4813 // make a vector of booleans initially false, set to true when used
4814 if tps.is_empty() { return; }
4815 let mut tps_used = vec![false; tps.len()];
4817 for leaf_ty in ty.walk() {
4818 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4819 debug!("Found use of ty param num {}", idx);
4820 tps_used[idx as usize] = true;
4824 for (i, b) in tps_used.iter().enumerate() {
4826 span_err!(ccx.tcx.sess, span, E0091,
4827 "type parameter `{}` is unused",
4828 token::get_ident(tps[i].ident));
4833 /// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
4834 /// and in libcore/intrinsics.rs
4835 pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
4836 fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
4837 let name = token::intern(&format!("P{}", n));
4838 ccx.tcx.mk_param(subst::FnSpace, n, name)
4842 let name = token::get_ident(it.ident);
4843 let (n_tps, inputs, output) = if name.starts_with("atomic_") {
4844 let split : Vec<&str> = name.split('_').collect();
4845 assert!(split.len() >= 2, "Atomic intrinsic not correct format");
4847 //We only care about the operation here
4848 let (n_tps, inputs, output) = match split[1] {
4849 "cxchg" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)),
4853 "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))),
4855 "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4858 "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" |
4859 "min" | "umax" | "umin" => {
4860 (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
4863 "fence" | "singlethreadfence" => {
4864 (0, Vec::new(), tcx.mk_nil())
4867 span_err!(tcx.sess, it.span, E0092,
4868 "unrecognized atomic operation function: `{}`", op);
4872 (n_tps, inputs, ty::FnConverging(output))
4873 } else if &name[..] == "abort" || &name[..] == "unreachable" {
4874 (0, Vec::new(), ty::FnDiverging)
4876 let (n_tps, inputs, output) = match &name[..] {
4877 "breakpoint" => (0, Vec::new(), tcx.mk_nil()),
4879 "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize),
4880 "size_of_val" | "min_align_of_val" => {
4882 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
4885 ], ccx.tcx.types.usize)
4887 "init" | "init_dropped" => (1, Vec::new(), param(ccx, 0)),
4888 "uninit" => (1, Vec::new(), param(ccx, 0)),
4889 "forget" => (1, vec!( param(ccx, 0) ), tcx.mk_nil()),
4890 "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)),
4891 "move_val_init" => {
4894 tcx.mk_mut_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
4901 "drop_in_place" => {
4902 (1, vec![tcx.mk_mut_ptr(param(ccx, 0))], tcx.mk_nil())
4904 "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool),
4906 "type_name" => (1, Vec::new(), tcx.mk_static_str()),
4907 "type_id" => (1, Vec::new(), ccx.tcx.types.u64),
4908 "offset" | "arith_offset" => {
4911 tcx.mk_ptr(ty::TypeAndMut {
4913 mutbl: ast::MutImmutable
4917 tcx.mk_ptr(ty::TypeAndMut {
4919 mutbl: ast::MutImmutable
4922 "copy" | "copy_nonoverlapping" => {
4925 tcx.mk_ptr(ty::TypeAndMut {
4927 mutbl: ast::MutImmutable
4929 tcx.mk_ptr(ty::TypeAndMut {
4931 mutbl: ast::MutMutable
4937 "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
4940 tcx.mk_ptr(ty::TypeAndMut {
4942 mutbl: ast::MutMutable
4944 tcx.mk_ptr(ty::TypeAndMut {
4946 mutbl: ast::MutImmutable
4952 "write_bytes" | "volatile_set_memory" => {
4955 tcx.mk_ptr(ty::TypeAndMut {
4957 mutbl: ast::MutMutable
4964 "sqrtf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4965 "sqrtf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4968 vec!( tcx.types.f32, tcx.types.i32 ),
4973 vec!( tcx.types.f64, tcx.types.i32 ),
4976 "sinf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4977 "sinf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4978 "cosf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4979 "cosf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4982 vec!( tcx.types.f32, tcx.types.f32 ),
4987 vec!( tcx.types.f64, tcx.types.f64 ),
4990 "expf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4991 "expf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4992 "exp2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4993 "exp2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4994 "logf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4995 "logf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4996 "log10f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4997 "log10f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
4998 "log2f32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
4999 "log2f64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5002 vec!( tcx.types.f32, tcx.types.f32, tcx.types.f32 ),
5007 vec!( tcx.types.f64, tcx.types.f64, tcx.types.f64 ),
5010 "fabsf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5011 "fabsf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5012 "copysignf32" => (0, vec!( tcx.types.f32, tcx.types.f32 ), tcx.types.f32),
5013 "copysignf64" => (0, vec!( tcx.types.f64, tcx.types.f64 ), tcx.types.f64),
5014 "floorf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5015 "floorf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5016 "ceilf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5017 "ceilf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5018 "truncf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5019 "truncf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5020 "rintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5021 "rintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5022 "nearbyintf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5023 "nearbyintf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5024 "roundf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32),
5025 "roundf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64),
5026 "ctpop8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5027 "ctpop16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5028 "ctpop32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5029 "ctpop64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5030 "ctlz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5031 "ctlz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5032 "ctlz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5033 "ctlz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5034 "cttz8" => (0, vec!( tcx.types.u8 ), tcx.types.u8),
5035 "cttz16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5036 "cttz32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5037 "cttz64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5038 "bswap16" => (0, vec!( tcx.types.u16 ), tcx.types.u16),
5039 "bswap32" => (0, vec!( tcx.types.u32 ), tcx.types.u32),
5040 "bswap64" => (0, vec!( tcx.types.u64 ), tcx.types.u64),
5043 (1, vec!( tcx.mk_imm_ptr(param(ccx, 0)) ), param(ccx, 0)),
5045 (1, vec!( tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ), tcx.mk_nil()),
5047 "i8_add_with_overflow" | "i8_sub_with_overflow" | "i8_mul_with_overflow" =>
5048 (0, vec!(tcx.types.i8, tcx.types.i8),
5049 tcx.mk_tup(vec!(tcx.types.i8, tcx.types.bool))),
5051 "i16_add_with_overflow" | "i16_sub_with_overflow" | "i16_mul_with_overflow" =>
5052 (0, vec!(tcx.types.i16, tcx.types.i16),
5053 tcx.mk_tup(vec!(tcx.types.i16, tcx.types.bool))),
5055 "i32_add_with_overflow" | "i32_sub_with_overflow" | "i32_mul_with_overflow" =>
5056 (0, vec!(tcx.types.i32, tcx.types.i32),
5057 tcx.mk_tup(vec!(tcx.types.i32, tcx.types.bool))),
5059 "i64_add_with_overflow" | "i64_sub_with_overflow" | "i64_mul_with_overflow" =>
5060 (0, vec!(tcx.types.i64, tcx.types.i64),
5061 tcx.mk_tup(vec!(tcx.types.i64, tcx.types.bool))),
5063 "u8_add_with_overflow" | "u8_sub_with_overflow" | "u8_mul_with_overflow" =>
5064 (0, vec!(tcx.types.u8, tcx.types.u8),
5065 tcx.mk_tup(vec!(tcx.types.u8, tcx.types.bool))),
5067 "u16_add_with_overflow" | "u16_sub_with_overflow" | "u16_mul_with_overflow" =>
5068 (0, vec!(tcx.types.u16, tcx.types.u16),
5069 tcx.mk_tup(vec!(tcx.types.u16, tcx.types.bool))),
5071 "u32_add_with_overflow" | "u32_sub_with_overflow" | "u32_mul_with_overflow"=>
5072 (0, vec!(tcx.types.u32, tcx.types.u32),
5073 tcx.mk_tup(vec!(tcx.types.u32, tcx.types.bool))),
5075 "u64_add_with_overflow" | "u64_sub_with_overflow" | "u64_mul_with_overflow" =>
5076 (0, vec!(tcx.types.u64, tcx.types.u64),
5077 tcx.mk_tup(vec!(tcx.types.u64, tcx.types.bool))),
5079 "unchecked_udiv" | "unchecked_sdiv" | "unchecked_urem" | "unchecked_srem" =>
5080 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5082 "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
5083 (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
5085 "return_address" => (0, vec![], tcx.mk_imm_ptr(tcx.types.u8)),
5087 "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()),
5089 "discriminant_value" => (1, vec![
5090 tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
5092 param(ccx, 0))], tcx.types.u64),
5095 span_err!(tcx.sess, it.span, E0093,
5096 "unrecognized intrinsic function: `{}`", *other);
5100 (n_tps, inputs, ty::FnConverging(output))
5102 let fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy {
5103 unsafety: ast::Unsafety::Unsafe,
5104 abi: abi::RustIntrinsic,
5105 sig: ty::Binder(FnSig {
5111 let i_ty = ccx.tcx.lookup_item_type(local_def(it.id));
5112 let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
5113 if i_n_tps != n_tps {
5114 span_err!(tcx.sess, it.span, E0094,
5115 "intrinsic has wrong number of type \
5116 parameters: found {}, expected {}",
5119 require_same_types(tcx,
5126 format!("intrinsic has wrong type: expected `{}`",