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::Expectation::*;
80 pub use self::compare_method::{compare_impl_method, compare_const_impl};
81 use self::TupleArgumentsFlag::*;
83 use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
84 use check::_match::pat_ctxt;
85 use dep_graph::DepNode;
86 use fmt_macros::{Parser, Piece, Position};
87 use middle::astconv_util::prohibit_type_params;
88 use middle::cstore::LOCAL_CRATE;
89 use middle::def::{self, Def};
90 use middle::def_id::DefId;
92 use middle::infer::{TypeOrigin, type_variable};
93 use middle::pat_util::{self, pat_id_map};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{GenericPredicates, TypeScheme};
97 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, ToPolyTraitRef, Ty, TyCtxt};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::util::Representability;
105 use require_c_abi_if_variadic;
106 use rscope::{ElisionFailureInfo, RegionScope};
107 use session::{Session, CompileResult};
108 use {CrateCtxt, lookup_full_def};
111 use util::common::{block_query, ErrorReported, indenter, loop_query};
112 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
114 use std::cell::{Cell, Ref, RefCell};
115 use std::collections::{HashSet};
116 use std::mem::replace;
117 use syntax::abi::Abi;
120 use syntax::attr::AttrMetaMethods;
121 use syntax::codemap::{self, Span, Spanned};
122 use syntax::errors::DiagnosticBuilder;
123 use syntax::parse::token::{self, InternedString, special_idents};
125 use syntax::util::lev_distance::find_best_match_for_name;
127 use rustc_front::intravisit::{self, Visitor};
128 use rustc_front::hir;
129 use rustc_front::hir::{Visibility, PatKind};
130 use rustc_front::print::pprust;
131 use rustc_back::slice;
150 /// closures defined within the function. For example:
153 /// bar(move|| { ... })
156 /// Here, the function `foo()` and the closure passed to
157 /// `bar()` will each have their own `FnCtxt`, but they will
158 /// share the inherited fields.
159 pub struct Inherited<'a, 'tcx: 'a> {
160 infcx: infer::InferCtxt<'a, 'tcx>,
161 locals: RefCell<NodeMap<Ty<'tcx>>>,
163 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
165 tables: &'a RefCell<ty::Tables<'tcx>>,
167 // When we process a call like `c()` where `c` is a closure type,
168 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
169 // `FnOnce` closure. In that case, we defer full resolution of the
170 // call until upvar inference can kick in and make the
171 // decision. We keep these deferred resolutions grouped by the
172 // def-id of the closure, so that once we decide, we can easily go
173 // back and process them.
174 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
176 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
179 trait DeferredCallResolution<'tcx> {
180 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
183 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
185 /// When type-checking an expression, we propagate downward
186 /// whatever type hint we are able in the form of an `Expectation`.
187 #[derive(Copy, Clone, Debug)]
188 pub enum Expectation<'tcx> {
189 /// We know nothing about what type this expression should have.
192 /// This expression should have the type given (or some subtype)
193 ExpectHasType(Ty<'tcx>),
195 /// This expression will be cast to the `Ty`
196 ExpectCastableToType(Ty<'tcx>),
198 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
199 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
200 ExpectRvalueLikeUnsized(Ty<'tcx>),
203 impl<'tcx> Expectation<'tcx> {
204 // Disregard "castable to" expectations because they
205 // can lead us astray. Consider for example `if cond
206 // {22} else {c} as u8` -- if we propagate the
207 // "castable to u8" constraint to 22, it will pick the
208 // type 22u8, which is overly constrained (c might not
209 // be a u8). In effect, the problem is that the
210 // "castable to" expectation is not the tightest thing
211 // we can say, so we want to drop it in this case.
212 // The tightest thing we can say is "must unify with
213 // else branch". Note that in the case of a "has type"
214 // constraint, this limitation does not hold.
216 // If the expected type is just a type variable, then don't use
217 // an expected type. Otherwise, we might write parts of the type
218 // when checking the 'then' block which are incompatible with the
220 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
222 ExpectHasType(ety) => {
223 let ety = fcx.infcx().shallow_resolve(ety);
224 if !ety.is_ty_var() {
230 ExpectRvalueLikeUnsized(ety) => {
231 ExpectRvalueLikeUnsized(ety)
238 #[derive(Copy, Clone)]
239 pub struct UnsafetyState {
240 pub def: ast::NodeId,
241 pub unsafety: hir::Unsafety,
242 pub unsafe_push_count: u32,
247 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
248 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
251 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
252 match self.unsafety {
253 // If this unsafe, then if the outer function was already marked as
254 // unsafe we shouldn't attribute the unsafe'ness to the block. This
255 // way the block can be warned about instead of ignoring this
256 // extraneous block (functions are never warned about).
257 hir::Unsafety::Unsafe if self.from_fn => *self,
260 let (unsafety, def, count) = match blk.rules {
261 hir::PushUnsafeBlock(..) =>
262 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
263 hir::PopUnsafeBlock(..) =>
264 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
265 hir::UnsafeBlock(..) =>
266 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
267 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
268 (unsafety, self.def, self.unsafe_push_count),
270 UnsafetyState{ def: def,
272 unsafe_push_count: count,
280 pub struct FnCtxt<'a, 'tcx: 'a> {
281 body_id: ast::NodeId,
283 // This flag is set to true if, during the writeback phase, we encounter
284 // a type error in this function.
285 writeback_errors: Cell<bool>,
287 // Number of errors that had been reported when we started
288 // checking this function. On exit, if we find that *more* errors
289 // have been reported, we will skip regionck and other work that
290 // expects the types within the function to be consistent.
291 err_count_on_creation: usize,
293 ret_ty: ty::FnOutput<'tcx>,
295 ps: RefCell<UnsafetyState>,
297 inh: &'a Inherited<'a, 'tcx>,
299 ccx: &'a CrateCtxt<'a, 'tcx>,
302 impl<'a, 'tcx> Inherited<'a, 'tcx> {
303 fn new(tcx: &'a TyCtxt<'tcx>,
304 tables: &'a RefCell<ty::Tables<'tcx>>,
305 param_env: ty::ParameterEnvironment<'a, 'tcx>)
306 -> Inherited<'a, 'tcx> {
309 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
310 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
311 locals: RefCell::new(NodeMap()),
313 deferred_call_resolutions: RefCell::new(DefIdMap()),
314 deferred_cast_checks: RefCell::new(Vec::new()),
318 fn normalize_associated_types_in<T>(&self,
320 body_id: ast::NodeId,
323 where T : TypeFoldable<'tcx>
325 assoc::normalize_associated_types_in(&self.infcx,
326 &mut self.fulfillment_cx.borrow_mut(),
334 // Used by check_const and check_enum_variants
335 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
336 inh: &'a Inherited<'a, 'tcx>,
337 rty: ty::FnOutput<'tcx>,
338 body_id: ast::NodeId)
339 -> FnCtxt<'a, 'tcx> {
342 writeback_errors: Cell::new(false),
343 err_count_on_creation: ccx.tcx.sess.err_count(),
345 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
351 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
352 tables: &'a RefCell<ty::Tables<'tcx>>)
353 -> Inherited<'a, 'tcx> {
354 // It's kind of a kludge to manufacture a fake function context
355 // and statement context, but we might as well do write the code only once
356 let param_env = ccx.tcx.empty_parameter_environment();
357 Inherited::new(ccx.tcx, &tables, param_env)
360 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
361 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
363 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
364 fn visit_item(&mut self, i: &'tcx hir::Item) {
365 check_item_type(self.ccx, i);
366 intravisit::walk_item(self, i);
369 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
371 hir::TyFixedLengthVec(_, ref expr) => {
372 check_const_in_type(self.ccx, &expr, self.ccx.tcx.types.usize);
377 intravisit::walk_ty(self, t);
381 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
382 fn visit_item(&mut self, i: &'tcx hir::Item) {
383 check_item_body(self.ccx, i);
387 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
388 ccx.tcx.sess.track_errors(|| {
389 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
390 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
394 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
395 ccx.tcx.sess.track_errors(|| {
396 let mut visit = CheckItemTypesVisitor { ccx: ccx };
397 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
401 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
402 ccx.tcx.sess.track_errors(|| {
403 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
404 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
408 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
409 ccx.tcx.sess.track_errors(|| {
410 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
411 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
412 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
414 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
415 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
416 if drop_impl_did.is_local() {
417 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
420 assert!(ccx.tcx.sess.has_errors());
428 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
429 decl: &'tcx hir::FnDecl,
430 body: &'tcx hir::Block,
434 param_env: ty::ParameterEnvironment<'a, 'tcx>)
437 ty::TyFnDef(_, _, ref fn_ty) => {
438 let tables = RefCell::new(ty::Tables::empty());
439 let inh = Inherited::new(ccx.tcx, &tables, param_env);
441 // Compute the fty from point of view of inside fn.
442 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
444 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
446 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
448 inh.normalize_associated_types_in(body.span,
452 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
453 decl, fn_id, body, &inh);
455 fcx.select_all_obligations_and_apply_defaults();
456 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
457 fcx.select_obligations_where_possible();
459 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
461 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
462 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
464 _ => ccx.tcx.sess.impossible_case(body.span,
465 "check_bare_fn: function type expected")
469 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
470 fcx: &'a FnCtxt<'a, 'tcx>
473 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
474 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
477 // infer the variable's type
478 let var_ty = self.fcx.infcx().next_ty_var();
479 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
483 // take type that the user specified
484 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
491 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
492 // Add explicitly-declared locals.
493 fn visit_local(&mut self, local: &'tcx hir::Local) {
494 let o_ty = match local.ty {
495 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
498 self.assign(local.span, local.id, o_ty);
499 debug!("Local variable {:?} is assigned type {}",
501 self.fcx.infcx().ty_to_string(
502 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
503 intravisit::walk_local(self, local);
506 // Add pattern bindings.
507 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
508 if let PatKind::Ident(_, ref path1, _) = p.node {
509 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
510 let var_ty = self.assign(p.span, p.id, None);
512 self.fcx.require_type_is_sized(var_ty, p.span,
513 traits::VariableType(p.id));
515 debug!("Pattern binding {} is assigned to {} with type {:?}",
517 self.fcx.infcx().ty_to_string(
518 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
522 intravisit::walk_pat(self, p);
525 fn visit_block(&mut self, b: &'tcx hir::Block) {
526 // non-obvious: the `blk` variable maps to region lb, so
527 // we have to keep this up-to-date. This
528 // is... unfortunate. It'd be nice to not need this.
529 intravisit::walk_block(self, b);
532 // Since an expr occurs as part of the type fixed size arrays we
533 // need to record the type for that node
534 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
536 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
538 check_expr_with_hint(self.fcx, &count_expr, self.fcx.tcx().types.usize);
540 hir::TyBareFn(ref function_declaration) => {
541 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
542 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
544 _ => intravisit::walk_ty(self, t)
548 // Don't descend into the bodies of nested closures
549 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
550 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
553 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
554 /// body and returns the function context used for that purpose, since in the case of a fn item
555 /// there is still a bit more to do.
558 /// * inherited: other fields inherited from the enclosing fn (if any)
559 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
560 unsafety: hir::Unsafety,
561 unsafety_id: ast::NodeId,
562 fn_sig: &ty::FnSig<'tcx>,
563 decl: &'tcx hir::FnDecl,
565 body: &'tcx hir::Block,
566 inherited: &'a Inherited<'a, 'tcx>)
570 let err_count_on_creation = tcx.sess.err_count();
572 let arg_tys = &fn_sig.inputs;
573 let ret_ty = fn_sig.output;
575 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
580 // Create the function context. This is either derived from scratch or,
581 // in the case of function expressions, based on the outer context.
584 writeback_errors: Cell::new(false),
585 err_count_on_creation: err_count_on_creation,
587 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
592 if let ty::FnConverging(ret_ty) = ret_ty {
593 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
596 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
598 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
601 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
603 // Add formal parameters.
604 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
605 // The type of the argument must be well-formed.
607 // NB -- this is now checked in wfcheck, but that
608 // currently only results in warnings, so we issue an
609 // old-style WF obligation here so that we still get the
610 // errors that we used to get.
611 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
613 // Create type variables for each argument.
614 pat_util::pat_bindings(
617 |_bm, pat_id, sp, _path| {
618 let var_ty = visit.assign(sp, pat_id, None);
619 fcx.require_type_is_sized(var_ty, sp,
620 traits::VariableType(pat_id));
623 // Check the pattern.
626 map: pat_id_map(&tcx.def_map, &input.pat),
628 _match::check_pat(&pcx, &input.pat, *arg_ty);
631 visit.visit_block(body);
634 check_block_with_expected(&fcx, body, match ret_ty {
635 ty::FnConverging(result_type) => ExpectHasType(result_type),
636 ty::FnDiverging => NoExpectation
639 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
640 fcx.write_ty(input.id, arg);
646 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
649 check_representable(tcx, span, id, "struct");
651 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
652 check_simd(tcx, span, id);
656 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
657 debug!("check_item_type(it.id={}, it.name={})",
659 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
660 let _indenter = indenter();
662 // Consts can play a role in type-checking, so they are included here.
663 hir::ItemStatic(_, _, ref e) |
664 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &e, it.id),
665 hir::ItemEnum(ref enum_definition, _) => {
666 check_enum_variants(ccx,
668 &enum_definition.variants,
671 hir::ItemFn(..) => {} // entirely within check_item_body
672 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
673 debug!("ItemImpl {} with id {}", it.name, it.id);
674 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
675 Some(impl_trait_ref) => {
676 check_impl_items_against_trait(ccx,
684 hir::ItemTrait(_, ref generics, _, _) => {
685 check_trait_on_unimplemented(ccx, generics, it);
687 hir::ItemStruct(..) => {
688 check_struct(ccx, it.id, it.span);
690 hir::ItemTy(_, ref generics) => {
691 let pty_ty = ccx.tcx.node_id_to_type(it.id);
692 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
694 hir::ItemForeignMod(ref m) => {
695 if m.abi == Abi::RustIntrinsic {
696 for item in &m.items {
697 intrinsic::check_intrinsic_type(ccx, item);
699 } else if m.abi == Abi::PlatformIntrinsic {
700 for item in &m.items {
701 intrinsic::check_platform_intrinsic_type(ccx, item);
704 for item in &m.items {
705 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
706 if !pty.generics.types.is_empty() {
707 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
708 "foreign items may not have type parameters");
709 span_help!(&mut err, item.span,
710 "consider using specialization instead of \
715 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
716 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
721 _ => {/* nothing to do */ }
725 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
726 debug!("check_item_body(it.id={}, it.name={})",
728 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
729 let _indenter = indenter();
731 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
732 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
733 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
734 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
736 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
737 debug!("ItemImpl {} with id {}", it.name, it.id);
739 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
741 for impl_item in impl_items {
742 match impl_item.node {
743 hir::ImplItemKind::Const(_, ref expr) => {
744 check_const(ccx, impl_item.span, &expr, impl_item.id)
746 hir::ImplItemKind::Method(ref sig, ref body) => {
747 check_method_body(ccx, &impl_pty.generics, sig, body,
748 impl_item.id, impl_item.span);
750 hir::ImplItemKind::Type(_) => {
751 // Nothing to do here.
756 hir::ItemTrait(_, _, _, ref trait_items) => {
757 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
758 for trait_item in trait_items {
759 match trait_item.node {
760 hir::ConstTraitItem(_, Some(ref expr)) => {
761 check_const(ccx, trait_item.span, &expr, trait_item.id)
763 hir::MethodTraitItem(ref sig, Some(ref body)) => {
764 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
766 check_method_body(ccx, &trait_def.generics, sig, body,
767 trait_item.id, trait_item.span);
769 hir::MethodTraitItem(ref sig, None) => {
770 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
772 hir::ConstTraitItem(_, None) |
773 hir::TypeTraitItem(..) => {
779 _ => {/* nothing to do */ }
783 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
785 constness: hir::Constness)
788 hir::Constness::NotConst => {
791 hir::Constness::Const => {
792 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
797 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
798 generics: &hir::Generics,
800 if let Some(ref attr) = item.attrs.iter().find(|a| {
801 a.check_name("rustc_on_unimplemented")
803 if let Some(ref istring) = attr.value_str() {
804 let parser = Parser::new(&istring);
805 let types = &generics.ty_params;
806 for token in parser {
808 Piece::String(_) => (), // Normal string, no need to check it
809 Piece::NextArgument(a) => match a.position {
810 // `{Self}` is allowed
811 Position::ArgumentNamed(s) if s == "Self" => (),
812 // So is `{A}` if A is a type parameter
813 Position::ArgumentNamed(s) => match types.iter().find(|t| {
818 span_err!(ccx.tcx.sess, attr.span, E0230,
819 "there is no type parameter \
824 // `{:1}` and `{}` are not to be used
825 Position::ArgumentIs(_) | Position::ArgumentNext => {
826 span_err!(ccx.tcx.sess, attr.span, E0231,
827 "only named substitution \
828 parameters are allowed");
834 span_err!(ccx.tcx.sess, attr.span, E0232,
835 "this attribute must have a value, \
836 eg `#[rustc_on_unimplemented = \"foo\"]`")
841 /// Type checks a method body.
845 /// * `item_generics`: generics defined on the impl/trait that contains
847 /// * `self_bound`: bound for the `Self` type parameter, if any
848 /// * `method`: the method definition
849 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
850 item_generics: &ty::Generics<'tcx>,
851 sig: &'tcx hir::MethodSig,
852 body: &'tcx hir::Block,
853 id: ast::NodeId, span: Span) {
854 debug!("check_method_body(item_generics={:?}, id={})",
856 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
858 let fty = ccx.tcx.node_id_to_type(id);
859 debug!("check_method_body: fty={:?}", fty);
861 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
864 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
866 impl_trait_ref: &ty::TraitRef<'tcx>,
867 impl_items: &[hir::ImplItem]) {
868 // Locate trait methods
870 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
871 let mut overridden_associated_type = None;
873 // Check existing impl methods to see if they are both present in trait
874 // and compatible with trait signature
875 for impl_item in impl_items {
876 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
877 let ty_trait_item = trait_items.iter()
878 .find(|ac| ac.name() == ty_impl_item.name());
880 if let Some(ty_trait_item) = ty_trait_item {
881 match impl_item.node {
882 hir::ImplItemKind::Const(..) => {
883 let impl_const = match ty_impl_item {
884 ty::ConstTraitItem(ref cti) => cti,
885 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
888 // Find associated const definition.
889 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
890 compare_const_impl(ccx.tcx,
896 span_err!(tcx.sess, impl_item.span, E0323,
897 "item `{}` is an associated const, \
898 which doesn't match its trait `{:?}`",
903 hir::ImplItemKind::Method(ref sig, ref body) => {
904 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
906 let impl_method = match ty_impl_item {
907 ty::MethodTraitItem(ref mti) => mti,
908 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
911 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
912 compare_impl_method(ccx.tcx,
919 span_err!(tcx.sess, impl_item.span, E0324,
920 "item `{}` is an associated method, \
921 which doesn't match its trait `{:?}`",
926 hir::ImplItemKind::Type(_) => {
927 let impl_type = match ty_impl_item {
928 ty::TypeTraitItem(ref tti) => tti,
929 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
932 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
933 if let Some(_) = at.ty {
934 overridden_associated_type = Some(impl_item);
937 span_err!(tcx.sess, impl_item.span, E0325,
938 "item `{}` is an associated type, \
939 which doesn't match its trait `{:?}`",
948 // Check for missing items from trait
949 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
950 let mut missing_items = Vec::new();
951 let mut invalidated_items = Vec::new();
952 let associated_type_overridden = overridden_associated_type.is_some();
953 for trait_item in trait_items.iter() {
955 ty::ConstTraitItem(ref associated_const) => {
956 let is_implemented = impl_items.iter().any(|ii| {
958 hir::ImplItemKind::Const(..) => {
959 ii.name == associated_const.name
964 let is_provided = associated_const.has_value;
968 missing_items.push(associated_const.name);
969 } else if associated_type_overridden {
970 invalidated_items.push(associated_const.name);
974 ty::MethodTraitItem(ref trait_method) => {
976 impl_items.iter().any(|ii| {
978 hir::ImplItemKind::Method(..) => {
979 ii.name == trait_method.name
985 provided_methods.iter().any(|m| m.name == trait_method.name);
988 missing_items.push(trait_method.name);
989 } else if associated_type_overridden {
990 invalidated_items.push(trait_method.name);
994 ty::TypeTraitItem(ref associated_type) => {
995 let is_implemented = impl_items.iter().any(|ii| {
997 hir::ImplItemKind::Type(_) => {
998 ii.name == associated_type.name
1003 let is_provided = associated_type.ty.is_some();
1004 if !is_implemented {
1006 missing_items.push(associated_type.name);
1007 } else if associated_type_overridden {
1008 invalidated_items.push(associated_type.name);
1015 if !missing_items.is_empty() {
1016 span_err!(tcx.sess, impl_span, E0046,
1017 "not all trait items implemented, missing: `{}`",
1018 missing_items.iter()
1019 .map(|name| name.to_string())
1020 .collect::<Vec<_>>().join("`, `"))
1023 if !invalidated_items.is_empty() {
1024 let invalidator = overridden_associated_type.unwrap();
1025 span_err!(tcx.sess, invalidator.span, E0399,
1026 "the following trait items need to be reimplemented \
1027 as `{}` was overridden: `{}`",
1029 invalidated_items.iter()
1030 .map(|name| name.to_string())
1031 .collect::<Vec<_>>().join("`, `"))
1035 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1042 if t_cast.references_error() || t_expr.references_error() {
1045 let tstr = fcx.infcx().ty_to_string(t_cast);
1046 let mut err = fcx.type_error_struct(span, |actual| {
1047 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1050 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1051 let mtstr = match mt {
1052 hir::MutMutable => "mut ",
1053 hir::MutImmutable => ""
1055 if t_cast.is_trait() {
1056 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1058 err.span_suggestion(t_span,
1059 "try casting to a reference instead:",
1060 format!("&{}{}", mtstr, s));
1063 span_help!(err, t_span,
1064 "did you mean `&{}{}`?", mtstr, tstr),
1067 span_help!(err, span,
1068 "consider using an implicit coercion to `&{}{}` instead",
1073 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1075 err.span_suggestion(t_span,
1076 "try casting to a `Box` instead:",
1077 format!("Box<{}>", s));
1080 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1084 span_help!(err, e_span,
1085 "consider using a box or reference as appropriate");
1089 fcx.write_error(id);
1093 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1094 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1096 fn get_item_type_scheme(&self, _: Span, id: DefId)
1097 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1099 Ok(self.tcx().lookup_item_type(id))
1102 fn get_trait_def(&self, _: Span, id: DefId)
1103 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1105 Ok(self.tcx().lookup_trait_def(id))
1108 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1109 // all super predicates are ensured during collect pass
1113 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1114 Some(&self.inh.infcx.parameter_environment.free_substs)
1117 fn get_type_parameter_bounds(&self,
1119 node_id: ast::NodeId)
1120 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1122 let def = self.tcx().type_parameter_def(node_id);
1123 let r = self.inh.infcx.parameter_environment
1126 .filter_map(|predicate| {
1128 ty::Predicate::Trait(ref data) => {
1129 if data.0.self_ty().is_param(def.space, def.index) {
1130 Some(data.to_poly_trait_ref())
1144 fn trait_defines_associated_type_named(&self,
1145 trait_def_id: DefId,
1146 assoc_name: ast::Name)
1149 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1150 trait_def.associated_type_names.contains(&assoc_name)
1154 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1155 substs: Option<&mut subst::Substs<'tcx>>,
1156 space: Option<subst::ParamSpace>,
1157 span: Span) -> Ty<'tcx> {
1158 // Grab the default doing subsitution
1159 let default = ty_param_def.and_then(|def| {
1160 def.default.map(|ty| type_variable::Default {
1161 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1163 def_id: def.default_def_id
1167 let ty_var = self.infcx().next_ty_var_with_default(default);
1169 // Finally we add the type variable to the substs
1172 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1176 fn projected_ty_from_poly_trait_ref(&self,
1178 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1179 item_name: ast::Name)
1182 let (trait_ref, _) =
1183 self.infcx().replace_late_bound_regions_with_fresh_var(
1185 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1188 self.normalize_associated_type(span, trait_ref, item_name)
1191 fn projected_ty(&self,
1193 trait_ref: ty::TraitRef<'tcx>,
1194 item_name: ast::Name)
1197 self.normalize_associated_type(span, trait_ref, item_name)
1201 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1202 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1204 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1208 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1209 &self.inh.infcx.parameter_environment
1212 pub fn sess(&self) -> &Session {
1216 pub fn err_count_since_creation(&self) -> usize {
1217 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1220 /// Resolves type variables in `ty` if possible. Unlike the infcx
1221 /// version, this version will also select obligations if it seems
1222 /// useful, in an effort to get more type information.
1223 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1224 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1226 // No TyInfer()? Nothing needs doing.
1227 if !ty.has_infer_types() {
1228 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1232 // If `ty` is a type variable, see whether we already know what it is.
1233 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1234 if !ty.has_infer_types() {
1235 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1239 // If not, try resolving pending obligations as much as
1240 // possible. This can help substantially when there are
1241 // indirect dependencies that don't seem worth tracking
1243 self.select_obligations_where_possible();
1244 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1246 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1250 fn record_deferred_call_resolution(&self,
1251 closure_def_id: DefId,
1252 r: DeferredCallResolutionHandler<'tcx>) {
1253 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1254 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1257 fn remove_deferred_call_resolutions(&self,
1258 closure_def_id: DefId)
1259 -> Vec<DeferredCallResolutionHandler<'tcx>>
1261 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1262 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1265 pub fn tag(&self) -> String {
1266 let self_ptr: *const FnCtxt = self;
1267 format!("{:?}", self_ptr)
1270 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1271 match self.inh.locals.borrow().get(&nid) {
1274 span_err!(self.tcx().sess, span, E0513,
1275 "no type for local variable {}",
1277 self.tcx().types.err
1283 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1284 debug!("write_ty({}, {:?}) in fcx {}",
1285 node_id, ty, self.tag());
1286 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1289 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1290 if !substs.substs.is_noop() {
1291 debug!("write_substs({}, {:?}) in fcx {}",
1296 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1300 pub fn write_autoderef_adjustment(&self,
1301 node_id: ast::NodeId,
1303 self.write_adjustment(
1305 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1313 pub fn write_adjustment(&self,
1314 node_id: ast::NodeId,
1315 adj: adjustment::AutoAdjustment<'tcx>) {
1316 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1318 if adj.is_identity() {
1322 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1325 /// Basically whenever we are converting from a type scheme into
1326 /// the fn body space, we always want to normalize associated
1327 /// types as well. This function combines the two.
1328 fn instantiate_type_scheme<T>(&self,
1330 substs: &Substs<'tcx>,
1333 where T : TypeFoldable<'tcx>
1335 let value = value.subst(self.tcx(), substs);
1336 let result = self.normalize_associated_types_in(span, &value);
1337 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1344 /// As `instantiate_type_scheme`, but for the bounds found in a
1345 /// generic type scheme.
1346 fn instantiate_bounds(&self,
1348 substs: &Substs<'tcx>,
1349 bounds: &ty::GenericPredicates<'tcx>)
1350 -> ty::InstantiatedPredicates<'tcx>
1352 ty::InstantiatedPredicates {
1353 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1358 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1359 where T : TypeFoldable<'tcx>
1361 self.inh.normalize_associated_types_in(span, self.body_id, value)
1364 fn normalize_associated_type(&self,
1366 trait_ref: ty::TraitRef<'tcx>,
1367 item_name: ast::Name)
1370 let cause = traits::ObligationCause::new(span,
1372 traits::ObligationCauseCode::MiscObligation);
1376 .normalize_projection_type(self.infcx(),
1378 trait_ref: trait_ref,
1379 item_name: item_name,
1384 /// Instantiates the type in `did` with the generics in `path` and returns
1385 /// it (registering the necessary trait obligations along the way).
1387 /// Note that this function is only intended to be used with type-paths,
1388 /// not with value-paths.
1389 pub fn instantiate_type(&self,
1394 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1396 self.tcx().lookup_item_type(did);
1397 let type_predicates =
1398 self.tcx().lookup_predicates(did);
1399 let substs = astconv::ast_path_substs_for_ty(self, self,
1401 PathParamMode::Optional,
1402 &type_scheme.generics,
1403 path.segments.last().unwrap());
1404 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1406 self.instantiate_bounds(path.span, &substs, &type_predicates);
1407 self.add_obligations_for_parameters(
1408 traits::ObligationCause::new(
1411 traits::ItemObligation(did)),
1414 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1417 /// Return the dict-like variant corresponding to a given `Def`.
1418 pub fn def_struct_variant(&self,
1421 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1423 let (adt, variant) = match def {
1424 Def::Variant(enum_id, variant_id) => {
1425 let adt = self.tcx().lookup_adt_def(enum_id);
1426 (adt, adt.variant_with_id(variant_id))
1428 Def::Struct(did) | Def::TyAlias(did) => {
1429 let typ = self.tcx().lookup_item_type(did);
1430 if let ty::TyStruct(adt, _) = typ.ty.sty {
1431 (adt, adt.struct_variant())
1439 let var_kind = variant.kind();
1440 if var_kind == ty::VariantKind::Struct {
1441 Some((adt, variant))
1442 } else if var_kind == ty::VariantKind::Unit {
1443 Some((adt, variant))
1449 pub fn write_nil(&self, node_id: ast::NodeId) {
1450 self.write_ty(node_id, self.tcx().mk_nil());
1452 pub fn write_error(&self, node_id: ast::NodeId) {
1453 self.write_ty(node_id, self.tcx().types.err);
1456 pub fn require_type_meets(&self,
1459 code: traits::ObligationCauseCode<'tcx>,
1460 bound: ty::BuiltinBound)
1462 self.register_builtin_bound(
1465 traits::ObligationCause::new(span, self.body_id, code));
1468 pub fn require_type_is_sized(&self,
1471 code: traits::ObligationCauseCode<'tcx>)
1473 self.require_type_meets(ty, span, code, ty::BoundSized);
1476 pub fn require_expr_have_sized_type(&self,
1478 code: traits::ObligationCauseCode<'tcx>)
1480 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1483 pub fn type_is_known_to_be_sized(&self,
1488 traits::type_known_to_meet_builtin_bound(self.infcx(),
1494 pub fn register_builtin_bound(&self,
1496 builtin_bound: ty::BuiltinBound,
1497 cause: traits::ObligationCause<'tcx>)
1499 self.inh.fulfillment_cx.borrow_mut()
1500 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1503 pub fn register_predicate(&self,
1504 obligation: traits::PredicateObligation<'tcx>)
1506 debug!("register_predicate({:?})",
1508 self.inh.fulfillment_cx
1510 .register_predicate_obligation(self.infcx(), obligation);
1513 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1514 let t = ast_ty_to_ty(self, self, ast_t);
1515 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1519 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1520 match self.inh.tables.borrow().node_types.get(&ex.id) {
1523 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1529 /// Apply `adjustment` to the type of `expr`
1530 pub fn adjust_expr_ty(&self,
1532 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1535 let raw_ty = self.expr_ty(expr);
1536 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1537 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1538 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1539 self.inh.tables.borrow().method_map.get(&method_call)
1540 .map(|method| resolve_ty(method.ty))
1544 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1545 match self.inh.tables.borrow().node_types.get(&id) {
1547 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1549 self.tcx().sess.bug(
1550 &format!("no type for node {}: {} in fcx {}",
1551 id, self.tcx().map.node_to_string(id),
1557 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1558 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1559 // it changes when we upgrade the snapshot compiler
1560 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1561 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1565 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1568 pub fn opt_node_ty_substs<F>(&self,
1571 F: FnOnce(&ty::ItemSubsts<'tcx>),
1573 match self.inh.tables.borrow().item_substs.get(&id) {
1579 pub fn mk_subty(&self,
1580 a_is_expected: bool,
1584 -> Result<(), TypeError<'tcx>> {
1585 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1588 pub fn mk_eqty(&self,
1589 a_is_expected: bool,
1593 -> Result<(), TypeError<'tcx>> {
1594 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1597 pub fn mk_subr(&self,
1598 origin: infer::SubregionOrigin<'tcx>,
1601 infer::mk_subr(self.infcx(), origin, sub, sup)
1604 pub fn type_error_message<M>(&self,
1607 actual_ty: Ty<'tcx>,
1608 err: Option<&TypeError<'tcx>>)
1609 where M: FnOnce(String) -> String,
1611 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1614 pub fn type_error_struct<M>(&self,
1617 actual_ty: Ty<'tcx>,
1618 err: Option<&TypeError<'tcx>>)
1619 -> DiagnosticBuilder<'tcx>
1620 where M: FnOnce(String) -> String,
1622 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1625 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1626 /// outlive the region `r`.
1627 pub fn register_region_obligation(&self,
1630 cause: traits::ObligationCause<'tcx>)
1632 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1633 fulfillment_cx.register_region_obligation(ty, region, cause);
1636 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1637 /// outlive the region `r`.
1638 pub fn register_wf_obligation(&self,
1641 code: traits::ObligationCauseCode<'tcx>)
1643 // WF obligations never themselves fail, so no real need to give a detailed cause:
1644 let cause = traits::ObligationCause::new(span, self.body_id, code);
1645 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1648 pub fn register_old_wf_obligation(&self,
1651 code: traits::ObligationCauseCode<'tcx>)
1653 // Registers an "old-style" WF obligation that uses the
1654 // implicator code. This is basically a buggy version of
1655 // `register_wf_obligation` that is being kept around
1656 // temporarily just to help with phasing in the newer rules.
1658 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1659 let cause = traits::ObligationCause::new(span, self.body_id, code);
1660 self.register_region_obligation(ty, ty::ReEmpty, cause);
1663 /// Registers obligations that all types appearing in `substs` are well-formed.
1664 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1666 for &ty in &substs.types {
1667 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1671 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1672 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1673 /// trait/region obligations.
1675 /// For example, if there is a function:
1678 /// fn foo<'a,T:'a>(...)
1681 /// and a reference:
1687 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1688 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1689 pub fn add_obligations_for_parameters(&self,
1690 cause: traits::ObligationCause<'tcx>,
1691 predicates: &ty::InstantiatedPredicates<'tcx>)
1693 assert!(!predicates.has_escaping_regions());
1695 debug!("add_obligations_for_parameters(predicates={:?})",
1698 for obligation in traits::predicates_for_generics(cause, predicates) {
1699 self.register_predicate(obligation);
1703 // FIXME(arielb1): use this instead of field.ty everywhere
1704 pub fn field_ty(&self,
1706 field: ty::FieldDef<'tcx>,
1707 substs: &Substs<'tcx>)
1710 self.normalize_associated_types_in(span,
1711 &field.ty(self.tcx(), substs))
1714 // Only for fields! Returns <none> for methods>
1715 // Indifferent to privacy flags
1716 fn check_casts(&self) {
1717 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1718 for cast in deferred_cast_checks.drain(..) {
1723 /// Apply "fallbacks" to some types
1724 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1725 fn default_type_parameters(&self) {
1726 use middle::ty::error::UnconstrainedNumeric::Neither;
1727 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1728 for ty in &self.infcx().unsolved_variables() {
1729 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1730 if self.infcx().type_var_diverges(resolved) {
1731 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1733 match self.infcx().type_is_unconstrained_numeric(resolved) {
1734 UnconstrainedInt => {
1735 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1737 UnconstrainedFloat => {
1738 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1746 fn select_all_obligations_and_apply_defaults(&self) {
1747 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1748 self.new_select_all_obligations_and_apply_defaults();
1750 self.old_select_all_obligations_and_apply_defaults();
1754 // Implements old type inference fallback algorithm
1755 fn old_select_all_obligations_and_apply_defaults(&self) {
1756 self.select_obligations_where_possible();
1757 self.default_type_parameters();
1758 self.select_obligations_where_possible();
1761 fn new_select_all_obligations_and_apply_defaults(&self) {
1762 use middle::ty::error::UnconstrainedNumeric::Neither;
1763 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1765 // For the time being this errs on the side of being memory wasteful but provides better
1767 // let type_variables = self.infcx().type_variables.clone();
1769 // There is a possibility that this algorithm will have to run an arbitrary number of times
1770 // to terminate so we bound it by the compiler's recursion limit.
1771 for _ in 0..self.tcx().sess.recursion_limit.get() {
1772 // First we try to solve all obligations, it is possible that the last iteration
1773 // has made it possible to make more progress.
1774 self.select_obligations_where_possible();
1776 let mut conflicts = Vec::new();
1778 // Collect all unsolved type, integral and floating point variables.
1779 let unsolved_variables = self.inh.infcx.unsolved_variables();
1781 // We must collect the defaults *before* we do any unification. Because we have
1782 // directly attached defaults to the type variables any unification that occurs
1783 // will erase defaults causing conflicting defaults to be completely ignored.
1784 let default_map: FnvHashMap<_, _> =
1787 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1790 let mut unbound_tyvars = HashSet::new();
1792 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1794 // We loop over the unsolved variables, resolving them and if they are
1795 // and unconstrainted numeric type we add them to the set of unbound
1796 // variables. We do this so we only apply literal fallback to type
1797 // variables without defaults.
1798 for ty in &unsolved_variables {
1799 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1800 if self.infcx().type_var_diverges(resolved) {
1801 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1803 match self.infcx().type_is_unconstrained_numeric(resolved) {
1804 UnconstrainedInt | UnconstrainedFloat => {
1805 unbound_tyvars.insert(resolved);
1812 // We now remove any numeric types that also have defaults, and instead insert
1813 // the type variable with a defined fallback.
1814 for ty in &unsolved_variables {
1815 if let Some(_default) = default_map.get(ty) {
1816 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1818 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1821 match resolved.sty {
1822 ty::TyInfer(ty::TyVar(_)) => {
1823 unbound_tyvars.insert(ty);
1826 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1827 unbound_tyvars.insert(ty);
1828 if unbound_tyvars.contains(resolved) {
1829 unbound_tyvars.remove(resolved);
1838 // If there are no more fallbacks to apply at this point we have applied all possible
1839 // defaults and type inference will proceed as normal.
1840 if unbound_tyvars.is_empty() {
1844 // Finally we go through each of the unbound type variables and unify them with
1845 // the proper fallback, reporting a conflicting default error if any of the
1846 // unifications fail. We know it must be a conflicting default because the
1847 // variable would only be in `unbound_tyvars` and have a concrete value if
1848 // it had been solved by previously applying a default.
1850 // We wrap this in a transaction for error reporting, if we detect a conflict
1851 // we will rollback the inference context to its prior state so we can probe
1852 // for conflicts and correctly report them.
1855 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1856 for ty in &unbound_tyvars {
1857 if self.infcx().type_var_diverges(ty) {
1858 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1860 match self.infcx().type_is_unconstrained_numeric(ty) {
1861 UnconstrainedInt => {
1862 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1864 UnconstrainedFloat => {
1865 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1868 if let Some(default) = default_map.get(ty) {
1869 let default = default.clone();
1870 match infer::mk_eqty(self.infcx(), false,
1871 TypeOrigin::Misc(default.origin_span),
1875 conflicts.push((*ty, default));
1884 // If there are conflicts we rollback, otherwise commit
1885 if conflicts.len() > 0 {
1892 if conflicts.len() > 0 {
1893 // Loop through each conflicting default, figuring out the default that caused
1894 // a unification failure and then report an error for each.
1895 for (conflict, default) in conflicts {
1896 let conflicting_default =
1897 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1898 .unwrap_or(type_variable::Default {
1899 ty: self.infcx().next_ty_var(),
1900 origin_span: codemap::DUMMY_SP,
1901 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1904 // This is to ensure that we elimnate any non-determinism from the error
1905 // reporting by fixing an order, it doesn't matter what order we choose
1906 // just that it is consistent.
1907 let (first_default, second_default) =
1908 if default.def_id < conflicting_default.def_id {
1909 (default, conflicting_default)
1911 (conflicting_default, default)
1915 self.infcx().report_conflicting_default_types(
1916 first_default.origin_span,
1923 self.select_obligations_where_possible();
1926 // For use in error handling related to default type parameter fallback. We explicitly
1927 // apply the default that caused conflict first to a local version of the type variable
1928 // table then apply defaults until we find a conflict. That default must be the one
1929 // that caused conflict earlier.
1930 fn find_conflicting_default(&self,
1931 unbound_vars: &HashSet<Ty<'tcx>>,
1932 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1934 -> Option<type_variable::Default<'tcx>> {
1935 use middle::ty::error::UnconstrainedNumeric::Neither;
1936 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1938 // Ensure that we apply the conflicting default first
1939 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1940 unbound_tyvars.push(conflict);
1941 unbound_tyvars.extend(unbound_vars.iter());
1943 let mut result = None;
1944 // We run the same code as above applying defaults in order, this time when
1945 // we find the conflict we just return it for error reporting above.
1947 // We also run this inside snapshot that never commits so we can do error
1948 // reporting for more then one conflict.
1949 for ty in &unbound_tyvars {
1950 if self.infcx().type_var_diverges(ty) {
1951 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1953 match self.infcx().type_is_unconstrained_numeric(ty) {
1954 UnconstrainedInt => {
1955 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1957 UnconstrainedFloat => {
1958 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1961 if let Some(default) = default_map.get(ty) {
1962 let default = default.clone();
1963 match infer::mk_eqty(self.infcx(), false,
1964 TypeOrigin::Misc(default.origin_span),
1968 result = Some(default);
1980 fn select_all_obligations_or_error(&self) {
1981 debug!("select_all_obligations_or_error");
1983 // upvar inference should have ensured that all deferred call
1984 // resolutions are handled by now.
1985 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1987 self.select_all_obligations_and_apply_defaults();
1989 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1990 match fulfillment_cx.select_all_or_error(self.infcx()) {
1992 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1996 /// Select as many obligations as we can at present.
1997 fn select_obligations_where_possible(&self) {
1999 self.inh.fulfillment_cx
2001 .select_where_possible(self.infcx())
2004 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2008 fn private_item_is_visible(&self, def_id: DefId) -> bool {
2009 match self.tcx().map.as_local_node_id(def_id) {
2010 Some(node_id) => self.tcx().map.private_item_is_visible_from(node_id, self.body_id),
2011 None => false, // Private items from other crates are never visible
2016 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2017 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2018 Some(self.base_object_lifetime_default(span))
2021 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2022 // RFC #599 specifies that object lifetime defaults take
2023 // precedence over other defaults. But within a fn body we
2024 // don't have a *default* region, rather we use inference to
2025 // find the *correct* region, which is strictly more general
2026 // (and anyway, within a fn body the right region may not even
2027 // be something the user can write explicitly, since it might
2028 // be some expression).
2029 self.infcx().next_region_var(infer::MiscVariable(span))
2032 fn anon_regions(&self, span: Span, count: usize)
2033 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2034 Ok((0..count).map(|_| {
2035 self.infcx().next_region_var(infer::MiscVariable(span))
2040 /// Whether `autoderef` requires types to resolve.
2041 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2042 pub enum UnresolvedTypeAction {
2043 /// Produce an error and return `TyError` whenever a type cannot
2044 /// be resolved (i.e. it is `TyInfer`).
2046 /// Go on without emitting any errors, and return the unresolved
2047 /// type. Useful for probing, e.g. in coercions.
2051 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2052 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2054 /// Note: this method does not modify the adjustments table. The caller is responsible for
2055 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2056 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2059 opt_expr: Option<&hir::Expr>,
2060 unresolved_type_action: UnresolvedTypeAction,
2061 mut lvalue_pref: LvaluePreference,
2063 -> (Ty<'tcx>, usize, Option<T>)
2064 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2066 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2071 let mut t = base_ty;
2072 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2073 let resolved_t = match unresolved_type_action {
2074 UnresolvedTypeAction::Error => {
2075 structurally_resolved_type(fcx, sp, t)
2077 UnresolvedTypeAction::Ignore => {
2078 // We can continue even when the type cannot be resolved
2079 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2080 // and `try_overloaded_deref` both simply return `None`
2081 // in such a case without producing spurious errors.
2082 fcx.resolve_type_vars_if_possible(t)
2085 if resolved_t.references_error() {
2086 return (resolved_t, autoderefs, None);
2089 match should_stop(resolved_t, autoderefs) {
2090 Some(x) => return (resolved_t, autoderefs, Some(x)),
2094 // Otherwise, deref if type is derefable:
2095 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2096 Some(mt) => Some(mt),
2099 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2101 // Super subtle: it might seem as though we should
2102 // pass `opt_expr` to `try_overloaded_deref`, so that
2103 // the (implicit) autoref of using an overloaded deref
2104 // would get added to the adjustment table. However we
2105 // do not do that, because it's kind of a
2106 // "meta-adjustment" -- instead, we just leave it
2107 // unrecorded and know that there "will be" an
2108 // autoref. regionck and other bits of the code base,
2109 // when they encounter an overloaded autoderef, have
2110 // to do some reconstructive surgery. This is a pretty
2111 // complex mess that is begging for a proper MIR.
2112 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2118 if mt.mutbl == hir::MutImmutable {
2119 lvalue_pref = NoPreference;
2122 None => return (resolved_t, autoderefs, None)
2126 // We've reached the recursion limit, error gracefully.
2127 span_err!(fcx.tcx().sess, sp, E0055,
2128 "reached the recursion limit while auto-dereferencing {:?}",
2130 (fcx.tcx().types.err, 0, None)
2133 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2135 method_call: Option<MethodCall>,
2136 base_expr: Option<&hir::Expr>,
2138 lvalue_pref: LvaluePreference)
2139 -> Option<ty::TypeAndMut<'tcx>>
2141 // Try DerefMut first, if preferred.
2142 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2143 (PreferMutLvalue, Some(trait_did)) => {
2144 method::lookup_in_trait(fcx, span, base_expr,
2145 token::intern("deref_mut"), trait_did,
2151 // Otherwise, fall back to Deref.
2152 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2153 (None, Some(trait_did)) => {
2154 method::lookup_in_trait(fcx, span, base_expr,
2155 token::intern("deref"), trait_did,
2158 (method, _) => method
2161 make_overloaded_lvalue_return_type(fcx, method_call, method)
2164 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2165 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2166 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2167 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2168 method_call: Option<MethodCall>,
2169 method: Option<MethodCallee<'tcx>>)
2170 -> Option<ty::TypeAndMut<'tcx>>
2174 // extract method return type, which will be &T;
2175 // all LB regions should have been instantiated during method lookup
2176 let ret_ty = method.ty.fn_ret();
2177 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2179 if let Some(method_call) = method_call {
2180 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2183 // method returns &T, but the type as visible to user is T, so deref
2184 ret_ty.builtin_deref(true, NoPreference)
2190 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2192 base_expr: &'tcx hir::Expr,
2195 lvalue_pref: LvaluePreference)
2196 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2198 // FIXME(#18741) -- this is almost but not quite the same as the
2199 // autoderef that normal method probing does. They could likely be
2202 let (ty, autoderefs, final_mt) = autoderef(fcx,
2206 UnresolvedTypeAction::Error,
2209 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2210 adj_ty, idx, false, lvalue_pref, idx_ty)
2213 if final_mt.is_some() {
2217 // After we have fully autoderef'd, if the resulting type is [T; n], then
2218 // do a final unsized coercion to yield [T].
2219 if let ty::TyArray(element_ty, _) = ty.sty {
2220 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2221 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2222 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2228 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2229 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2230 /// This loop implements one step in that search; the autoderef loop is implemented by
2231 /// `lookup_indexing`.
2232 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2233 method_call: MethodCall,
2235 base_expr: &'tcx hir::Expr,
2236 adjusted_ty: Ty<'tcx>,
2239 lvalue_pref: LvaluePreference,
2241 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2243 let tcx = fcx.tcx();
2244 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2245 autoderefs={}, unsize={}, index_ty={:?})",
2253 let input_ty = fcx.infcx().next_ty_var();
2255 // First, try built-in indexing.
2256 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2257 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2258 debug!("try_index_step: success, using built-in indexing");
2259 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2261 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2262 return Some((tcx.types.usize, ty));
2267 // Try `IndexMut` first, if preferred.
2268 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2269 (PreferMutLvalue, Some(trait_did)) => {
2270 method::lookup_in_trait_adjusted(fcx,
2273 token::intern("index_mut"),
2278 Some(vec![input_ty]))
2283 // Otherwise, fall back to `Index`.
2284 let method = match (method, tcx.lang_items.index_trait()) {
2285 (None, Some(trait_did)) => {
2286 method::lookup_in_trait_adjusted(fcx,
2289 token::intern("index"),
2294 Some(vec![input_ty]))
2296 (method, _) => method,
2299 // If some lookup succeeds, write callee into table and extract index/element
2300 // type from the method signature.
2301 // If some lookup succeeded, install method in table
2302 method.and_then(|method| {
2303 debug!("try_index_step: success, using overloaded indexing");
2304 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2305 map(|ret| (input_ty, ret.ty))
2309 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2311 method_fn_ty: Ty<'tcx>,
2312 callee_expr: &'tcx hir::Expr,
2313 args_no_rcvr: &'tcx [P<hir::Expr>],
2314 tuple_arguments: TupleArgumentsFlag,
2315 expected: Expectation<'tcx>)
2316 -> ty::FnOutput<'tcx> {
2317 if method_fn_ty.references_error() {
2318 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2320 let err_inputs = match tuple_arguments {
2321 DontTupleArguments => err_inputs,
2322 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2325 check_argument_types(fcx,
2332 ty::FnConverging(fcx.tcx().types.err)
2334 match method_fn_ty.sty {
2335 ty::TyFnDef(_, _, ref fty) => {
2336 // HACK(eddyb) ignore self in the definition (see above).
2337 let expected_arg_tys = expected_types_for_fn_args(fcx,
2341 &fty.sig.0.inputs[1..]);
2342 check_argument_types(fcx,
2344 &fty.sig.0.inputs[1..],
2345 &expected_arg_tys[..],
2352 fcx.tcx().sess.span_bug(callee_expr.span,
2353 "method without bare fn type");
2359 /// Generic function that factors out common logic from function calls, method calls and overloaded
2361 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2363 fn_inputs: &[Ty<'tcx>],
2364 expected_arg_tys: &[Ty<'tcx>],
2365 args: &'tcx [P<hir::Expr>],
2367 tuple_arguments: TupleArgumentsFlag) {
2368 let tcx = fcx.ccx.tcx;
2370 // Grab the argument types, supplying fresh type variables
2371 // if the wrong number of arguments were supplied
2372 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2378 // All the input types from the fn signature must outlive the call
2379 // so as to validate implied bounds.
2380 for &fn_input_ty in fn_inputs {
2381 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2384 let mut expected_arg_tys = expected_arg_tys;
2385 let expected_arg_count = fn_inputs.len();
2386 let formal_tys = if tuple_arguments == TupleArguments {
2387 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2388 match tuple_type.sty {
2389 ty::TyTuple(ref arg_types) => {
2390 if arg_types.len() != args.len() {
2391 span_err!(tcx.sess, sp, E0057,
2392 "this function takes {} parameter{} but {} parameter{} supplied",
2394 if arg_types.len() == 1 {""} else {"s"},
2396 if args.len() == 1 {" was"} else {"s were"});
2397 expected_arg_tys = &[];
2398 err_args(fcx.tcx(), args.len())
2400 expected_arg_tys = match expected_arg_tys.get(0) {
2401 Some(&ty) => match ty.sty {
2402 ty::TyTuple(ref tys) => &tys,
2407 (*arg_types).clone()
2411 span_err!(tcx.sess, sp, E0059,
2412 "cannot use call notation; the first type parameter \
2413 for the function trait is neither a tuple nor unit");
2414 expected_arg_tys = &[];
2415 err_args(fcx.tcx(), args.len())
2418 } else if expected_arg_count == supplied_arg_count {
2420 } else if variadic {
2421 if supplied_arg_count >= expected_arg_count {
2424 span_err!(tcx.sess, sp, E0060,
2425 "this function takes at least {} parameter{} \
2426 but {} parameter{} supplied",
2428 if expected_arg_count == 1 {""} else {"s"},
2430 if supplied_arg_count == 1 {" was"} else {"s were"});
2431 expected_arg_tys = &[];
2432 err_args(fcx.tcx(), supplied_arg_count)
2435 span_err!(tcx.sess, sp, E0061,
2436 "this function takes {} parameter{} but {} parameter{} supplied",
2438 if expected_arg_count == 1 {""} else {"s"},
2440 if supplied_arg_count == 1 {" was"} else {"s were"});
2441 expected_arg_tys = &[];
2442 err_args(fcx.tcx(), supplied_arg_count)
2445 debug!("check_argument_types: formal_tys={:?}",
2446 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2448 // Check the arguments.
2449 // We do this in a pretty awful way: first we typecheck any arguments
2450 // that are not anonymous functions, then we typecheck the anonymous
2451 // functions. This is so that we have more information about the types
2452 // of arguments when we typecheck the functions. This isn't really the
2453 // right way to do this.
2454 let xs = [false, true];
2455 let mut any_diverges = false; // has any of the arguments diverged?
2456 let mut warned = false; // have we already warned about unreachable code?
2457 for check_blocks in &xs {
2458 let check_blocks = *check_blocks;
2459 debug!("check_blocks={}", check_blocks);
2461 // More awful hacks: before we check argument types, try to do
2462 // an "opportunistic" vtable resolution of any trait bounds on
2463 // the call. This helps coercions.
2465 fcx.select_obligations_where_possible();
2468 // For variadic functions, we don't have a declared type for all of
2469 // the arguments hence we only do our usual type checking with
2470 // the arguments who's types we do know.
2471 let t = if variadic {
2473 } else if tuple_arguments == TupleArguments {
2478 for (i, arg) in args.iter().take(t).enumerate() {
2479 if any_diverges && !warned {
2483 .add_lint(lint::builtin::UNREACHABLE_CODE,
2486 "unreachable expression".to_string());
2489 let is_block = match arg.node {
2490 hir::ExprClosure(..) => true,
2494 if is_block == check_blocks {
2495 debug!("checking the argument");
2496 let formal_ty = formal_tys[i];
2498 // The special-cased logic below has three functions:
2499 // 1. Provide as good of an expected type as possible.
2500 let expected = expected_arg_tys.get(i).map(|&ty| {
2501 Expectation::rvalue_hint(fcx.tcx(), ty)
2504 check_expr_with_unifier(fcx,
2506 expected.unwrap_or(ExpectHasType(formal_ty)),
2508 // 2. Coerce to the most detailed type that could be coerced
2509 // to, which is `expected_ty` if `rvalue_hint` returns an
2510 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2511 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2512 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2514 // 3. Relate the expected type and the formal one,
2515 // if the expected type was used for the coercion.
2516 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2520 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2521 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2524 if any_diverges && !warned {
2525 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2529 .add_lint(lint::builtin::UNREACHABLE_CODE,
2532 "unreachable call".to_string());
2538 // We also need to make sure we at least write the ty of the other
2539 // arguments which we skipped above.
2541 for arg in args.iter().skip(expected_arg_count) {
2542 check_expr(fcx, &arg);
2544 // There are a few types which get autopromoted when passed via varargs
2545 // in C but we just error out instead and require explicit casts.
2546 let arg_ty = structurally_resolved_type(fcx, arg.span,
2549 ty::TyFloat(ast::FloatTy::F32) => {
2550 fcx.type_error_message(arg.span,
2552 format!("can't pass an {} to variadic \
2553 function, cast to c_double", t)
2556 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2557 fcx.type_error_message(arg.span, |t| {
2558 format!("can't pass {} to variadic \
2559 function, cast to c_int",
2563 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2564 fcx.type_error_message(arg.span, |t| {
2565 format!("can't pass {} to variadic \
2566 function, cast to c_uint",
2576 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2577 fn err_args<'tcx>(tcx: &TyCtxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2578 (0..len).map(|_| tcx.types.err).collect()
2581 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2582 call_expr: &hir::Expr,
2583 output: ty::FnOutput<'tcx>) {
2584 fcx.write_ty(call_expr.id, match output {
2585 ty::FnConverging(output_ty) => output_ty,
2586 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2590 // AST fragment checking
2591 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2593 expected: Expectation<'tcx>)
2596 let tcx = fcx.ccx.tcx;
2599 ast::LitKind::Str(..) => tcx.mk_static_str(),
2600 ast::LitKind::ByteStr(ref v) => {
2601 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2602 tcx.mk_array(tcx.types.u8, v.len()))
2604 ast::LitKind::Byte(_) => tcx.types.u8,
2605 ast::LitKind::Char(_) => tcx.types.char,
2606 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2607 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2608 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2609 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2611 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2612 ty::TyChar => Some(tcx.types.u8),
2613 ty::TyRawPtr(..) => Some(tcx.types.usize),
2614 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2618 opt_ty.unwrap_or_else(
2619 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2621 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2622 ast::LitKind::FloatUnsuffixed(_) => {
2623 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2625 ty::TyFloat(_) => Some(ty),
2629 opt_ty.unwrap_or_else(
2630 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2632 ast::LitKind::Bool(_) => tcx.types.bool
2636 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2637 expr: &'tcx hir::Expr,
2638 expected: Ty<'tcx>) {
2639 check_expr_with_unifier(
2640 fcx, expr, ExpectHasType(expected), NoPreference,
2641 || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2644 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2645 expr: &'tcx hir::Expr,
2646 expected: Ty<'tcx>) {
2647 check_expr_with_unifier(
2648 fcx, expr, ExpectHasType(expected), NoPreference,
2649 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2652 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2653 expr: &'tcx hir::Expr,
2654 expected: Ty<'tcx>) {
2655 check_expr_with_unifier(
2656 fcx, expr, ExpectHasType(expected), NoPreference,
2657 || demand::coerce(fcx, expr.span, expected, expr));
2660 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2661 expected: Ty<'tcx>) {
2662 check_expr_with_unifier(
2663 fcx, expr, ExpectHasType(expected), NoPreference,
2667 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2668 expr: &'tcx hir::Expr,
2669 expected: Expectation<'tcx>) {
2670 check_expr_with_unifier(
2671 fcx, expr, expected, NoPreference,
2675 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2676 expr: &'tcx hir::Expr,
2677 expected: Expectation<'tcx>,
2678 lvalue_pref: LvaluePreference)
2680 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2683 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2684 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2687 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2688 lvalue_pref: LvaluePreference) {
2689 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2692 // determine the `self` type, using fresh variables for all variables
2693 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2694 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2696 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2697 span: Span, // (potential) receiver for this impl
2699 -> TypeAndSubsts<'tcx> {
2700 let tcx = fcx.tcx();
2702 let ity = tcx.lookup_item_type(did);
2703 let (tps, rps, raw_ty) =
2704 (ity.generics.types.get_slice(subst::TypeSpace),
2705 ity.generics.regions.get_slice(subst::TypeSpace),
2708 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2710 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2711 let mut substs = subst::Substs::new(
2712 VecPerParamSpace::empty(),
2713 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2714 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2715 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2717 TypeAndSubsts { substs: substs, ty: substd_ty }
2720 /// Controls whether the arguments are tupled. This is used for the call
2723 /// Tupling means that all call-side arguments are packed into a tuple and
2724 /// passed as a single parameter. For example, if tupling is enabled, this
2727 /// fn f(x: (isize, isize))
2729 /// Can be called as:
2736 #[derive(Clone, Eq, PartialEq)]
2737 enum TupleArgumentsFlag {
2742 /// Unifies the return type with the expected type early, for more coercions
2743 /// and forward type information on the argument expressions.
2744 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2746 expected_ret: Expectation<'tcx>,
2747 formal_ret: ty::FnOutput<'tcx>,
2748 formal_args: &[Ty<'tcx>])
2750 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2751 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2752 fcx.infcx().commit_regions_if_ok(|| {
2753 // Attempt to apply a subtyping relationship between the formal
2754 // return type (likely containing type variables if the function
2755 // is polymorphic) and the expected return type.
2756 // No argument expectations are produced if unification fails.
2757 let origin = TypeOrigin::Misc(call_span);
2758 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2759 // FIXME(#15760) can't use try! here, FromError doesn't default
2760 // to identity so the resulting type is not constrained.
2761 if let Err(e) = ures {
2765 // Record all the argument types, with the substitutions
2766 // produced from the above subtyping unification.
2767 Ok(formal_args.iter().map(|ty| {
2768 fcx.infcx().resolve_type_vars_if_possible(ty)
2774 }).unwrap_or(vec![]);
2775 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2776 formal_args, formal_ret,
2777 expected_args, expected_ret);
2782 /// If an expression has any sub-expressions that result in a type error,
2783 /// inspecting that expression's type with `ty.references_error()` will return
2784 /// true. Likewise, if an expression is known to diverge, inspecting its
2785 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2786 /// strict, _|_ can appear in the type of an expression that does not,
2787 /// itself, diverge: for example, fn() -> _|_.)
2788 /// Note that inspecting a type's structure *directly* may expose the fact
2789 /// that there are actually multiple representations for `TyError`, so avoid
2790 /// that when err needs to be handled differently.
2791 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2792 expr: &'tcx hir::Expr,
2793 expected: Expectation<'tcx>,
2794 lvalue_pref: LvaluePreference,
2798 debug!(">> typechecking: expr={:?} expected={:?}",
2801 // Checks a method call.
2802 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2803 expr: &'tcx hir::Expr,
2804 method_name: Spanned<ast::Name>,
2805 args: &'tcx [P<hir::Expr>],
2807 expected: Expectation<'tcx>,
2808 lvalue_pref: LvaluePreference) {
2809 let rcvr = &args[0];
2810 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2812 // no need to check for bot/err -- callee does that
2813 let expr_t = structurally_resolved_type(fcx,
2815 fcx.expr_ty(&rcvr));
2817 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2818 let fn_ty = match method::lookup(fcx,
2826 let method_ty = method.ty;
2827 let method_call = MethodCall::expr(expr.id);
2828 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2832 if method_name.node != special_idents::invalid.name {
2833 method::report_error(fcx, method_name.span, expr_t,
2834 method_name.node, Some(rcvr), error);
2836 fcx.write_error(expr.id);
2841 // Call the generic checker.
2842 let ret_ty = check_method_argument_types(fcx,
2850 write_call(fcx, expr, ret_ty);
2853 // A generic function for checking the then and else in an if
2855 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2856 cond_expr: &'tcx hir::Expr,
2857 then_blk: &'tcx hir::Block,
2858 opt_else_expr: Option<&'tcx hir::Expr>,
2861 expected: Expectation<'tcx>) {
2862 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2864 let expected = expected.adjust_for_branches(fcx);
2865 check_block_with_expected(fcx, then_blk, expected);
2866 let then_ty = fcx.node_ty(then_blk.id);
2868 let branches_ty = match opt_else_expr {
2869 Some(ref else_expr) => {
2870 check_expr_with_expectation(fcx, &else_expr, expected);
2871 let else_ty = fcx.expr_ty(&else_expr);
2872 infer::common_supertype(fcx.infcx(),
2873 TypeOrigin::IfExpression(sp),
2879 infer::common_supertype(fcx.infcx(),
2880 TypeOrigin::IfExpressionWithNoElse(sp),
2887 let cond_ty = fcx.expr_ty(cond_expr);
2888 let if_ty = if cond_ty.references_error() {
2894 fcx.write_ty(id, if_ty);
2897 // Check field access expressions
2898 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2899 expr: &'tcx hir::Expr,
2900 lvalue_pref: LvaluePreference,
2901 base: &'tcx hir::Expr,
2902 field: &Spanned<ast::Name>) {
2903 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2904 let expr_t = structurally_resolved_type(fcx, expr.span,
2906 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2907 let (_, autoderefs, field_ty) = autoderef(fcx,
2911 UnresolvedTypeAction::Error,
2915 ty::TyStruct(base_def, substs) => {
2916 debug!("struct named {:?}", base_t);
2917 base_def.struct_variant()
2918 .find_field_named(field.node)
2919 .map(|f| fcx.field_ty(expr.span, f, substs))
2926 fcx.write_ty(expr.id, field_ty);
2927 fcx.write_autoderef_adjustment(base.id, autoderefs);
2933 if field.node == special_idents::invalid.name {
2934 fcx.write_error(expr.id);
2938 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2939 fcx.type_error_struct(field.span,
2941 format!("attempted to take value of method `{}` on type \
2942 `{}`", field.node, actual)
2945 .fileline_help(field.span,
2946 "maybe a `()` to call it is missing? \
2947 If not, try an anonymous function")
2950 let mut err = fcx.type_error_struct(
2953 format!("attempted access of field `{}` on \
2954 type `{}`, but no field with that \
2960 if let ty::TyStruct(def, _) = expr_t.sty {
2961 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2966 fcx.write_error(expr.id);
2969 // displays hints about the closest matches in field names
2970 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2971 variant: ty::VariantDef<'tcx>,
2972 field: &Spanned<ast::Name>,
2973 skip : Vec<InternedString>) {
2974 let name = field.node.as_str();
2975 let names = variant.fields
2977 .filter_map(|ref field| {
2978 // ignore already set fields and private fields from non-local crates
2979 if skip.iter().any(|x| *x == field.name.as_str()) ||
2980 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2987 // only find fits with at least one matching letter
2988 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2989 err.span_help(field.span,
2990 &format!("did you mean `{}`?", name));
2994 // Check tuple index expressions
2995 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2996 expr: &'tcx hir::Expr,
2997 lvalue_pref: LvaluePreference,
2998 base: &'tcx hir::Expr,
2999 idx: codemap::Spanned<usize>) {
3000 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3001 let expr_t = structurally_resolved_type(fcx, expr.span,
3003 let mut tuple_like = false;
3004 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3005 let (_, autoderefs, field_ty) = autoderef(fcx,
3009 UnresolvedTypeAction::Error,
3013 ty::TyStruct(base_def, substs) => {
3014 tuple_like = base_def.struct_variant().is_tuple_struct();
3016 debug!("tuple struct named {:?}", base_t);
3017 base_def.struct_variant()
3020 .map(|f| fcx.field_ty(expr.span, f, substs))
3025 ty::TyTuple(ref v) => {
3027 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3034 fcx.write_ty(expr.id, field_ty);
3035 fcx.write_autoderef_adjustment(base.id, autoderefs);
3040 fcx.type_error_message(
3044 format!("attempted out-of-bounds tuple index `{}` on \
3049 format!("attempted tuple index `{}` on type `{}`, but the \
3050 type was not a tuple or tuple struct",
3057 fcx.write_error(expr.id);
3060 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3062 variant: ty::VariantDef<'tcx>,
3064 skip_fields: &[hir::Field]) {
3065 let mut err = fcx.type_error_struct(
3067 |actual| if let ty::TyEnum(..) = ty.sty {
3068 format!("struct variant `{}::{}` has no field named `{}`",
3069 actual, variant.name.as_str(), field.name.node)
3071 format!("structure `{}` has no field named `{}`",
3072 actual, field.name.node)
3076 // prevent all specified fields from being suggested
3077 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3078 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3082 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3085 variant: ty::VariantDef<'tcx>,
3086 ast_fields: &'tcx [hir::Field],
3087 check_completeness: bool) {
3088 let tcx = fcx.ccx.tcx;
3089 let substs = match adt_ty.sty {
3090 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3091 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3094 let mut remaining_fields = FnvHashMap();
3095 for field in &variant.fields {
3096 remaining_fields.insert(field.name, field);
3099 let mut error_happened = false;
3101 // Typecheck each field.
3102 for field in ast_fields {
3103 let expected_field_type;
3105 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3106 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3108 error_happened = true;
3109 expected_field_type = tcx.types.err;
3110 if let Some(_) = variant.find_field_named(field.name.node) {
3111 span_err!(fcx.tcx().sess, field.name.span, E0062,
3112 "field `{}` specified more than once",
3115 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3119 // Make sure to give a type to the field even if there's
3120 // an error, so we can continue typechecking
3121 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3124 // Make sure the programmer specified all the fields.
3125 if check_completeness &&
3127 !remaining_fields.is_empty()
3129 span_err!(tcx.sess, span, E0063,
3130 "missing field{} {} in initializer of `{}`",
3131 if remaining_fields.len() == 1 {""} else {"s"},
3132 remaining_fields.keys()
3133 .map(|n| format!("`{}`", n))
3134 .collect::<Vec<_>>()
3141 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3143 fields: &'tcx [hir::Field],
3144 base_expr: &'tcx Option<P<hir::Expr>>) {
3145 // Make sure to still write the types
3146 // otherwise we might ICE
3147 fcx.write_error(id);
3148 for field in fields {
3149 check_expr(fcx, &field.expr);
3152 Some(ref base) => check_expr(fcx, &base),
3157 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3160 fields: &'tcx [hir::Field],
3161 base_expr: &'tcx Option<P<hir::Expr>>)
3163 let tcx = fcx.tcx();
3165 // Find the relevant variant
3166 let def = lookup_full_def(tcx, path.span, expr.id);
3167 if def == Def::Err {
3168 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3171 let variant = match fcx.def_struct_variant(def, path.span) {
3172 Some((_, variant)) => variant,
3174 span_err!(fcx.tcx().sess, path.span, E0071,
3175 "`{}` does not name a structure",
3176 pprust::path_to_string(path));
3177 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3182 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3183 fcx.write_ty(expr.id, expr_ty);
3185 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3186 base_expr.is_none());
3187 if let &Some(ref base_expr) = base_expr {
3188 check_expr_has_type(fcx, base_expr, expr_ty);
3190 ty::TyStruct(adt, substs) => {
3191 fcx.inh.tables.borrow_mut().fru_field_types.insert(
3193 adt.struct_variant().fields.iter().map(|f| {
3194 fcx.normalize_associated_types_in(
3195 expr.span, &f.ty(tcx, substs)
3201 span_err!(tcx.sess, base_expr.span, E0436,
3202 "functional record update syntax requires a struct");
3208 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3210 let tcx = fcx.ccx.tcx;
3213 hir::ExprBox(ref subexpr) => {
3214 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3216 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3220 check_expr_with_expectation(fcx, subexpr, expected_inner);
3221 let referent_ty = fcx.expr_ty(&subexpr);
3222 fcx.write_ty(id, tcx.mk_box(referent_ty));
3225 hir::ExprLit(ref lit) => {
3226 let typ = check_lit(fcx, &lit, expected);
3227 fcx.write_ty(id, typ);
3229 hir::ExprBinary(op, ref lhs, ref rhs) => {
3230 op::check_binop(fcx, expr, op, lhs, rhs);
3232 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3233 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3235 hir::ExprUnary(unop, ref oprnd) => {
3236 let expected_inner = match unop {
3237 hir::UnNot | hir::UnNeg => {
3244 let lvalue_pref = match unop {
3245 hir::UnDeref => lvalue_pref,
3248 check_expr_with_expectation_and_lvalue_pref(
3249 fcx, &oprnd, expected_inner, lvalue_pref);
3250 let mut oprnd_t = fcx.expr_ty(&oprnd);
3252 if !oprnd_t.references_error() {
3255 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3256 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3258 None => match try_overloaded_deref(fcx, expr.span,
3259 Some(MethodCall::expr(expr.id)),
3260 Some(&oprnd), oprnd_t, lvalue_pref) {
3263 fcx.type_error_message(expr.span, |actual| {
3264 format!("type `{}` cannot be \
3265 dereferenced", actual)
3273 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3275 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3276 oprnd_t = op::check_user_unop(fcx, "!", "not",
3277 tcx.lang_items.not_trait(),
3278 expr, &oprnd, oprnd_t, unop);
3282 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3284 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3285 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3286 tcx.lang_items.neg_trait(),
3287 expr, &oprnd, oprnd_t, unop);
3292 fcx.write_ty(id, oprnd_t);
3294 hir::ExprAddrOf(mutbl, ref oprnd) => {
3295 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3297 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3298 if fcx.tcx().expr_is_lval(&oprnd) {
3299 // Lvalues may legitimately have unsized types.
3300 // For example, dereferences of a fat pointer and
3301 // the last field of a struct can be unsized.
3302 ExpectHasType(mt.ty)
3304 Expectation::rvalue_hint(tcx, mt.ty)
3310 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3311 check_expr_with_expectation_and_lvalue_pref(fcx,
3316 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3317 let oprnd_t = if tm.ty.references_error() {
3320 // Note: at this point, we cannot say what the best lifetime
3321 // is to use for resulting pointer. We want to use the
3322 // shortest lifetime possible so as to avoid spurious borrowck
3323 // errors. Moreover, the longest lifetime will depend on the
3324 // precise details of the value whose address is being taken
3325 // (and how long it is valid), which we don't know yet until type
3326 // inference is complete.
3328 // Therefore, here we simply generate a region variable. The
3329 // region inferencer will then select the ultimate value.
3330 // Finally, borrowck is charged with guaranteeing that the
3331 // value whose address was taken can actually be made to live
3332 // as long as it needs to live.
3333 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3334 tcx.mk_ref(tcx.mk_region(region), tm)
3336 fcx.write_ty(id, oprnd_t);
3338 hir::ExprPath(ref maybe_qself, ref path) => {
3339 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3340 fcx.to_ty(&qself.ty)
3343 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3345 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3346 // Create some fake resolution that can't possibly be a type.
3347 def::PathResolution {
3348 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3349 depth: path.segments.len()
3352 tcx.sess.span_bug(expr.span,
3353 &format!("unbound path {:?}", expr))
3356 if let Some((opt_ty, segments, def)) =
3357 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3358 expr.span, expr.id) {
3359 if def != Def::Err {
3360 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3363 instantiate_path(fcx,
3372 fcx.write_ty(id, fcx.tcx().types.err);
3376 // We always require that the type provided as the value for
3377 // a type parameter outlives the moment of instantiation.
3378 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3379 fcx.add_wf_bounds(&item_substs.substs, expr);
3382 hir::ExprInlineAsm(ref ia) => {
3383 for &(_, ref input) in &ia.inputs {
3384 check_expr(fcx, &input);
3386 for out in &ia.outputs {
3387 check_expr(fcx, &out.expr);
3391 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3392 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3393 hir::ExprRet(ref expr_opt) => {
3395 ty::FnConverging(result_type) => {
3398 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3399 result_type, fcx.tcx().mk_nil()) {
3400 span_err!(tcx.sess, expr.span, E0069,
3401 "`return;` in a function whose return type is \
3405 check_expr_coercable_to_type(fcx, &e, result_type);
3409 ty::FnDiverging => {
3410 if let Some(ref e) = *expr_opt {
3411 check_expr(fcx, &e);
3413 span_err!(tcx.sess, expr.span, E0166,
3414 "`return` in a function declared as diverging");
3417 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3419 hir::ExprAssign(ref lhs, ref rhs) => {
3420 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3422 let tcx = fcx.tcx();
3423 if !tcx.expr_is_lval(&lhs) {
3424 span_err!(tcx.sess, expr.span, E0070,
3425 "invalid left-hand side expression");
3428 let lhs_ty = fcx.expr_ty(&lhs);
3429 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3430 let rhs_ty = fcx.expr_ty(&rhs);
3432 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3434 if lhs_ty.references_error() || rhs_ty.references_error() {
3435 fcx.write_error(id);
3440 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3441 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3442 id, expr.span, expected);
3444 hir::ExprWhile(ref cond, ref body, _) => {
3445 check_expr_has_type(fcx, &cond, tcx.types.bool);
3446 check_block_no_value(fcx, &body);
3447 let cond_ty = fcx.expr_ty(&cond);
3448 let body_ty = fcx.node_ty(body.id);
3449 if cond_ty.references_error() || body_ty.references_error() {
3450 fcx.write_error(id);
3456 hir::ExprLoop(ref body, _) => {
3457 check_block_no_value(fcx, &body);
3458 if !may_break(tcx, expr.id, &body) {
3459 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3464 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3465 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3467 hir::ExprClosure(capture, ref decl, ref body) => {
3468 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3470 hir::ExprBlock(ref b) => {
3471 check_block_with_expected(fcx, &b, expected);
3472 fcx.write_ty(id, fcx.node_ty(b.id));
3474 hir::ExprCall(ref callee, ref args) => {
3475 callee::check_call(fcx, expr, &callee, &args[..], expected);
3477 // we must check that return type of called functions is WF:
3478 let ret_ty = fcx.expr_ty(expr);
3479 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3481 hir::ExprMethodCall(name, ref tps, ref args) => {
3482 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3483 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3484 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3486 fcx.write_error(id);
3489 hir::ExprCast(ref e, ref t) => {
3490 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3491 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3494 // Find the type of `e`. Supply hints based on the type we are casting to,
3496 let t_cast = fcx.to_ty(t);
3497 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3498 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3499 let t_expr = fcx.expr_ty(e);
3500 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3502 // Eagerly check for some obvious errors.
3503 if t_expr.references_error() || t_cast.references_error() {
3504 fcx.write_error(id);
3505 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3506 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3508 // Write a type for the whole expression, assuming everything is going
3510 fcx.write_ty(id, t_cast);
3512 // Defer other checks until we're done type checking.
3513 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3514 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3515 deferred_cast_checks.push(cast_check);
3518 hir::ExprType(ref e, ref t) => {
3519 let typ = fcx.to_ty(&t);
3520 check_expr_eq_type(fcx, &e, typ);
3521 fcx.write_ty(id, typ);
3523 hir::ExprVec(ref args) => {
3524 let uty = expected.to_option(fcx).and_then(|uty| {
3526 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3531 let typ = match uty {
3534 check_expr_coercable_to_type(fcx, &e, uty);
3539 let t: Ty = fcx.infcx().next_ty_var();
3541 check_expr_has_type(fcx, &e, t);
3546 let typ = tcx.mk_array(typ, args.len());
3547 fcx.write_ty(id, typ);
3549 hir::ExprRepeat(ref element, ref count_expr) => {
3550 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3551 let count = fcx.tcx().eval_repeat_count(&count_expr);
3553 let uty = match expected {
3554 ExpectHasType(uty) => {
3556 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3563 let (element_ty, t) = match uty {
3565 check_expr_coercable_to_type(fcx, &element, uty);
3569 let t: Ty = fcx.infcx().next_ty_var();
3570 check_expr_has_type(fcx, &element, t);
3571 (fcx.expr_ty(&element), t)
3576 // For [foo, ..n] where n > 1, `foo` must have
3578 fcx.require_type_meets(
3585 if element_ty.references_error() {
3586 fcx.write_error(id);
3588 let t = tcx.mk_array(t, count);
3589 fcx.write_ty(id, t);
3592 hir::ExprTup(ref elts) => {
3593 let flds = expected.only_has_type(fcx).and_then(|ty| {
3595 ty::TyTuple(ref flds) => Some(&flds[..]),
3599 let mut err_field = false;
3601 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3602 let t = match flds {
3603 Some(ref fs) if i < fs.len() => {
3605 check_expr_coercable_to_type(fcx, &e, ety);
3609 check_expr_with_expectation(fcx, &e, NoExpectation);
3613 err_field = err_field || t.references_error();
3617 fcx.write_error(id);
3619 let typ = tcx.mk_tup(elt_ts);
3620 fcx.write_ty(id, typ);
3623 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3624 check_expr_struct(fcx, expr, path, fields, base_expr);
3626 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3628 hir::ExprField(ref base, ref field) => {
3629 check_field(fcx, expr, lvalue_pref, &base, field);
3631 hir::ExprTupField(ref base, idx) => {
3632 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3634 hir::ExprIndex(ref base, ref idx) => {
3635 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3636 check_expr(fcx, &idx);
3638 let base_t = fcx.expr_ty(&base);
3639 let idx_t = fcx.expr_ty(&idx);
3641 if base_t.references_error() {
3642 fcx.write_ty(id, base_t);
3643 } else if idx_t.references_error() {
3644 fcx.write_ty(id, idx_t);
3646 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3647 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3648 Some((index_ty, element_ty)) => {
3649 let idx_expr_ty = fcx.expr_ty(idx);
3650 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3651 fcx.write_ty(id, element_ty);
3654 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3655 fcx.type_error_message(
3658 format!("cannot index a value of type `{}`",
3663 fcx.write_ty(id, fcx.tcx().types.err);
3670 debug!("type of expr({}) {} is...", expr.id,
3671 pprust::expr_to_string(expr));
3672 debug!("... {:?}, expected is {:?}",
3679 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3680 path_res: def::PathResolution,
3681 opt_self_ty: Option<Ty<'tcx>>,
3682 path: &'a hir::Path,
3684 node_id: ast::NodeId)
3685 -> Option<(Option<Ty<'tcx>>,
3686 &'a [hir::PathSegment],
3690 // If fully resolved already, we don't have to do anything.
3691 if path_res.depth == 0 {
3692 Some((opt_self_ty, &path.segments, path_res.base_def))
3694 let mut def = path_res.base_def;
3695 let ty_segments = path.segments.split_last().unwrap().1;
3696 let base_ty_end = path.segments.len() - path_res.depth;
3697 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3698 PathParamMode::Optional,
3701 &ty_segments[..base_ty_end],
3702 &ty_segments[base_ty_end..]);
3703 let item_segment = path.segments.last().unwrap();
3704 let item_name = item_segment.identifier.name;
3705 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3707 // Write back the new resolution.
3708 fcx.ccx.tcx.def_map.borrow_mut()
3709 .insert(node_id, def::PathResolution {
3713 Some((Some(ty), slice::ref_slice(item_segment), def))
3716 if item_name != special_idents::invalid.name {
3717 method::report_error(fcx, span, ty, item_name, None, error);
3719 fcx.write_error(node_id);
3726 impl<'tcx> Expectation<'tcx> {
3727 /// Provide an expectation for an rvalue expression given an *optional*
3728 /// hint, which is not required for type safety (the resulting type might
3729 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3730 /// is useful in determining the concrete type.
3732 /// The primary use case is where the expected type is a fat pointer,
3733 /// like `&[isize]`. For example, consider the following statement:
3735 /// let x: &[isize] = &[1, 2, 3];
3737 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3738 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3739 /// expectation `ExpectHasType([isize])`, that would be too strong --
3740 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3741 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3742 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3743 /// which still is useful, because it informs integer literals and the like.
3744 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3745 /// for examples of where this comes up,.
3746 fn rvalue_hint(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3747 match tcx.struct_tail(ty).sty {
3748 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3749 ExpectRvalueLikeUnsized(ty)
3751 _ => ExpectHasType(ty)
3755 // Resolves `expected` by a single level if it is a variable. If
3756 // there is no expected type or resolution is not possible (e.g.,
3757 // no constraints yet present), just returns `None`.
3758 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3763 ExpectCastableToType(t) => {
3764 ExpectCastableToType(
3765 fcx.infcx().resolve_type_vars_if_possible(&t))
3767 ExpectHasType(t) => {
3769 fcx.infcx().resolve_type_vars_if_possible(&t))
3771 ExpectRvalueLikeUnsized(t) => {
3772 ExpectRvalueLikeUnsized(
3773 fcx.infcx().resolve_type_vars_if_possible(&t))
3778 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3779 match self.resolve(fcx) {
3780 NoExpectation => None,
3781 ExpectCastableToType(ty) |
3783 ExpectRvalueLikeUnsized(ty) => Some(ty),
3787 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3788 match self.resolve(fcx) {
3789 ExpectHasType(ty) => Some(ty),
3795 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3796 local: &'tcx hir::Local,
3797 init: &'tcx hir::Expr)
3799 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3801 let local_ty = fcx.local_ty(init.span, local.id);
3802 if let Some(m) = ref_bindings {
3803 // Somewhat subtle: if we have a `ref` binding in the pattern,
3804 // we want to avoid introducing coercions for the RHS. This is
3805 // both because it helps preserve sanity and, in the case of
3806 // ref mut, for soundness (issue #23116). In particular, in
3807 // the latter case, we need to be clear that the type of the
3808 // referent for the reference that results is *equal to* the
3809 // type of the lvalue it is referencing, and not some
3810 // supertype thereof.
3811 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3812 let init_ty = fcx.expr_ty(init);
3813 demand::eqtype(fcx, init.span, init_ty, local_ty);
3815 check_expr_coercable_to_type(fcx, init, local_ty)
3819 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3820 let tcx = fcx.ccx.tcx;
3822 let t = fcx.local_ty(local.span, local.id);
3823 fcx.write_ty(local.id, t);
3825 if let Some(ref init) = local.init {
3826 check_decl_initializer(fcx, local, &init);
3827 let init_ty = fcx.expr_ty(&init);
3828 if init_ty.references_error() {
3829 fcx.write_ty(local.id, init_ty);
3833 let pcx = pat_ctxt {
3835 map: pat_id_map(&tcx.def_map, &local.pat),
3837 _match::check_pat(&pcx, &local.pat, t);
3838 let pat_ty = fcx.node_ty(local.pat.id);
3839 if pat_ty.references_error() {
3840 fcx.write_ty(local.id, pat_ty);
3844 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3846 let mut saw_bot = false;
3847 let mut saw_err = false;
3849 hir::StmtDecl(ref decl, id) => {
3852 hir::DeclLocal(ref l) => {
3853 check_decl_local(fcx, &l);
3854 let l_t = fcx.node_ty(l.id);
3855 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3856 saw_err = saw_err || l_t.references_error();
3858 hir::DeclItem(_) => {/* ignore for now */ }
3861 hir::StmtExpr(ref expr, id) => {
3863 // Check with expected type of ()
3864 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3865 let expr_ty = fcx.expr_ty(&expr);
3866 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3867 saw_err = saw_err || expr_ty.references_error();
3869 hir::StmtSemi(ref expr, id) => {
3871 check_expr(fcx, &expr);
3872 let expr_ty = fcx.expr_ty(&expr);
3873 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3874 saw_err |= expr_ty.references_error();
3878 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3881 fcx.write_error(node_id);
3884 fcx.write_nil(node_id)
3888 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3889 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3890 let blkty = fcx.node_ty(blk.id);
3891 if blkty.references_error() {
3892 fcx.write_error(blk.id);
3894 let nilty = fcx.tcx().mk_nil();
3895 demand::suptype(fcx, blk.span, nilty, blkty);
3899 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3900 blk: &'tcx hir::Block,
3901 expected: Expectation<'tcx>) {
3903 let mut fcx_ps = fcx.ps.borrow_mut();
3904 let unsafety_state = fcx_ps.recurse(blk);
3905 replace(&mut *fcx_ps, unsafety_state)
3908 let mut warned = false;
3909 let mut any_diverges = false;
3910 let mut any_err = false;
3911 for s in &blk.stmts {
3913 let s_id = ::rustc_front::util::stmt_id(s);
3914 let s_ty = fcx.node_ty(s_id);
3915 if any_diverges && !warned && match s.node {
3916 hir::StmtDecl(ref decl, _) => {
3918 hir::DeclLocal(_) => true,
3922 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3927 .add_lint(lint::builtin::UNREACHABLE_CODE,
3930 "unreachable statement".to_string());
3933 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3934 any_err = any_err || s_ty.references_error();
3937 None => if any_err {
3938 fcx.write_error(blk.id);
3939 } else if any_diverges {
3940 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3942 fcx.write_nil(blk.id);
3945 if any_diverges && !warned {
3949 .add_lint(lint::builtin::UNREACHABLE_CODE,
3952 "unreachable expression".to_string());
3954 let ety = match expected {
3955 ExpectHasType(ety) => {
3956 check_expr_coercable_to_type(fcx, &e, ety);
3960 check_expr_with_expectation(fcx, &e, expected);
3966 fcx.write_error(blk.id);
3967 } else if any_diverges {
3968 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3970 fcx.write_ty(blk.id, ety);
3975 *fcx.ps.borrow_mut() = prev;
3978 /// Checks a constant appearing in a type. At the moment this is just the
3979 /// length expression in a fixed-length vector, but someday it might be
3980 /// extended to type-level numeric literals.
3981 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3982 expr: &'tcx hir::Expr,
3983 expected_type: Ty<'tcx>) {
3984 let tables = RefCell::new(ty::Tables::empty());
3985 let inh = static_inherited_fields(ccx, &tables);
3986 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3987 check_const_with_ty(&fcx, expr.span, expr, expected_type);
3990 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3994 let tables = RefCell::new(ty::Tables::empty());
3995 let inh = static_inherited_fields(ccx, &tables);
3996 let rty = ccx.tcx.node_id_to_type(id);
3997 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
3998 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
3999 check_const_with_ty(&fcx, sp, e, declty);
4002 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4006 // Gather locals in statics (because of block expressions).
4007 // This is technically unnecessary because locals in static items are forbidden,
4008 // but prevents type checking from blowing up before const checking can properly
4010 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4012 check_expr_with_hint(fcx, e, declty);
4013 demand::coerce(fcx, e.span, declty, e);
4015 fcx.select_all_obligations_and_apply_defaults();
4016 upvar::closure_analyze_const(&fcx, e);
4017 fcx.select_obligations_where_possible();
4019 fcx.select_all_obligations_or_error();
4021 regionck::regionck_expr(fcx, e);
4022 writeback::resolve_type_vars_in_expr(fcx, e);
4025 /// Checks whether a type can be represented in memory. In particular, it
4026 /// identifies types that contain themselves without indirection through a
4027 /// pointer, which would mean their size is unbounded.
4028 pub fn check_representable(tcx: &TyCtxt,
4030 item_id: ast::NodeId,
4031 _designation: &str) -> bool {
4032 let rty = tcx.node_id_to_type(item_id);
4034 // Check that it is possible to represent this type. This call identifies
4035 // (1) types that contain themselves and (2) types that contain a different
4036 // recursive type. It is only necessary to throw an error on those that
4037 // contain themselves. For case 2, there must be an inner type that will be
4038 // caught by case 1.
4039 match rty.is_representable(tcx, sp) {
4040 Representability::SelfRecursive => {
4041 let item_def_id = tcx.map.local_def_id(item_id);
4042 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4045 Representability::Representable | Representability::ContainsRecursive => (),
4050 pub fn check_simd(tcx: &TyCtxt, sp: Span, id: ast::NodeId) {
4051 let t = tcx.node_id_to_type(id);
4053 ty::TyStruct(def, substs) => {
4054 let fields = &def.struct_variant().fields;
4055 if fields.is_empty() {
4056 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4059 let e = fields[0].ty(tcx, substs);
4060 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4061 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4065 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4066 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4068 span_err!(tcx.sess, sp, E0077,
4069 "SIMD vector element type should be machine type");
4078 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4080 vs: &'tcx [hir::Variant],
4082 // disr_in_range should be removed once we have forced type hints for consts
4083 fn disr_in_range(ccx: &CrateCtxt,
4085 disr: ty::Disr) -> bool {
4086 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4088 ast::UintTy::U8 => disr as u8 as Disr == disr,
4089 ast::UintTy::U16 => disr as u16 as Disr == disr,
4090 ast::UintTy::U32 => disr as u32 as Disr == disr,
4091 ast::UintTy::U64 => disr as u64 as Disr == disr,
4092 ast::UintTy::Us => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4095 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4097 ast::IntTy::I8 => disr as i8 as Disr == disr,
4098 ast::IntTy::I16 => disr as i16 as Disr == disr,
4099 ast::IntTy::I32 => disr as i32 as Disr == disr,
4100 ast::IntTy::I64 => disr as i64 as Disr == disr,
4101 ast::IntTy::Is => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4105 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4106 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4110 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4111 vs: &'tcx [hir::Variant],
4113 hint: attr::ReprAttr) {
4114 #![allow(trivial_numeric_casts)]
4116 let rty = ccx.tcx.node_id_to_type(id);
4117 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4119 let tables = RefCell::new(ty::Tables::empty());
4120 let inh = static_inherited_fields(ccx, &tables);
4121 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4123 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4125 if let Some(ref e) = v.node.disr_expr {
4126 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4130 let def_id = ccx.tcx.map.local_def_id(id);
4132 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4133 for (v, variant) in vs.iter().zip(variants.iter()) {
4134 let current_disr_val = variant.disr_val;
4136 // Check for duplicate discriminant values
4137 match disr_vals.iter().position(|&x| x == current_disr_val) {
4139 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4140 "discriminant value `{}` already exists", disr_vals[i]);
4141 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4142 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4143 "conflicting discriminant here");
4148 // Check for unrepresentable discriminant values
4150 attr::ReprAny | attr::ReprExtern => {
4151 disr_vals.push(current_disr_val);
4153 attr::ReprInt(sp, ity) => {
4154 if !disr_in_range(ccx, ity, current_disr_val) {
4155 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4156 "discriminant value outside specified type");
4157 span_note!(&mut err, sp,
4158 "discriminant type specified here");
4162 // Error reported elsewhere.
4163 attr::ReprSimd | attr::ReprPacked => {}
4168 let def_id = ccx.tcx.map.local_def_id(id);
4169 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4171 if hint != attr::ReprAny && vs.is_empty() {
4172 span_err!(ccx.tcx.sess, sp, E0084,
4173 "unsupported representation for zero-variant enum");
4176 do_check(ccx, vs, id, hint);
4178 check_representable(ccx.tcx, sp, id, "enum");
4181 // Returns the type parameter count and the type for the given definition.
4182 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4185 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4187 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4188 let typ = fcx.local_ty(sp, nid);
4189 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4190 ty::GenericPredicates::empty())
4192 Def::Fn(id) | Def::Method(id) |
4193 Def::Static(id, _) | Def::Variant(_, id) |
4194 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4195 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4200 Def::AssociatedTy(..) |
4204 Def::ForeignMod(..) |
4208 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4213 // Instantiates the given path, which must refer to an item with the given
4214 // number of type parameters and type.
4215 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4216 segments: &[hir::PathSegment],
4217 type_scheme: TypeScheme<'tcx>,
4218 type_predicates: &ty::GenericPredicates<'tcx>,
4219 opt_self_ty: Option<Ty<'tcx>>,
4222 node_id: ast::NodeId) {
4223 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4229 // We need to extract the type parameters supplied by the user in
4230 // the path `path`. Due to the current setup, this is a bit of a
4231 // tricky-process; the problem is that resolve only tells us the
4232 // end-point of the path resolution, and not the intermediate steps.
4233 // Luckily, we can (at least for now) deduce the intermediate steps
4234 // just from the end-point.
4236 // There are basically four cases to consider:
4238 // 1. Reference to a *type*, such as a struct or enum:
4240 // mod a { struct Foo<T> { ... } }
4242 // Because we don't allow types to be declared within one
4243 // another, a path that leads to a type will always look like
4244 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4245 // that only the final segment can have type parameters, and
4246 // they are located in the TypeSpace.
4248 // *Note:* Generally speaking, references to types don't
4249 // actually pass through this function, but rather the
4250 // `ast_ty_to_ty` function in `astconv`. However, in the case
4251 // of struct patterns (and maybe literals) we do invoke
4252 // `instantiate_path` to get the general type of an instance of
4253 // a struct. (In these cases, there are actually no type
4254 // parameters permitted at present, but perhaps we will allow
4255 // them in the future.)
4257 // 1b. Reference to an enum variant or tuple-like struct:
4259 // struct foo<T>(...)
4260 // enum E<T> { foo(...) }
4262 // In these cases, the parameters are declared in the type
4265 // 2. Reference to a *fn item*:
4269 // In this case, the path will again always have the form
4270 // `a::b::foo::<T>` where only the final segment should have
4271 // type parameters. However, in this case, those parameters are
4272 // declared on a value, and hence are in the `FnSpace`.
4274 // 3. Reference to a *method*:
4276 // impl<A> SomeStruct<A> {
4280 // Here we can have a path like
4281 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4282 // may appear in two places. The penultimate segment,
4283 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4284 // final segment, `foo::<B>` contains parameters in fn space.
4286 // 4. Reference to an *associated const*:
4288 // impl<A> AnotherStruct<A> {
4289 // const FOO: B = BAR;
4292 // The path in this case will look like
4293 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4294 // only will have parameters in TypeSpace.
4296 // The first step then is to categorize the segments appropriately.
4298 assert!(!segments.is_empty());
4300 let mut ufcs_associated = None;
4301 let mut segment_spaces: Vec<_>;
4303 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4309 Def::AssociatedTy(..) |
4312 Def::TyParam(..) => {
4313 // Everything but the final segment should have no
4314 // parameters at all.
4315 segment_spaces = vec![None; segments.len() - 1];
4316 segment_spaces.push(Some(subst::TypeSpace));
4319 // Case 2. Reference to a top-level value.
4322 Def::Static(..) => {
4323 segment_spaces = vec![None; segments.len() - 1];
4324 segment_spaces.push(Some(subst::FnSpace));
4327 // Case 3. Reference to a method.
4328 Def::Method(def_id) => {
4329 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4331 ty::TraitContainer(trait_did) => {
4332 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4334 ty::ImplContainer(_) => {}
4337 if segments.len() >= 2 {
4338 segment_spaces = vec![None; segments.len() - 2];
4339 segment_spaces.push(Some(subst::TypeSpace));
4340 segment_spaces.push(Some(subst::FnSpace));
4342 // `<T>::method` will end up here, and so can `T::method`.
4343 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4344 segment_spaces = vec![Some(subst::FnSpace)];
4345 ufcs_associated = Some((container, self_ty));
4349 Def::AssociatedConst(def_id) => {
4350 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4352 ty::TraitContainer(trait_did) => {
4353 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4355 ty::ImplContainer(_) => {}
4358 if segments.len() >= 2 {
4359 segment_spaces = vec![None; segments.len() - 2];
4360 segment_spaces.push(Some(subst::TypeSpace));
4361 segment_spaces.push(None);
4363 // `<T>::CONST` will end up here, and so can `T::CONST`.
4364 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4365 segment_spaces = vec![None];
4366 ufcs_associated = Some((container, self_ty));
4370 // Other cases. Various nonsense that really shouldn't show up
4371 // here. If they do, an error will have been reported
4372 // elsewhere. (I hope)
4374 Def::ForeignMod(..) |
4379 segment_spaces = vec![None; segments.len()];
4382 assert_eq!(segment_spaces.len(), segments.len());
4384 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4385 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4386 // type parameters are not mandatory.
4387 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4389 debug!("segment_spaces={:?}", segment_spaces);
4391 // Next, examine the definition, and determine how many type
4392 // parameters we expect from each space.
4393 let type_defs = &type_scheme.generics.types;
4394 let region_defs = &type_scheme.generics.regions;
4396 // Now that we have categorized what space the parameters for each
4397 // segment belong to, let's sort out the parameters that the user
4398 // provided (if any) into their appropriate spaces. We'll also report
4399 // errors if type parameters are provided in an inappropriate place.
4400 let mut substs = Substs::empty();
4401 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4404 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4408 push_explicit_parameters_from_segment_to_substs(fcx,
4418 if let Some(self_ty) = opt_self_ty {
4419 if type_defs.len(subst::SelfSpace) == 1 {
4420 substs.types.push(subst::SelfSpace, self_ty);
4424 // Now we have to compare the types that the user *actually*
4425 // provided against the types that were *expected*. If the user
4426 // did not provide any types, then we want to substitute inference
4427 // variables. If the user provided some types, we may still need
4428 // to add defaults. If the user provided *too many* types, that's
4430 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4431 adjust_type_parameters(fcx, span, space, type_defs,
4432 require_type_space, &mut substs);
4433 assert_eq!(substs.types.len(space), type_defs.len(space));
4435 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4436 assert_eq!(substs.regions().len(space), region_defs.len(space));
4439 // The things we are substituting into the type should not contain
4440 // escaping late-bound regions, and nor should the base type scheme.
4441 assert!(!substs.has_regions_escaping_depth(0));
4442 assert!(!type_scheme.has_escaping_regions());
4444 // Add all the obligations that are required, substituting and
4445 // normalized appropriately.
4446 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4447 fcx.add_obligations_for_parameters(
4448 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4451 // Substitute the values for the type parameters into the type of
4452 // the referenced item.
4453 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4456 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4457 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4458 // is inherent, there is no `Self` parameter, instead, the impl needs
4459 // type parameters, which we can infer by unifying the provided `Self`
4460 // with the substituted impl type.
4461 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4462 assert_eq!(substs.types.len(subst::TypeSpace),
4463 impl_scheme.generics.types.len(subst::TypeSpace));
4464 assert_eq!(substs.regions().len(subst::TypeSpace),
4465 impl_scheme.generics.regions.len(subst::TypeSpace));
4467 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4468 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4469 fcx.tcx().sess.span_bug(span,
4471 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4477 debug!("instantiate_path: type of {:?} is {:?}",
4480 fcx.write_ty(node_id, ty_substituted);
4481 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4484 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4485 /// parameters are provided, then reports an error and clears the output vector.
4487 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4488 /// use inference variables. This seems less likely to lead to derived errors.
4490 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4491 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4492 /// here because we can easily use the precise span of the N+1'th parameter.
4493 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4494 fcx: &FnCtxt<'a, 'tcx>,
4495 space: subst::ParamSpace,
4497 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4498 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4499 segment: &hir::PathSegment,
4500 substs: &mut Substs<'tcx>)
4502 match segment.parameters {
4503 hir::AngleBracketedParameters(ref data) => {
4504 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4505 fcx, space, type_defs, region_defs, data, substs);
4508 hir::ParenthesizedParameters(ref data) => {
4509 span_err!(fcx.tcx().sess, span, E0238,
4510 "parenthesized parameters may only be used with a trait");
4511 push_explicit_parenthesized_parameters_from_segment_to_substs(
4512 fcx, space, span, type_defs, data, substs);
4517 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4518 fcx: &FnCtxt<'a, 'tcx>,
4519 space: subst::ParamSpace,
4520 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4521 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4522 data: &hir::AngleBracketedParameterData,
4523 substs: &mut Substs<'tcx>)
4526 let type_count = type_defs.len(space);
4527 assert_eq!(substs.types.len(space), 0);
4528 for (i, typ) in data.types.iter().enumerate() {
4529 let t = fcx.to_ty(&typ);
4531 substs.types.push(space, t);
4532 } else if i == type_count {
4533 span_err!(fcx.tcx().sess, typ.span, E0087,
4534 "too many type parameters provided: \
4535 expected at most {} parameter{}, \
4536 found {} parameter{}",
4538 if type_count == 1 {""} else {"s"},
4540 if data.types.len() == 1 {""} else {"s"});
4541 substs.types.truncate(space, 0);
4547 if !data.bindings.is_empty() {
4548 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4549 "unexpected binding of associated item in expression path \
4550 (only allowed in type paths)");
4554 let region_count = region_defs.len(space);
4555 assert_eq!(substs.regions().len(space), 0);
4556 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4557 let r = ast_region_to_region(fcx.tcx(), lifetime);
4558 if i < region_count {
4559 substs.mut_regions().push(space, r);
4560 } else if i == region_count {
4561 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4562 "too many lifetime parameters provided: \
4563 expected {} parameter{}, found {} parameter{}",
4565 if region_count == 1 {""} else {"s"},
4566 data.lifetimes.len(),
4567 if data.lifetimes.len() == 1 {""} else {"s"});
4568 substs.mut_regions().truncate(space, 0);
4576 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4577 /// but intended for `Foo(A,B) -> C` form. This expands to
4578 /// roughly the same thing as `Foo<(A,B),C>`. One important
4579 /// difference has to do with the treatment of anonymous
4580 /// regions, which are translated into bound regions (NYI).
4581 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4582 fcx: &FnCtxt<'a, 'tcx>,
4583 space: subst::ParamSpace,
4585 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4586 data: &hir::ParenthesizedParameterData,
4587 substs: &mut Substs<'tcx>)
4589 let type_count = type_defs.len(space);
4591 span_err!(fcx.tcx().sess, span, E0167,
4592 "parenthesized form always supplies 2 type parameters, \
4593 but only {} parameter(s) were expected",
4597 let input_tys: Vec<Ty> =
4598 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4600 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4602 if type_count >= 1 {
4603 substs.types.push(space, tuple_ty);
4606 let output_ty: Option<Ty> =
4607 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4610 output_ty.unwrap_or(fcx.tcx().mk_nil());
4612 if type_count >= 2 {
4613 substs.types.push(space, output_ty);
4617 fn adjust_type_parameters<'a, 'tcx>(
4618 fcx: &FnCtxt<'a, 'tcx>,
4621 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4622 require_type_space: bool,
4623 substs: &mut Substs<'tcx>)
4625 let provided_len = substs.types.len(space);
4626 let desired = defs.get_slice(space);
4627 let required_len = desired.iter()
4628 .take_while(|d| d.default.is_none())
4631 debug!("adjust_type_parameters(space={:?}, \
4640 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4641 assert!(provided_len <= desired.len());
4643 // Nothing specified at all: supply inference variables for
4645 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4646 substs.types.replace(space, Vec::new());
4647 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4651 // Too few parameters specified: report an error and use Err
4653 if provided_len < required_len {
4655 if desired.len() != required_len { "at least " } else { "" };
4656 span_err!(fcx.tcx().sess, span, E0089,
4657 "too few type parameters provided: expected {}{} parameter{}, \
4658 found {} parameter{}",
4659 qualifier, required_len,
4660 if required_len == 1 {""} else {"s"},
4662 if provided_len == 1 {""} else {"s"});
4663 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4667 // Otherwise, add in any optional parameters that the user
4668 // omitted. The case of *too many* parameters is handled
4670 // push_explicit_parameters_from_segment_to_substs(). Note
4671 // that the *default* type are expressed in terms of all prior
4672 // parameters, so we have to substitute as we go with the
4673 // partial substitution that we have built up.
4674 for i in provided_len..desired.len() {
4675 let default = desired[i].default.unwrap();
4676 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4677 substs.types.push(space, default);
4679 assert_eq!(substs.types.len(space), desired.len());
4681 debug!("Final substs: {:?}", substs);
4684 fn adjust_region_parameters(
4688 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4689 substs: &mut Substs)
4691 let provided_len = substs.mut_regions().len(space);
4692 let desired = defs.get_slice(space);
4694 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4695 assert!(provided_len <= desired.len());
4697 // If nothing was provided, just use inference variables.
4698 if provided_len == 0 {
4699 substs.mut_regions().replace(
4701 fcx.infcx().region_vars_for_defs(span, desired));
4705 // If just the right number were provided, everybody is happy.
4706 if provided_len == desired.len() {
4710 // Otherwise, too few were provided. Report an error and then
4711 // use inference variables.
4712 span_err!(fcx.tcx().sess, span, E0090,
4713 "too few lifetime parameters provided: expected {} parameter{}, \
4714 found {} parameter{}",
4716 if desired.len() == 1 {""} else {"s"},
4718 if provided_len == 1 {""} else {"s"});
4720 substs.mut_regions().replace(
4722 fcx.infcx().region_vars_for_defs(span, desired));
4726 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4730 where F: Fn() -> Ty<'tcx>
4732 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4735 let alternative = f();
4738 if alternative.is_ty_var() || alternative.references_error() {
4739 fcx.type_error_message(sp, |_actual| {
4740 "the type of this value must be known in this context".to_string()
4742 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4743 ty = fcx.tcx().types.err;
4745 demand::suptype(fcx, sp, alternative, ty);
4753 // Resolves `typ` by a single level if `typ` is a type variable. If no
4754 // resolution is possible, then an error is reported.
4755 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4760 structurally_resolve_type_or_else(fcx, sp, ty, || {
4765 // Returns true if b contains a break that can exit from b
4766 pub fn may_break(cx: &TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4767 // First: is there an unlabeled break immediately
4769 (loop_query(&b, |e| {
4771 hir::ExprBreak(None) => true,
4775 // Second: is there a labeled break with label
4776 // <id> nested anywhere inside the loop?
4777 (block_query(b, |e| {
4778 if let hir::ExprBreak(Some(_)) = e.node {
4779 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4786 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4787 tps: &[hir::TyParam],
4789 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4792 // make a vector of booleans initially false, set to true when used
4793 if tps.is_empty() { return; }
4794 let mut tps_used = vec![false; tps.len()];
4796 for leaf_ty in ty.walk() {
4797 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4798 debug!("Found use of ty param num {}", idx);
4799 tps_used[idx as usize] = true;
4803 for (i, b) in tps_used.iter().enumerate() {
4805 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4806 "type parameter `{}` is unused",