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;
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::privacy::{AllPublic, LastMod};
95 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
96 use middle::traits::{self, report_fulfillment_errors};
97 use middle::ty::{GenericPredicates, TypeScheme};
98 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
99 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
100 use middle::ty::{self, ToPolyTraitRef, Ty};
101 use middle::ty::{MethodCall, MethodCallee};
102 use middle::ty::adjustment;
103 use middle::ty::error::TypeError;
104 use middle::ty::fold::{TypeFolder, TypeFoldable};
105 use middle::ty::util::Representability;
106 use require_c_abi_if_variadic;
107 use rscope::{ElisionFailureInfo, RegionScope};
108 use session::Session;
109 use {CrateCtxt, lookup_full_def};
112 use util::common::{block_query, ErrorReported, indenter, loop_query};
113 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
115 use std::cell::{Cell, Ref, RefCell};
116 use std::collections::{HashSet};
117 use std::mem::replace;
121 use syntax::attr::AttrMetaMethods;
122 use syntax::codemap::{self, Span, Spanned};
123 use syntax::errors::DiagnosticBuilder;
124 use syntax::parse::token::{self, InternedString};
126 use syntax::util::lev_distance::find_best_match_for_name;
128 use rustc_front::intravisit::{self, Visitor};
129 use rustc_front::hir;
130 use rustc_front::hir::Visibility;
131 use rustc_front::print::pprust;
132 use rustc_back::slice;
151 /// closures defined within the function. For example:
154 /// bar(move|| { ... })
157 /// Here, the function `foo()` and the closure passed to
158 /// `bar()` will each have their own `FnCtxt`, but they will
159 /// share the inherited fields.
160 pub struct Inherited<'a, 'tcx: 'a> {
161 infcx: infer::InferCtxt<'a, 'tcx>,
162 locals: RefCell<NodeMap<Ty<'tcx>>>,
164 tables: &'a RefCell<ty::Tables<'tcx>>,
166 // When we process a call like `c()` where `c` is a closure type,
167 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
168 // `FnOnce` closure. In that case, we defer full resolution of the
169 // call until upvar inference can kick in and make the
170 // decision. We keep these deferred resolutions grouped by the
171 // def-id of the closure, so that once we decide, we can easily go
172 // back and process them.
173 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
175 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
178 trait DeferredCallResolution<'tcx> {
179 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
182 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
184 /// When type-checking an expression, we propagate downward
185 /// whatever type hint we are able in the form of an `Expectation`.
186 #[derive(Copy, Clone, Debug)]
187 pub enum Expectation<'tcx> {
188 /// We know nothing about what type this expression should have.
191 /// This expression should have the type given (or some subtype)
192 ExpectHasType(Ty<'tcx>),
194 /// This expression will be cast to the `Ty`
195 ExpectCastableToType(Ty<'tcx>),
197 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
198 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
199 ExpectRvalueLikeUnsized(Ty<'tcx>),
202 impl<'tcx> Expectation<'tcx> {
203 // Disregard "castable to" expectations because they
204 // can lead us astray. Consider for example `if cond
205 // {22} else {c} as u8` -- if we propagate the
206 // "castable to u8" constraint to 22, it will pick the
207 // type 22u8, which is overly constrained (c might not
208 // be a u8). In effect, the problem is that the
209 // "castable to" expectation is not the tightest thing
210 // we can say, so we want to drop it in this case.
211 // The tightest thing we can say is "must unify with
212 // else branch". Note that in the case of a "has type"
213 // constraint, this limitation does not hold.
215 // If the expected type is just a type variable, then don't use
216 // an expected type. Otherwise, we might write parts of the type
217 // when checking the 'then' block which are incompatible with the
219 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
221 ExpectHasType(ety) => {
222 let ety = fcx.infcx().shallow_resolve(ety);
223 if !ety.is_ty_var() {
229 ExpectRvalueLikeUnsized(ety) => {
230 ExpectRvalueLikeUnsized(ety)
237 #[derive(Copy, Clone)]
238 pub struct UnsafetyState {
239 pub def: ast::NodeId,
240 pub unsafety: hir::Unsafety,
241 pub unsafe_push_count: u32,
246 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
247 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
250 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
251 match self.unsafety {
252 // If this unsafe, then if the outer function was already marked as
253 // unsafe we shouldn't attribute the unsafe'ness to the block. This
254 // way the block can be warned about instead of ignoring this
255 // extraneous block (functions are never warned about).
256 hir::Unsafety::Unsafe if self.from_fn => *self,
259 let (unsafety, def, count) = match blk.rules {
260 hir::PushUnsafeBlock(..) =>
261 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
262 hir::PopUnsafeBlock(..) =>
263 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
264 hir::UnsafeBlock(..) =>
265 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
266 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
267 (unsafety, self.def, self.unsafe_push_count),
269 UnsafetyState{ def: def,
271 unsafe_push_count: count,
279 pub struct FnCtxt<'a, 'tcx: 'a> {
280 body_id: ast::NodeId,
282 // This flag is set to true if, during the writeback phase, we encounter
283 // a type error in this function.
284 writeback_errors: Cell<bool>,
286 // Number of errors that had been reported when we started
287 // checking this function. On exit, if we find that *more* errors
288 // have been reported, we will skip regionck and other work that
289 // expects the types within the function to be consistent.
290 err_count_on_creation: usize,
292 ret_ty: ty::FnOutput<'tcx>,
294 ps: RefCell<UnsafetyState>,
296 inh: &'a Inherited<'a, 'tcx>,
298 ccx: &'a CrateCtxt<'a, 'tcx>,
301 impl<'a, 'tcx> Inherited<'a, 'tcx> {
302 fn new(tcx: &'a ty::ctxt<'tcx>,
303 tables: &'a RefCell<ty::Tables<'tcx>>,
304 param_env: ty::ParameterEnvironment<'a, 'tcx>)
305 -> Inherited<'a, 'tcx> {
308 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
309 locals: RefCell::new(NodeMap()),
311 deferred_call_resolutions: RefCell::new(DefIdMap()),
312 deferred_cast_checks: RefCell::new(Vec::new()),
316 fn normalize_associated_types_in<T>(&self,
318 body_id: ast::NodeId,
321 where T : TypeFoldable<'tcx>
323 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
324 assoc::normalize_associated_types_in(&self.infcx,
333 // Used by check_const and check_enum_variants
334 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
335 inh: &'a Inherited<'a, 'tcx>,
336 rty: ty::FnOutput<'tcx>,
337 body_id: ast::NodeId)
338 -> FnCtxt<'a, 'tcx> {
341 writeback_errors: Cell::new(false),
342 err_count_on_creation: ccx.tcx.sess.err_count(),
344 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
350 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
351 tables: &'a RefCell<ty::Tables<'tcx>>)
352 -> Inherited<'a, 'tcx> {
353 // It's kind of a kludge to manufacture a fake function context
354 // and statement context, but we might as well do write the code only once
355 let param_env = ccx.tcx.empty_parameter_environment();
356 Inherited::new(ccx.tcx, &tables, param_env)
359 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
360 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
362 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
363 fn visit_item(&mut self, i: &'tcx hir::Item) {
364 check_item_type(self.ccx, i);
365 intravisit::walk_item(self, i);
368 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
370 hir::TyFixedLengthVec(_, ref expr) => {
371 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
376 intravisit::walk_ty(self, t);
380 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
381 fn visit_item(&mut self, i: &'tcx hir::Item) {
382 check_item_body(self.ccx, i);
386 pub fn check_wf_new(ccx: &CrateCtxt) {
387 ccx.tcx.sess.abort_if_new_errors(|| {
388 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
389 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
393 pub fn check_item_types(ccx: &CrateCtxt) {
394 ccx.tcx.sess.abort_if_new_errors(|| {
395 let mut visit = CheckItemTypesVisitor { ccx: ccx };
396 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
400 pub fn check_item_bodies(ccx: &CrateCtxt) {
401 ccx.tcx.sess.abort_if_new_errors(|| {
402 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
403 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
407 pub fn check_drop_impls(ccx: &CrateCtxt) {
408 ccx.tcx.sess.abort_if_new_errors(|| {
409 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
410 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
411 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
413 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
414 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
415 if drop_impl_did.is_local() {
416 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
419 assert!(ccx.tcx.sess.has_errors());
427 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
428 decl: &'tcx hir::FnDecl,
429 body: &'tcx hir::Block,
433 param_env: ty::ParameterEnvironment<'a, 'tcx>)
436 ty::TyBareFn(_, ref fn_ty) => {
437 let tables = RefCell::new(ty::Tables::empty());
438 let inh = Inherited::new(ccx.tcx, &tables, param_env);
440 // Compute the fty from point of view of inside fn.
441 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
443 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
445 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
447 inh.normalize_associated_types_in(body.span,
451 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
452 decl, fn_id, body, &inh);
454 fcx.select_all_obligations_and_apply_defaults();
455 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
456 fcx.select_obligations_where_possible();
458 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
460 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
461 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
463 _ => ccx.tcx.sess.impossible_case(body.span,
464 "check_bare_fn: function type expected")
468 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
469 fcx: &'a FnCtxt<'a, 'tcx>
472 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
473 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
476 // infer the variable's type
477 let var_ty = self.fcx.infcx().next_ty_var();
478 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
482 // take type that the user specified
483 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
490 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
491 // Add explicitly-declared locals.
492 fn visit_local(&mut self, local: &'tcx hir::Local) {
493 let o_ty = match local.ty {
494 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
497 self.assign(local.span, local.id, o_ty);
498 debug!("Local variable {:?} is assigned type {}",
500 self.fcx.infcx().ty_to_string(
501 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
502 intravisit::walk_local(self, local);
505 // Add pattern bindings.
506 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
507 if let hir::PatIdent(_, ref path1, _) = p.node {
508 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
509 let var_ty = self.assign(p.span, p.id, None);
511 self.fcx.require_type_is_sized(var_ty, p.span,
512 traits::VariableType(p.id));
514 debug!("Pattern binding {} is assigned to {} with type {:?}",
516 self.fcx.infcx().ty_to_string(
517 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
521 intravisit::walk_pat(self, p);
524 fn visit_block(&mut self, b: &'tcx hir::Block) {
525 // non-obvious: the `blk` variable maps to region lb, so
526 // we have to keep this up-to-date. This
527 // is... unfortunate. It'd be nice to not need this.
528 intravisit::walk_block(self, b);
531 // Since an expr occurs as part of the type fixed size arrays we
532 // need to record the type for that node
533 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
535 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
536 self.visit_ty(&**ty);
537 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
539 hir::TyBareFn(ref function_declaration) => {
540 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
541 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
543 _ => intravisit::walk_ty(self, t)
547 // Don't descend into the bodies of nested closures
548 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
549 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
552 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
553 /// body and returns the function context used for that purpose, since in the case of a fn item
554 /// there is still a bit more to do.
557 /// * inherited: other fields inherited from the enclosing fn (if any)
558 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
559 unsafety: hir::Unsafety,
560 unsafety_id: ast::NodeId,
561 fn_sig: &ty::FnSig<'tcx>,
562 decl: &'tcx hir::FnDecl,
564 body: &'tcx hir::Block,
565 inherited: &'a Inherited<'a, 'tcx>)
569 let err_count_on_creation = tcx.sess.err_count();
571 let arg_tys = &fn_sig.inputs;
572 let ret_ty = fn_sig.output;
574 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
579 // Create the function context. This is either derived from scratch or,
580 // in the case of function expressions, based on the outer context.
583 writeback_errors: Cell::new(false),
584 err_count_on_creation: err_count_on_creation,
586 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
591 if let ty::FnConverging(ret_ty) = ret_ty {
592 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
595 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
597 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
600 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
602 // Add formal parameters.
603 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
604 // The type of the argument must be well-formed.
606 // NB -- this is now checked in wfcheck, but that
607 // currently only results in warnings, so we issue an
608 // old-style WF obligation here so that we still get the
609 // errors that we used to get.
610 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
612 // Create type variables for each argument.
613 pat_util::pat_bindings(
616 |_bm, pat_id, sp, _path| {
617 let var_ty = visit.assign(sp, pat_id, None);
618 fcx.require_type_is_sized(var_ty, sp,
619 traits::VariableType(pat_id));
622 // Check the pattern.
625 map: pat_id_map(&tcx.def_map, &*input.pat),
627 _match::check_pat(&pcx, &*input.pat, *arg_ty);
630 visit.visit_block(body);
633 check_block_with_expected(&fcx, body, match ret_ty {
634 ty::FnConverging(result_type) => ExpectHasType(result_type),
635 ty::FnDiverging => NoExpectation
638 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
639 fcx.write_ty(input.id, arg);
645 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
648 check_representable(tcx, span, id, "struct");
650 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
651 check_simd(tcx, span, id);
655 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
656 debug!("check_item_type(it.id={}, it.name={})",
658 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
659 let _indenter = indenter();
661 // Consts can play a role in type-checking, so they are included here.
662 hir::ItemStatic(_, _, ref e) |
663 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
664 hir::ItemEnum(ref enum_definition, _) => {
665 check_enum_variants(ccx,
667 &enum_definition.variants,
670 hir::ItemFn(..) => {} // entirely within check_item_body
671 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
672 debug!("ItemImpl {} with id {}", it.name, it.id);
673 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
674 Some(impl_trait_ref) => {
675 check_impl_items_against_trait(ccx,
683 hir::ItemTrait(_, ref generics, _, _) => {
684 check_trait_on_unimplemented(ccx, generics, it);
686 hir::ItemStruct(..) => {
687 check_struct(ccx, it.id, it.span);
689 hir::ItemTy(_, ref generics) => {
690 let pty_ty = ccx.tcx.node_id_to_type(it.id);
691 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
693 hir::ItemForeignMod(ref m) => {
694 if m.abi == abi::RustIntrinsic {
695 for item in &m.items {
696 intrinsic::check_intrinsic_type(ccx, item);
698 } else if m.abi == abi::PlatformIntrinsic {
699 for item in &m.items {
700 intrinsic::check_platform_intrinsic_type(ccx, item);
703 for item in &m.items {
704 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
705 if !pty.generics.types.is_empty() {
706 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
707 "foreign items may not have type parameters");
708 span_help!(&mut err, item.span,
709 "consider using specialization instead of \
714 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
715 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
720 _ => {/* nothing to do */ }
724 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
725 debug!("check_item_body(it.id={}, it.name={})",
727 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
728 let _indenter = indenter();
730 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
731 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
732 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
733 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
735 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
736 debug!("ItemImpl {} with id {}", it.name, it.id);
738 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
740 for impl_item in impl_items {
741 match impl_item.node {
742 hir::ImplItemKind::Const(_, ref expr) => {
743 check_const(ccx, impl_item.span, &*expr, impl_item.id)
745 hir::ImplItemKind::Method(ref sig, ref body) => {
746 check_method_body(ccx, &impl_pty.generics, sig, body,
747 impl_item.id, impl_item.span);
749 hir::ImplItemKind::Type(_) => {
750 // Nothing to do here.
755 hir::ItemTrait(_, _, _, ref trait_items) => {
756 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
757 for trait_item in trait_items {
758 match trait_item.node {
759 hir::ConstTraitItem(_, Some(ref expr)) => {
760 check_const(ccx, trait_item.span, &*expr, trait_item.id)
762 hir::MethodTraitItem(ref sig, Some(ref body)) => {
763 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
765 check_method_body(ccx, &trait_def.generics, sig, body,
766 trait_item.id, trait_item.span);
768 hir::MethodTraitItem(ref sig, None) => {
769 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
771 hir::ConstTraitItem(_, None) |
772 hir::TypeTraitItem(..) => {
778 _ => {/* nothing to do */ }
782 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
784 constness: hir::Constness)
787 hir::Constness::NotConst => {
790 hir::Constness::Const => {
791 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
796 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
797 generics: &hir::Generics,
799 if let Some(ref attr) = item.attrs.iter().find(|a| {
800 a.check_name("rustc_on_unimplemented")
802 if let Some(ref istring) = attr.value_str() {
803 let parser = Parser::new(&istring);
804 let types = &*generics.ty_params;
805 for token in parser {
807 Piece::String(_) => (), // Normal string, no need to check it
808 Piece::NextArgument(a) => match a.position {
809 // `{Self}` is allowed
810 Position::ArgumentNamed(s) if s == "Self" => (),
811 // So is `{A}` if A is a type parameter
812 Position::ArgumentNamed(s) => match types.iter().find(|t| {
817 span_err!(ccx.tcx.sess, attr.span, E0230,
818 "there is no type parameter \
823 // `{:1}` and `{}` are not to be used
824 Position::ArgumentIs(_) | Position::ArgumentNext => {
825 span_err!(ccx.tcx.sess, attr.span, E0231,
826 "only named substitution \
827 parameters are allowed");
833 span_err!(ccx.tcx.sess, attr.span, E0232,
834 "this attribute must have a value, \
835 eg `#[rustc_on_unimplemented = \"foo\"]`")
840 /// Type checks a method body.
844 /// * `item_generics`: generics defined on the impl/trait that contains
846 /// * `self_bound`: bound for the `Self` type parameter, if any
847 /// * `method`: the method definition
848 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
849 item_generics: &ty::Generics<'tcx>,
850 sig: &'tcx hir::MethodSig,
851 body: &'tcx hir::Block,
852 id: ast::NodeId, span: Span) {
853 debug!("check_method_body(item_generics={:?}, id={})",
855 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
857 let fty = ccx.tcx.node_id_to_type(id);
858 debug!("check_method_body: fty={:?}", fty);
860 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
863 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
865 impl_trait_ref: &ty::TraitRef<'tcx>,
866 impl_items: &[hir::ImplItem]) {
867 // Locate trait methods
869 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
870 let mut overridden_associated_type = None;
872 // Check existing impl methods to see if they are both present in trait
873 // and compatible with trait signature
874 for impl_item in impl_items {
875 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
876 let ty_trait_item = trait_items.iter()
877 .find(|ac| ac.name() == ty_impl_item.name());
879 if let Some(ty_trait_item) = ty_trait_item {
880 match impl_item.node {
881 hir::ImplItemKind::Const(..) => {
882 let impl_const = match ty_impl_item {
883 ty::ConstTraitItem(ref cti) => cti,
884 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
887 // Find associated const definition.
888 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
889 compare_const_impl(ccx.tcx,
895 span_err!(tcx.sess, impl_item.span, E0323,
896 "item `{}` is an associated const, \
897 which doesn't match its trait `{:?}`",
902 hir::ImplItemKind::Method(ref sig, ref body) => {
903 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
905 let impl_method = match ty_impl_item {
906 ty::MethodTraitItem(ref mti) => mti,
907 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
910 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
911 compare_impl_method(ccx.tcx,
918 span_err!(tcx.sess, impl_item.span, E0324,
919 "item `{}` is an associated method, \
920 which doesn't match its trait `{:?}`",
925 hir::ImplItemKind::Type(_) => {
926 let impl_type = match ty_impl_item {
927 ty::TypeTraitItem(ref tti) => tti,
928 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
931 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
932 if let Some(_) = at.ty {
933 overridden_associated_type = Some(impl_item);
936 span_err!(tcx.sess, impl_item.span, E0325,
937 "item `{}` is an associated type, \
938 which doesn't match its trait `{:?}`",
947 // Check for missing items from trait
948 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
949 let mut missing_items = Vec::new();
950 let mut invalidated_items = Vec::new();
951 let associated_type_overridden = overridden_associated_type.is_some();
952 for trait_item in trait_items.iter() {
954 ty::ConstTraitItem(ref associated_const) => {
955 let is_implemented = impl_items.iter().any(|ii| {
957 hir::ImplItemKind::Const(..) => {
958 ii.name == associated_const.name
963 let is_provided = associated_const.has_value;
967 missing_items.push(associated_const.name);
968 } else if associated_type_overridden {
969 invalidated_items.push(associated_const.name);
973 ty::MethodTraitItem(ref trait_method) => {
975 impl_items.iter().any(|ii| {
977 hir::ImplItemKind::Method(..) => {
978 ii.name == trait_method.name
984 provided_methods.iter().any(|m| m.name == trait_method.name);
987 missing_items.push(trait_method.name);
988 } else if associated_type_overridden {
989 invalidated_items.push(trait_method.name);
993 ty::TypeTraitItem(ref associated_type) => {
994 let is_implemented = impl_items.iter().any(|ii| {
996 hir::ImplItemKind::Type(_) => {
997 ii.name == associated_type.name
1002 let is_provided = associated_type.ty.is_some();
1003 if !is_implemented {
1005 missing_items.push(associated_type.name);
1006 } else if associated_type_overridden {
1007 invalidated_items.push(associated_type.name);
1014 if !missing_items.is_empty() {
1015 span_err!(tcx.sess, impl_span, E0046,
1016 "not all trait items implemented, missing: `{}`",
1017 missing_items.iter()
1018 .map(|name| name.to_string())
1019 .collect::<Vec<_>>().join("`, `"))
1022 if !invalidated_items.is_empty() {
1023 let invalidator = overridden_associated_type.unwrap();
1024 span_err!(tcx.sess, invalidator.span, E0399,
1025 "the following trait items need to be reimplemented \
1026 as `{}` was overridden: `{}`",
1028 invalidated_items.iter()
1029 .map(|name| name.to_string())
1030 .collect::<Vec<_>>().join("`, `"))
1034 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1041 if t_cast.references_error() || t_expr.references_error() {
1044 let tstr = fcx.infcx().ty_to_string(t_cast);
1045 let mut err = fcx.type_error_struct(span, |actual| {
1046 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1049 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1050 let mtstr = match mt {
1051 hir::MutMutable => "mut ",
1052 hir::MutImmutable => ""
1054 if t_cast.is_trait() {
1055 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1057 err.span_suggestion(t_span,
1058 "try casting to a reference instead:",
1059 format!("&{}{}", mtstr, s));
1062 span_help!(err, t_span,
1063 "did you mean `&{}{}`?", mtstr, tstr),
1066 span_help!(err, span,
1067 "consider using an implicit coercion to `&{}{}` instead",
1072 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1074 err.span_suggestion(t_span,
1075 "try casting to a `Box` instead:",
1076 format!("Box<{}>", s));
1079 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1083 span_help!(err, e_span,
1084 "consider using a box or reference as appropriate");
1088 fcx.write_error(id);
1092 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1093 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1095 fn get_item_type_scheme(&self, _: Span, id: DefId)
1096 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1098 Ok(self.tcx().lookup_item_type(id))
1101 fn get_trait_def(&self, _: Span, id: DefId)
1102 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1104 Ok(self.tcx().lookup_trait_def(id))
1107 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1108 // all super predicates are ensured during collect pass
1112 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1113 Some(&self.inh.infcx.parameter_environment.free_substs)
1116 fn get_type_parameter_bounds(&self,
1118 node_id: ast::NodeId)
1119 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1121 let def = self.tcx().type_parameter_def(node_id);
1122 let r = self.inh.infcx.parameter_environment
1125 .filter_map(|predicate| {
1127 ty::Predicate::Trait(ref data) => {
1128 if data.0.self_ty().is_param(def.space, def.index) {
1129 Some(data.to_poly_trait_ref())
1143 fn trait_defines_associated_type_named(&self,
1144 trait_def_id: DefId,
1145 assoc_name: ast::Name)
1148 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1149 trait_def.associated_type_names.contains(&assoc_name)
1153 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1154 substs: Option<&mut subst::Substs<'tcx>>,
1155 space: Option<subst::ParamSpace>,
1156 span: Span) -> Ty<'tcx> {
1157 // Grab the default doing subsitution
1158 let default = ty_param_def.and_then(|def| {
1159 def.default.map(|ty| type_variable::Default {
1160 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1162 def_id: def.default_def_id
1166 let ty_var = self.infcx().next_ty_var_with_default(default);
1168 // Finally we add the type variable to the substs
1171 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1175 fn projected_ty_from_poly_trait_ref(&self,
1177 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1178 item_name: ast::Name)
1181 let (trait_ref, _) =
1182 self.infcx().replace_late_bound_regions_with_fresh_var(
1184 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1187 self.normalize_associated_type(span, trait_ref, item_name)
1190 fn projected_ty(&self,
1192 trait_ref: ty::TraitRef<'tcx>,
1193 item_name: ast::Name)
1196 self.normalize_associated_type(span, trait_ref, item_name)
1200 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1201 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1203 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1207 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1208 &self.inh.infcx.parameter_environment
1211 pub fn sess(&self) -> &Session {
1215 pub fn err_count_since_creation(&self) -> usize {
1216 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1219 /// Resolves type variables in `ty` if possible. Unlike the infcx
1220 /// version, this version will also select obligations if it seems
1221 /// useful, in an effort to get more type information.
1222 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1223 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1225 // No TyInfer()? Nothing needs doing.
1226 if !ty.has_infer_types() {
1227 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1231 // If `ty` is a type variable, see whether we already know what it is.
1232 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1233 if !ty.has_infer_types() {
1234 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1238 // If not, try resolving any new fcx obligations that have cropped up.
1239 self.select_new_obligations();
1240 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1241 if !ty.has_infer_types() {
1242 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1246 // If not, try resolving *all* pending obligations as much as
1247 // possible. This can help substantially when there are
1248 // indirect dependencies that don't seem worth tracking
1250 self.select_obligations_where_possible();
1251 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1253 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1257 fn record_deferred_call_resolution(&self,
1258 closure_def_id: DefId,
1259 r: DeferredCallResolutionHandler<'tcx>) {
1260 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1261 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1264 fn remove_deferred_call_resolutions(&self,
1265 closure_def_id: DefId)
1266 -> Vec<DeferredCallResolutionHandler<'tcx>>
1268 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1269 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1272 pub fn tag(&self) -> String {
1273 let self_ptr: *const FnCtxt = self;
1274 format!("{:?}", self_ptr)
1277 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1278 match self.inh.locals.borrow().get(&nid) {
1281 span_err!(self.tcx().sess, span, E0513,
1282 "no type for local variable {}",
1284 self.tcx().types.err
1290 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1291 debug!("write_ty({}, {:?}) in fcx {}",
1292 node_id, ty, self.tag());
1293 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1296 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1297 if !substs.substs.is_noop() {
1298 debug!("write_substs({}, {:?}) in fcx {}",
1303 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1307 pub fn write_autoderef_adjustment(&self,
1308 node_id: ast::NodeId,
1310 self.write_adjustment(
1312 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1320 pub fn write_adjustment(&self,
1321 node_id: ast::NodeId,
1322 adj: adjustment::AutoAdjustment<'tcx>) {
1323 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1325 if adj.is_identity() {
1329 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1332 /// Basically whenever we are converting from a type scheme into
1333 /// the fn body space, we always want to normalize associated
1334 /// types as well. This function combines the two.
1335 fn instantiate_type_scheme<T>(&self,
1337 substs: &Substs<'tcx>,
1340 where T : TypeFoldable<'tcx>
1342 let value = value.subst(self.tcx(), substs);
1343 let result = self.normalize_associated_types_in(span, &value);
1344 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1351 /// As `instantiate_type_scheme`, but for the bounds found in a
1352 /// generic type scheme.
1353 fn instantiate_bounds(&self,
1355 substs: &Substs<'tcx>,
1356 bounds: &ty::GenericPredicates<'tcx>)
1357 -> ty::InstantiatedPredicates<'tcx>
1359 ty::InstantiatedPredicates {
1360 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1365 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1366 where T : TypeFoldable<'tcx>
1368 self.inh.normalize_associated_types_in(span, self.body_id, value)
1371 fn normalize_associated_type(&self,
1373 trait_ref: ty::TraitRef<'tcx>,
1374 item_name: ast::Name)
1377 let cause = traits::ObligationCause::new(span,
1379 traits::ObligationCauseCode::MiscObligation);
1384 .normalize_projection_type(self.infcx(),
1386 trait_ref: trait_ref,
1387 item_name: item_name,
1392 /// Instantiates the type in `did` with the generics in `path` and returns
1393 /// it (registering the necessary trait obligations along the way).
1395 /// Note that this function is only intended to be used with type-paths,
1396 /// not with value-paths.
1397 pub fn instantiate_type(&self,
1402 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1404 self.tcx().lookup_item_type(did);
1405 let type_predicates =
1406 self.tcx().lookup_predicates(did);
1407 let substs = astconv::ast_path_substs_for_ty(self, self,
1409 PathParamMode::Optional,
1410 &type_scheme.generics,
1411 path.segments.last().unwrap());
1412 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1414 self.instantiate_bounds(path.span, &substs, &type_predicates);
1415 self.add_obligations_for_parameters(
1416 traits::ObligationCause::new(
1419 traits::ItemObligation(did)),
1422 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1425 /// Return the dict-like variant corresponding to a given `Def`.
1426 pub fn def_struct_variant(&self,
1429 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1431 let (adt, variant) = match def {
1432 def::DefVariant(enum_id, variant_id, _) => {
1433 let adt = self.tcx().lookup_adt_def(enum_id);
1434 (adt, adt.variant_with_id(variant_id))
1436 def::DefTy(did, _) | def::DefStruct(did) => {
1437 let typ = self.tcx().lookup_item_type(did);
1438 if let ty::TyStruct(adt, _) = typ.ty.sty {
1439 (adt, adt.struct_variant())
1447 let var_kind = variant.kind();
1448 if var_kind == ty::VariantKind::Struct {
1449 Some((adt, variant))
1450 } else if var_kind == ty::VariantKind::Unit {
1451 if !self.tcx().sess.features.borrow().braced_empty_structs {
1452 let mut err = self.tcx().sess.struct_span_err(span,
1453 "empty structs and enum variants \
1454 with braces are unstable");
1455 fileline_help!(&mut err, span, "add #![feature(braced_empty_structs)] to \
1456 the crate features to enable");
1460 Some((adt, variant))
1466 pub fn write_nil(&self, node_id: ast::NodeId) {
1467 self.write_ty(node_id, self.tcx().mk_nil());
1469 pub fn write_error(&self, node_id: ast::NodeId) {
1470 self.write_ty(node_id, self.tcx().types.err);
1473 pub fn require_type_meets(&self,
1476 code: traits::ObligationCauseCode<'tcx>,
1477 bound: ty::BuiltinBound)
1479 self.register_builtin_bound(
1482 traits::ObligationCause::new(span, self.body_id, code));
1485 pub fn require_type_is_sized(&self,
1488 code: traits::ObligationCauseCode<'tcx>)
1490 self.require_type_meets(ty, span, code, ty::BoundSized);
1493 pub fn require_expr_have_sized_type(&self,
1495 code: traits::ObligationCauseCode<'tcx>)
1497 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1500 pub fn type_is_known_to_be_sized(&self,
1505 traits::type_known_to_meet_builtin_bound(self.infcx(),
1511 pub fn register_builtin_bound(&self,
1513 builtin_bound: ty::BuiltinBound,
1514 cause: traits::ObligationCause<'tcx>)
1516 self.inh.infcx.fulfillment_cx.borrow_mut()
1517 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1520 pub fn register_predicate(&self,
1521 obligation: traits::PredicateObligation<'tcx>)
1523 debug!("register_predicate({:?})",
1525 self.inh.infcx.fulfillment_cx
1527 .register_predicate_obligation(self.infcx(), obligation);
1530 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1531 let t = ast_ty_to_ty(self, self, ast_t);
1532 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1536 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1537 match self.inh.tables.borrow().node_types.get(&ex.id) {
1540 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1546 /// Apply `adjustment` to the type of `expr`
1547 pub fn adjust_expr_ty(&self,
1549 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1552 let raw_ty = self.expr_ty(expr);
1553 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1554 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1555 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1556 self.inh.tables.borrow().method_map.get(&method_call)
1557 .map(|method| resolve_ty(method.ty))
1561 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1562 match self.inh.tables.borrow().node_types.get(&id) {
1564 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1566 self.tcx().sess.bug(
1567 &format!("no type for node {}: {} in fcx {}",
1568 id, self.tcx().map.node_to_string(id),
1574 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1575 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1576 // it changes when we upgrade the snapshot compiler
1577 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1578 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1582 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1585 pub fn opt_node_ty_substs<F>(&self,
1588 F: FnOnce(&ty::ItemSubsts<'tcx>),
1590 match self.inh.tables.borrow().item_substs.get(&id) {
1596 pub fn mk_subty(&self,
1597 a_is_expected: bool,
1601 -> Result<(), TypeError<'tcx>> {
1602 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1605 pub fn mk_eqty(&self,
1606 a_is_expected: bool,
1610 -> Result<(), TypeError<'tcx>> {
1611 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1614 pub fn mk_subr(&self,
1615 origin: infer::SubregionOrigin<'tcx>,
1618 infer::mk_subr(self.infcx(), origin, sub, sup)
1621 pub fn type_error_message<M>(&self,
1624 actual_ty: Ty<'tcx>,
1625 err: Option<&TypeError<'tcx>>)
1626 where M: FnOnce(String) -> String,
1628 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1631 pub fn type_error_struct<M>(&self,
1634 actual_ty: Ty<'tcx>,
1635 err: Option<&TypeError<'tcx>>)
1636 -> DiagnosticBuilder<'tcx>
1637 where M: FnOnce(String) -> String,
1639 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1642 pub fn report_mismatched_types(&self,
1646 err: &TypeError<'tcx>) {
1647 self.infcx().report_mismatched_types(sp, e, a, err)
1650 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1651 /// outlive the region `r`.
1652 pub fn register_region_obligation(&self,
1655 cause: traits::ObligationCause<'tcx>)
1657 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1658 fulfillment_cx.register_region_obligation(ty, region, cause);
1661 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1662 /// outlive the region `r`.
1663 pub fn register_wf_obligation(&self,
1666 code: traits::ObligationCauseCode<'tcx>)
1668 // WF obligations never themselves fail, so no real need to give a detailed cause:
1669 let cause = traits::ObligationCause::new(span, self.body_id, code);
1670 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1673 pub fn register_old_wf_obligation(&self,
1676 code: traits::ObligationCauseCode<'tcx>)
1678 // Registers an "old-style" WF obligation that uses the
1679 // implicator code. This is basically a buggy version of
1680 // `register_wf_obligation` that is being kept around
1681 // temporarily just to help with phasing in the newer rules.
1683 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1684 let cause = traits::ObligationCause::new(span, self.body_id, code);
1685 self.register_region_obligation(ty, ty::ReEmpty, cause);
1688 /// Registers obligations that all types appearing in `substs` are well-formed.
1689 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1691 for &ty in &substs.types {
1692 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1696 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1697 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1698 /// trait/region obligations.
1700 /// For example, if there is a function:
1703 /// fn foo<'a,T:'a>(...)
1706 /// and a reference:
1712 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1713 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1714 pub fn add_obligations_for_parameters(&self,
1715 cause: traits::ObligationCause<'tcx>,
1716 predicates: &ty::InstantiatedPredicates<'tcx>)
1718 assert!(!predicates.has_escaping_regions());
1720 debug!("add_obligations_for_parameters(predicates={:?})",
1723 for obligation in traits::predicates_for_generics(cause, predicates) {
1724 self.register_predicate(obligation);
1728 // FIXME(arielb1): use this instead of field.ty everywhere
1729 pub fn field_ty(&self,
1731 field: ty::FieldDef<'tcx>,
1732 substs: &Substs<'tcx>)
1735 self.normalize_associated_types_in(span,
1736 &field.ty(self.tcx(), substs))
1739 // Only for fields! Returns <none> for methods>
1740 // Indifferent to privacy flags
1741 fn check_casts(&self) {
1742 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1743 for cast in deferred_cast_checks.drain(..) {
1748 /// Apply "fallbacks" to some types
1749 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1750 fn default_type_parameters(&self) {
1751 use middle::ty::error::UnconstrainedNumeric::Neither;
1752 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1753 for ty in &self.infcx().unsolved_variables() {
1754 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1755 if self.infcx().type_var_diverges(resolved) {
1756 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1758 match self.infcx().type_is_unconstrained_numeric(resolved) {
1759 UnconstrainedInt => {
1760 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1762 UnconstrainedFloat => {
1763 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1771 fn select_all_obligations_and_apply_defaults(&self) {
1772 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1773 self.new_select_all_obligations_and_apply_defaults();
1775 self.old_select_all_obligations_and_apply_defaults();
1779 // Implements old type inference fallback algorithm
1780 fn old_select_all_obligations_and_apply_defaults(&self) {
1781 self.select_obligations_where_possible();
1782 self.default_type_parameters();
1783 self.select_obligations_where_possible();
1786 fn new_select_all_obligations_and_apply_defaults(&self) {
1787 use middle::ty::error::UnconstrainedNumeric::Neither;
1788 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1790 // For the time being this errs on the side of being memory wasteful but provides better
1792 // let type_variables = self.infcx().type_variables.clone();
1794 // There is a possibility that this algorithm will have to run an arbitrary number of times
1795 // to terminate so we bound it by the compiler's recursion limit.
1796 for _ in 0..self.tcx().sess.recursion_limit.get() {
1797 // First we try to solve all obligations, it is possible that the last iteration
1798 // has made it possible to make more progress.
1799 self.select_obligations_where_possible();
1801 let mut conflicts = Vec::new();
1803 // Collect all unsolved type, integral and floating point variables.
1804 let unsolved_variables = self.inh.infcx.unsolved_variables();
1806 // We must collect the defaults *before* we do any unification. Because we have
1807 // directly attached defaults to the type variables any unification that occurs
1808 // will erase defaults causing conflicting defaults to be completely ignored.
1809 let default_map: FnvHashMap<_, _> =
1812 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1815 let mut unbound_tyvars = HashSet::new();
1817 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1819 // We loop over the unsolved variables, resolving them and if they are
1820 // and unconstrainted numberic type we add them to the set of unbound
1821 // variables. We do this so we only apply literal fallback to type
1822 // variables without defaults.
1823 for ty in &unsolved_variables {
1824 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1825 if self.infcx().type_var_diverges(resolved) {
1826 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1828 match self.infcx().type_is_unconstrained_numeric(resolved) {
1829 UnconstrainedInt | UnconstrainedFloat => {
1830 unbound_tyvars.insert(resolved);
1837 // We now remove any numeric types that also have defaults, and instead insert
1838 // the type variable with a defined fallback.
1839 for ty in &unsolved_variables {
1840 if let Some(_default) = default_map.get(ty) {
1841 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1843 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1846 match resolved.sty {
1847 ty::TyInfer(ty::TyVar(_)) => {
1848 unbound_tyvars.insert(ty);
1851 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1852 unbound_tyvars.insert(ty);
1853 if unbound_tyvars.contains(resolved) {
1854 unbound_tyvars.remove(resolved);
1863 // If there are no more fallbacks to apply at this point we have applied all possible
1864 // defaults and type inference will proceed as normal.
1865 if unbound_tyvars.is_empty() {
1869 // Finally we go through each of the unbound type variables and unify them with
1870 // the proper fallback, reporting a conflicting default error if any of the
1871 // unifications fail. We know it must be a conflicting default because the
1872 // variable would only be in `unbound_tyvars` and have a concrete value if
1873 // it had been solved by previously applying a default.
1875 // We wrap this in a transaction for error reporting, if we detect a conflict
1876 // we will rollback the inference context to its prior state so we can probe
1877 // for conflicts and correctly report them.
1880 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1881 for ty in &unbound_tyvars {
1882 if self.infcx().type_var_diverges(ty) {
1883 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1885 match self.infcx().type_is_unconstrained_numeric(ty) {
1886 UnconstrainedInt => {
1887 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1889 UnconstrainedFloat => {
1890 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1893 if let Some(default) = default_map.get(ty) {
1894 let default = default.clone();
1895 match infer::mk_eqty(self.infcx(), false,
1896 TypeOrigin::Misc(default.origin_span),
1900 conflicts.push((*ty, default));
1909 // If there are conflicts we rollback, otherwise commit
1910 if conflicts.len() > 0 {
1917 if conflicts.len() > 0 {
1918 // Loop through each conflicting default, figuring out the default that caused
1919 // a unification failure and then report an error for each.
1920 for (conflict, default) in conflicts {
1921 let conflicting_default =
1922 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1923 .unwrap_or(type_variable::Default {
1924 ty: self.infcx().next_ty_var(),
1925 origin_span: codemap::DUMMY_SP,
1926 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1929 // This is to ensure that we elimnate any non-determinism from the error
1930 // reporting by fixing an order, it doesn't matter what order we choose
1931 // just that it is consistent.
1932 let (first_default, second_default) =
1933 if default.def_id < conflicting_default.def_id {
1934 (default, conflicting_default)
1936 (conflicting_default, default)
1940 self.infcx().report_conflicting_default_types(
1941 first_default.origin_span,
1948 self.select_obligations_where_possible();
1951 // For use in error handling related to default type parameter fallback. We explicitly
1952 // apply the default that caused conflict first to a local version of the type variable
1953 // table then apply defaults until we find a conflict. That default must be the one
1954 // that caused conflict earlier.
1955 fn find_conflicting_default(&self,
1956 unbound_vars: &HashSet<Ty<'tcx>>,
1957 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1959 -> Option<type_variable::Default<'tcx>> {
1960 use middle::ty::error::UnconstrainedNumeric::Neither;
1961 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1963 // Ensure that we apply the conflicting default first
1964 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1965 unbound_tyvars.push(conflict);
1966 unbound_tyvars.extend(unbound_vars.iter());
1968 let mut result = None;
1969 // We run the same code as above applying defaults in order, this time when
1970 // we find the conflict we just return it for error reporting above.
1972 // We also run this inside snapshot that never commits so we can do error
1973 // reporting for more then one conflict.
1974 for ty in &unbound_tyvars {
1975 if self.infcx().type_var_diverges(ty) {
1976 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1978 match self.infcx().type_is_unconstrained_numeric(ty) {
1979 UnconstrainedInt => {
1980 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1982 UnconstrainedFloat => {
1983 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1986 if let Some(default) = default_map.get(ty) {
1987 let default = default.clone();
1988 match infer::mk_eqty(self.infcx(), false,
1989 TypeOrigin::Misc(default.origin_span),
1993 result = Some(default);
2005 fn select_all_obligations_or_error(&self) {
2006 debug!("select_all_obligations_or_error");
2008 // upvar inference should have ensured that all deferred call
2009 // resolutions are handled by now.
2010 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2012 self.select_all_obligations_and_apply_defaults();
2014 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
2015 match fulfillment_cx.select_all_or_error(self.infcx()) {
2017 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2021 /// Select as many obligations as we can at present.
2022 fn select_obligations_where_possible(&self) {
2024 self.inh.infcx.fulfillment_cx
2026 .select_where_possible(self.infcx())
2029 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2033 /// Try to select any fcx obligation that we haven't tried yet, in an effort
2034 /// to improve inference. You could just call
2035 /// `select_obligations_where_possible` except that it leads to repeated
2037 fn select_new_obligations(&self) {
2039 self.inh.infcx.fulfillment_cx
2041 .select_new_obligations(self.infcx())
2044 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2050 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2051 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2052 Some(self.base_object_lifetime_default(span))
2055 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2056 // RFC #599 specifies that object lifetime defaults take
2057 // precedence over other defaults. But within a fn body we
2058 // don't have a *default* region, rather we use inference to
2059 // find the *correct* region, which is strictly more general
2060 // (and anyway, within a fn body the right region may not even
2061 // be something the user can write explicitly, since it might
2062 // be some expression).
2063 self.infcx().next_region_var(infer::MiscVariable(span))
2066 fn anon_regions(&self, span: Span, count: usize)
2067 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2068 Ok((0..count).map(|_| {
2069 self.infcx().next_region_var(infer::MiscVariable(span))
2074 /// Whether `autoderef` requires types to resolve.
2075 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2076 pub enum UnresolvedTypeAction {
2077 /// Produce an error and return `TyError` whenever a type cannot
2078 /// be resolved (i.e. it is `TyInfer`).
2080 /// Go on without emitting any errors, and return the unresolved
2081 /// type. Useful for probing, e.g. in coercions.
2085 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2086 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2088 /// Note: this method does not modify the adjustments table. The caller is responsible for
2089 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2090 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2093 opt_expr: Option<&hir::Expr>,
2094 unresolved_type_action: UnresolvedTypeAction,
2095 mut lvalue_pref: LvaluePreference,
2097 -> (Ty<'tcx>, usize, Option<T>)
2098 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2100 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2105 let mut t = base_ty;
2106 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2107 let resolved_t = match unresolved_type_action {
2108 UnresolvedTypeAction::Error => {
2109 structurally_resolved_type(fcx, sp, t)
2111 UnresolvedTypeAction::Ignore => {
2112 // We can continue even when the type cannot be resolved
2113 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2114 // and `try_overloaded_deref` both simply return `None`
2115 // in such a case without producing spurious errors.
2116 fcx.resolve_type_vars_if_possible(t)
2119 if resolved_t.references_error() {
2120 return (resolved_t, autoderefs, None);
2123 match should_stop(resolved_t, autoderefs) {
2124 Some(x) => return (resolved_t, autoderefs, Some(x)),
2128 // Otherwise, deref if type is derefable:
2129 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2130 Some(mt) => Some(mt),
2133 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2135 // Super subtle: it might seem as though we should
2136 // pass `opt_expr` to `try_overloaded_deref`, so that
2137 // the (implicit) autoref of using an overloaded deref
2138 // would get added to the adjustment table. However we
2139 // do not do that, because it's kind of a
2140 // "meta-adjustment" -- instead, we just leave it
2141 // unrecorded and know that there "will be" an
2142 // autoref. regionck and other bits of the code base,
2143 // when they encounter an overloaded autoderef, have
2144 // to do some reconstructive surgery. This is a pretty
2145 // complex mess that is begging for a proper MIR.
2146 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2152 if mt.mutbl == hir::MutImmutable {
2153 lvalue_pref = NoPreference;
2156 None => return (resolved_t, autoderefs, None)
2160 // We've reached the recursion limit, error gracefully.
2161 span_err!(fcx.tcx().sess, sp, E0055,
2162 "reached the recursion limit while auto-dereferencing {:?}",
2164 (fcx.tcx().types.err, 0, None)
2167 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2169 method_call: Option<MethodCall>,
2170 base_expr: Option<&hir::Expr>,
2172 lvalue_pref: LvaluePreference)
2173 -> Option<ty::TypeAndMut<'tcx>>
2175 // Try DerefMut first, if preferred.
2176 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2177 (PreferMutLvalue, Some(trait_did)) => {
2178 method::lookup_in_trait(fcx, span, base_expr,
2179 token::intern("deref_mut"), trait_did,
2185 // Otherwise, fall back to Deref.
2186 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2187 (None, Some(trait_did)) => {
2188 method::lookup_in_trait(fcx, span, base_expr,
2189 token::intern("deref"), trait_did,
2192 (method, _) => method
2195 make_overloaded_lvalue_return_type(fcx, method_call, method)
2198 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2199 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2200 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2201 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2202 method_call: Option<MethodCall>,
2203 method: Option<MethodCallee<'tcx>>)
2204 -> Option<ty::TypeAndMut<'tcx>>
2208 // extract method return type, which will be &T;
2209 // all LB regions should have been instantiated during method lookup
2210 let ret_ty = method.ty.fn_ret();
2211 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2213 if let Some(method_call) = method_call {
2214 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2217 // method returns &T, but the type as visible to user is T, so deref
2218 ret_ty.builtin_deref(true, NoPreference)
2224 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2226 base_expr: &'tcx hir::Expr,
2229 lvalue_pref: LvaluePreference)
2230 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2232 // FIXME(#18741) -- this is almost but not quite the same as the
2233 // autoderef that normal method probing does. They could likely be
2236 let (ty, autoderefs, final_mt) = autoderef(fcx,
2240 UnresolvedTypeAction::Error,
2243 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2244 adj_ty, idx, false, lvalue_pref, idx_ty)
2247 if final_mt.is_some() {
2251 // After we have fully autoderef'd, if the resulting type is [T; n], then
2252 // do a final unsized coercion to yield [T].
2253 if let ty::TyArray(element_ty, _) = ty.sty {
2254 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2255 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2256 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2262 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2263 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2264 /// This loop implements one step in that search; the autoderef loop is implemented by
2265 /// `lookup_indexing`.
2266 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2267 method_call: MethodCall,
2269 base_expr: &'tcx hir::Expr,
2270 adjusted_ty: Ty<'tcx>,
2273 lvalue_pref: LvaluePreference,
2275 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2277 let tcx = fcx.tcx();
2278 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2279 autoderefs={}, unsize={}, index_ty={:?})",
2287 let input_ty = fcx.infcx().next_ty_var();
2289 // First, try built-in indexing.
2290 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2291 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2292 debug!("try_index_step: success, using built-in indexing");
2293 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2295 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2296 return Some((tcx.types.usize, ty));
2301 // Try `IndexMut` first, if preferred.
2302 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2303 (PreferMutLvalue, Some(trait_did)) => {
2304 method::lookup_in_trait_adjusted(fcx,
2307 token::intern("index_mut"),
2312 Some(vec![input_ty]))
2317 // Otherwise, fall back to `Index`.
2318 let method = match (method, tcx.lang_items.index_trait()) {
2319 (None, Some(trait_did)) => {
2320 method::lookup_in_trait_adjusted(fcx,
2323 token::intern("index"),
2328 Some(vec![input_ty]))
2330 (method, _) => method,
2333 // If some lookup succeeds, write callee into table and extract index/element
2334 // type from the method signature.
2335 // If some lookup succeeded, install method in table
2336 method.and_then(|method| {
2337 debug!("try_index_step: success, using overloaded indexing");
2338 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2339 map(|ret| (input_ty, ret.ty))
2343 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2345 method_fn_ty: Ty<'tcx>,
2346 callee_expr: &'tcx hir::Expr,
2347 args_no_rcvr: &'tcx [P<hir::Expr>],
2348 tuple_arguments: TupleArgumentsFlag,
2349 expected: Expectation<'tcx>)
2350 -> ty::FnOutput<'tcx> {
2351 if method_fn_ty.references_error() {
2352 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2354 let err_inputs = match tuple_arguments {
2355 DontTupleArguments => err_inputs,
2356 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2359 check_argument_types(fcx,
2366 ty::FnConverging(fcx.tcx().types.err)
2368 match method_fn_ty.sty {
2369 ty::TyBareFn(_, ref fty) => {
2370 // HACK(eddyb) ignore self in the definition (see above).
2371 let expected_arg_tys = expected_types_for_fn_args(fcx,
2375 &fty.sig.0.inputs[1..]);
2376 check_argument_types(fcx,
2378 &fty.sig.0.inputs[1..],
2379 &expected_arg_tys[..],
2386 fcx.tcx().sess.span_bug(callee_expr.span,
2387 "method without bare fn type");
2393 /// Generic function that factors out common logic from function calls, method calls and overloaded
2395 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2397 fn_inputs: &[Ty<'tcx>],
2398 expected_arg_tys: &[Ty<'tcx>],
2399 args: &'tcx [P<hir::Expr>],
2401 tuple_arguments: TupleArgumentsFlag) {
2402 let tcx = fcx.ccx.tcx;
2404 // Grab the argument types, supplying fresh type variables
2405 // if the wrong number of arguments were supplied
2406 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2412 // All the input types from the fn signature must outlive the call
2413 // so as to validate implied bounds.
2414 for &fn_input_ty in fn_inputs {
2415 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2418 let mut expected_arg_tys = expected_arg_tys;
2419 let expected_arg_count = fn_inputs.len();
2420 let formal_tys = if tuple_arguments == TupleArguments {
2421 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2422 match tuple_type.sty {
2423 ty::TyTuple(ref arg_types) => {
2424 if arg_types.len() != args.len() {
2425 span_err!(tcx.sess, sp, E0057,
2426 "this function takes {} parameter{} but {} parameter{} supplied",
2428 if arg_types.len() == 1 {""} else {"s"},
2430 if args.len() == 1 {" was"} else {"s were"});
2431 expected_arg_tys = &[];
2432 err_args(fcx.tcx(), args.len())
2434 expected_arg_tys = match expected_arg_tys.get(0) {
2435 Some(&ty) => match ty.sty {
2436 ty::TyTuple(ref tys) => &**tys,
2441 (*arg_types).clone()
2445 span_err!(tcx.sess, sp, E0059,
2446 "cannot use call notation; the first type parameter \
2447 for the function trait is neither a tuple nor unit");
2448 expected_arg_tys = &[];
2449 err_args(fcx.tcx(), args.len())
2452 } else if expected_arg_count == supplied_arg_count {
2454 } else if variadic {
2455 if supplied_arg_count >= expected_arg_count {
2458 span_err!(tcx.sess, sp, E0060,
2459 "this function takes at least {} parameter{} \
2460 but {} parameter{} supplied",
2462 if expected_arg_count == 1 {""} else {"s"},
2464 if supplied_arg_count == 1 {" was"} else {"s were"});
2465 expected_arg_tys = &[];
2466 err_args(fcx.tcx(), supplied_arg_count)
2469 span_err!(tcx.sess, sp, E0061,
2470 "this function takes {} parameter{} but {} parameter{} supplied",
2472 if expected_arg_count == 1 {""} else {"s"},
2474 if supplied_arg_count == 1 {" was"} else {"s were"});
2475 expected_arg_tys = &[];
2476 err_args(fcx.tcx(), supplied_arg_count)
2479 debug!("check_argument_types: formal_tys={:?}",
2480 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2482 // Check the arguments.
2483 // We do this in a pretty awful way: first we typecheck any arguments
2484 // that are not anonymous functions, then we typecheck the anonymous
2485 // functions. This is so that we have more information about the types
2486 // of arguments when we typecheck the functions. This isn't really the
2487 // right way to do this.
2488 let xs = [false, true];
2489 let mut any_diverges = false; // has any of the arguments diverged?
2490 let mut warned = false; // have we already warned about unreachable code?
2491 for check_blocks in &xs {
2492 let check_blocks = *check_blocks;
2493 debug!("check_blocks={}", check_blocks);
2495 // More awful hacks: before we check argument types, try to do
2496 // an "opportunistic" vtable resolution of any trait bounds on
2497 // the call. This helps coercions.
2499 fcx.select_new_obligations();
2502 // For variadic functions, we don't have a declared type for all of
2503 // the arguments hence we only do our usual type checking with
2504 // the arguments who's types we do know.
2505 let t = if variadic {
2507 } else if tuple_arguments == TupleArguments {
2512 for (i, arg) in args.iter().take(t).enumerate() {
2513 if any_diverges && !warned {
2517 .add_lint(lint::builtin::UNREACHABLE_CODE,
2520 "unreachable expression".to_string());
2523 let is_block = match arg.node {
2524 hir::ExprClosure(..) => true,
2528 if is_block == check_blocks {
2529 debug!("checking the argument");
2530 let formal_ty = formal_tys[i];
2532 // The special-cased logic below has three functions:
2533 // 1. Provide as good of an expected type as possible.
2534 let expected = expected_arg_tys.get(i).map(|&ty| {
2535 Expectation::rvalue_hint(fcx.tcx(), ty)
2538 check_expr_with_unifier(fcx,
2540 expected.unwrap_or(ExpectHasType(formal_ty)),
2542 // 2. Coerce to the most detailed type that could be coerced
2543 // to, which is `expected_ty` if `rvalue_hint` returns an
2544 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2545 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2546 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2548 // 3. Relate the expected type and the formal one,
2549 // if the expected type was used for the coercion.
2550 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2554 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2555 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2558 if any_diverges && !warned {
2559 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2563 .add_lint(lint::builtin::UNREACHABLE_CODE,
2566 "unreachable call".to_string());
2572 // We also need to make sure we at least write the ty of the other
2573 // arguments which we skipped above.
2575 for arg in args.iter().skip(expected_arg_count) {
2576 check_expr(fcx, &**arg);
2578 // There are a few types which get autopromoted when passed via varargs
2579 // in C but we just error out instead and require explicit casts.
2580 let arg_ty = structurally_resolved_type(fcx, arg.span,
2581 fcx.expr_ty(&**arg));
2583 ty::TyFloat(ast::TyF32) => {
2584 fcx.type_error_message(arg.span,
2586 format!("can't pass an {} to variadic \
2587 function, cast to c_double", t)
2590 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2591 fcx.type_error_message(arg.span, |t| {
2592 format!("can't pass {} to variadic \
2593 function, cast to c_int",
2597 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2598 fcx.type_error_message(arg.span, |t| {
2599 format!("can't pass {} to variadic \
2600 function, cast to c_uint",
2610 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2611 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2612 (0..len).map(|_| tcx.types.err).collect()
2615 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2616 call_expr: &hir::Expr,
2617 output: ty::FnOutput<'tcx>) {
2618 fcx.write_ty(call_expr.id, match output {
2619 ty::FnConverging(output_ty) => output_ty,
2620 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2624 // AST fragment checking
2625 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2627 expected: Expectation<'tcx>)
2630 let tcx = fcx.ccx.tcx;
2633 ast::LitStr(..) => tcx.mk_static_str(),
2634 ast::LitByteStr(ref v) => {
2635 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2636 tcx.mk_array(tcx.types.u8, v.len()))
2638 ast::LitByte(_) => tcx.types.u8,
2639 ast::LitChar(_) => tcx.types.char,
2640 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2641 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2642 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2643 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2645 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2646 ty::TyChar => Some(tcx.types.u8),
2647 ty::TyRawPtr(..) => Some(tcx.types.usize),
2648 ty::TyBareFn(..) => Some(tcx.types.usize),
2652 opt_ty.unwrap_or_else(
2653 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2655 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2656 ast::LitFloatUnsuffixed(_) => {
2657 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2659 ty::TyFloat(_) => Some(ty),
2663 opt_ty.unwrap_or_else(
2664 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2666 ast::LitBool(_) => tcx.types.bool
2670 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2671 expr: &'tcx hir::Expr,
2672 expected: Ty<'tcx>) {
2673 check_expr_with_unifier(
2674 fcx, expr, ExpectHasType(expected), NoPreference,
2675 || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2678 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2679 expr: &'tcx hir::Expr,
2680 expected: Ty<'tcx>) {
2681 check_expr_with_unifier(
2682 fcx, expr, ExpectHasType(expected), NoPreference,
2683 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2686 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2687 expr: &'tcx hir::Expr,
2688 expected: Ty<'tcx>) {
2689 check_expr_with_unifier(
2690 fcx, expr, ExpectHasType(expected), NoPreference,
2691 || demand::coerce(fcx, expr.span, expected, expr));
2694 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2695 expected: Ty<'tcx>) {
2696 check_expr_with_unifier(
2697 fcx, expr, ExpectHasType(expected), NoPreference,
2701 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2702 expr: &'tcx hir::Expr,
2703 expected: Expectation<'tcx>) {
2704 check_expr_with_unifier(
2705 fcx, expr, expected, NoPreference,
2709 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2710 expr: &'tcx hir::Expr,
2711 expected: Expectation<'tcx>,
2712 lvalue_pref: LvaluePreference)
2714 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2717 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2718 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2721 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2722 lvalue_pref: LvaluePreference) {
2723 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2726 // determine the `self` type, using fresh variables for all variables
2727 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2728 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2730 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2731 span: Span, // (potential) receiver for this impl
2733 -> TypeAndSubsts<'tcx> {
2734 let tcx = fcx.tcx();
2736 let ity = tcx.lookup_item_type(did);
2737 let (tps, rps, raw_ty) =
2738 (ity.generics.types.get_slice(subst::TypeSpace),
2739 ity.generics.regions.get_slice(subst::TypeSpace),
2742 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2744 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2745 let mut substs = subst::Substs::new(
2746 VecPerParamSpace::empty(),
2747 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2748 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2749 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2751 TypeAndSubsts { substs: substs, ty: substd_ty }
2754 /// Controls whether the arguments are tupled. This is used for the call
2757 /// Tupling means that all call-side arguments are packed into a tuple and
2758 /// passed as a single parameter. For example, if tupling is enabled, this
2761 /// fn f(x: (isize, isize))
2763 /// Can be called as:
2770 #[derive(Clone, Eq, PartialEq)]
2771 enum TupleArgumentsFlag {
2776 /// Unifies the return type with the expected type early, for more coercions
2777 /// and forward type information on the argument expressions.
2778 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2780 expected_ret: Expectation<'tcx>,
2781 formal_ret: ty::FnOutput<'tcx>,
2782 formal_args: &[Ty<'tcx>])
2784 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2785 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2786 fcx.infcx().commit_regions_if_ok(|| {
2787 // Attempt to apply a subtyping relationship between the formal
2788 // return type (likely containing type variables if the function
2789 // is polymorphic) and the expected return type.
2790 // No argument expectations are produced if unification fails.
2791 let origin = TypeOrigin::Misc(call_span);
2792 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2793 // FIXME(#15760) can't use try! here, FromError doesn't default
2794 // to identity so the resulting type is not constrained.
2795 if let Err(e) = ures {
2799 // Record all the argument types, with the substitutions
2800 // produced from the above subtyping unification.
2801 Ok(formal_args.iter().map(|ty| {
2802 fcx.infcx().resolve_type_vars_if_possible(ty)
2808 }).unwrap_or(vec![]);
2809 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2810 formal_args, formal_ret,
2811 expected_args, expected_ret);
2816 /// If an expression has any sub-expressions that result in a type error,
2817 /// inspecting that expression's type with `ty.references_error()` will return
2818 /// true. Likewise, if an expression is known to diverge, inspecting its
2819 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2820 /// strict, _|_ can appear in the type of an expression that does not,
2821 /// itself, diverge: for example, fn() -> _|_.)
2822 /// Note that inspecting a type's structure *directly* may expose the fact
2823 /// that there are actually multiple representations for `TyError`, so avoid
2824 /// that when err needs to be handled differently.
2825 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2826 expr: &'tcx hir::Expr,
2827 expected: Expectation<'tcx>,
2828 lvalue_pref: LvaluePreference,
2832 debug!(">> typechecking: expr={:?} expected={:?}",
2835 // Checks a method call.
2836 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2837 expr: &'tcx hir::Expr,
2838 method_name: Spanned<ast::Name>,
2839 args: &'tcx [P<hir::Expr>],
2841 expected: Expectation<'tcx>,
2842 lvalue_pref: LvaluePreference) {
2843 let rcvr = &*args[0];
2844 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2846 // no need to check for bot/err -- callee does that
2847 let expr_t = structurally_resolved_type(fcx,
2849 fcx.expr_ty(&*rcvr));
2851 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2852 let fn_ty = match method::lookup(fcx,
2860 let method_ty = method.ty;
2861 let method_call = MethodCall::expr(expr.id);
2862 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2866 method::report_error(fcx, method_name.span, expr_t,
2867 method_name.node, Some(rcvr), error);
2868 fcx.write_error(expr.id);
2873 // Call the generic checker.
2874 let ret_ty = check_method_argument_types(fcx,
2882 write_call(fcx, expr, ret_ty);
2885 // A generic function for checking the then and else in an if
2887 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2888 cond_expr: &'tcx hir::Expr,
2889 then_blk: &'tcx hir::Block,
2890 opt_else_expr: Option<&'tcx hir::Expr>,
2893 expected: Expectation<'tcx>) {
2894 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2896 let expected = expected.adjust_for_branches(fcx);
2897 check_block_with_expected(fcx, then_blk, expected);
2898 let then_ty = fcx.node_ty(then_blk.id);
2900 let branches_ty = match opt_else_expr {
2901 Some(ref else_expr) => {
2902 check_expr_with_expectation(fcx, &**else_expr, expected);
2903 let else_ty = fcx.expr_ty(&**else_expr);
2904 infer::common_supertype(fcx.infcx(),
2905 TypeOrigin::IfExpression(sp),
2911 infer::common_supertype(fcx.infcx(),
2912 TypeOrigin::IfExpressionWithNoElse(sp),
2919 let cond_ty = fcx.expr_ty(cond_expr);
2920 let if_ty = if cond_ty.references_error() {
2926 fcx.write_ty(id, if_ty);
2929 // Check field access expressions
2930 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2931 expr: &'tcx hir::Expr,
2932 lvalue_pref: LvaluePreference,
2933 base: &'tcx hir::Expr,
2934 field: &Spanned<ast::Name>) {
2935 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2936 let expr_t = structurally_resolved_type(fcx, expr.span,
2938 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2939 let (_, autoderefs, field_ty) = autoderef(fcx,
2943 UnresolvedTypeAction::Error,
2947 ty::TyStruct(base_def, substs) => {
2948 debug!("struct named {:?}", base_t);
2949 base_def.struct_variant()
2950 .find_field_named(field.node)
2951 .map(|f| fcx.field_ty(expr.span, f, substs))
2958 fcx.write_ty(expr.id, field_ty);
2959 fcx.write_autoderef_adjustment(base.id, autoderefs);
2965 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2966 fcx.type_error_struct(field.span,
2968 format!("attempted to take value of method `{}` on type \
2969 `{}`", field.node, actual)
2972 .fileline_help(field.span,
2973 "maybe a `()` to call it is missing? \
2974 If not, try an anonymous function")
2977 let mut err = fcx.type_error_struct(
2980 format!("attempted access of field `{}` on \
2981 type `{}`, but no field with that \
2987 if let ty::TyStruct(def, _) = expr_t.sty {
2988 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2993 fcx.write_error(expr.id);
2996 // displays hints about the closest matches in field names
2997 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2998 variant: ty::VariantDef<'tcx>,
2999 field: &Spanned<ast::Name>,
3000 skip : Vec<InternedString>) {
3001 let name = field.node.as_str();
3002 let names = variant.fields
3004 .filter_map(|ref field| {
3005 // ignore already set fields and private fields from non-local crates
3006 if skip.iter().any(|x| *x == field.name.as_str()) ||
3007 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3014 // only find fits with at least one matching letter
3015 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3016 err.span_help(field.span,
3017 &format!("did you mean `{}`?", name));
3021 // Check tuple index expressions
3022 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3023 expr: &'tcx hir::Expr,
3024 lvalue_pref: LvaluePreference,
3025 base: &'tcx hir::Expr,
3026 idx: codemap::Spanned<usize>) {
3027 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3028 let expr_t = structurally_resolved_type(fcx, expr.span,
3030 let mut tuple_like = false;
3031 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3032 let (_, autoderefs, field_ty) = autoderef(fcx,
3036 UnresolvedTypeAction::Error,
3040 ty::TyStruct(base_def, substs) => {
3041 tuple_like = base_def.struct_variant().is_tuple_struct();
3043 debug!("tuple struct named {:?}", base_t);
3044 base_def.struct_variant()
3047 .map(|f| fcx.field_ty(expr.span, f, substs))
3052 ty::TyTuple(ref v) => {
3054 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3061 fcx.write_ty(expr.id, field_ty);
3062 fcx.write_autoderef_adjustment(base.id, autoderefs);
3067 fcx.type_error_message(
3071 format!("attempted out-of-bounds tuple index `{}` on \
3076 format!("attempted tuple index `{}` on type `{}`, but the \
3077 type was not a tuple or tuple struct",
3084 fcx.write_error(expr.id);
3087 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3089 variant: ty::VariantDef<'tcx>,
3091 skip_fields: &[hir::Field]) {
3092 let mut err = fcx.type_error_struct(
3094 |actual| if let ty::TyEnum(..) = ty.sty {
3095 format!("struct variant `{}::{}` has no field named `{}`",
3096 actual, variant.name.as_str(), field.name.node)
3098 format!("structure `{}` has no field named `{}`",
3099 actual, field.name.node)
3103 // prevent all specified fields from being suggested
3104 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3105 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3109 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3112 variant: ty::VariantDef<'tcx>,
3113 ast_fields: &'tcx [hir::Field],
3114 check_completeness: bool) {
3115 let tcx = fcx.ccx.tcx;
3116 let substs = match adt_ty.sty {
3117 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3118 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3121 let mut remaining_fields = FnvHashMap();
3122 for field in &variant.fields {
3123 remaining_fields.insert(field.name, field);
3126 let mut error_happened = false;
3128 // Typecheck each field.
3129 for field in ast_fields {
3130 let expected_field_type;
3132 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3133 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3135 error_happened = true;
3136 expected_field_type = tcx.types.err;
3137 if let Some(_) = variant.find_field_named(field.name.node) {
3138 span_err!(fcx.tcx().sess, field.name.span, E0062,
3139 "field `{}` specified more than once",
3142 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3146 // Make sure to give a type to the field even if there's
3147 // an error, so we can continue typechecking
3148 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3151 // Make sure the programmer specified all the fields.
3152 if check_completeness &&
3154 !remaining_fields.is_empty()
3156 span_err!(tcx.sess, span, E0063,
3157 "missing field{} {} in initializer of `{}`",
3158 if remaining_fields.len() == 1 {""} else {"s"},
3159 remaining_fields.keys()
3160 .map(|n| format!("`{}`", n))
3161 .collect::<Vec<_>>()
3168 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3170 fields: &'tcx [hir::Field],
3171 base_expr: &'tcx Option<P<hir::Expr>>) {
3172 // Make sure to still write the types
3173 // otherwise we might ICE
3174 fcx.write_error(id);
3175 for field in fields {
3176 check_expr(fcx, &*field.expr);
3179 Some(ref base) => check_expr(fcx, &**base),
3184 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3187 fields: &'tcx [hir::Field],
3188 base_expr: &'tcx Option<P<hir::Expr>>)
3190 let tcx = fcx.tcx();
3192 // Find the relevant variant
3193 let def = lookup_full_def(tcx, path.span, expr.id);
3194 if def == def::DefErr {
3195 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3198 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3199 Some((adt, variant)) => (adt, variant),
3201 span_err!(fcx.tcx().sess, path.span, E0071,
3202 "`{}` does not name a structure",
3203 pprust::path_to_string(path));
3204 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3209 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3210 fcx.write_ty(expr.id, expr_ty);
3212 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3213 base_expr.is_none());
3215 if let &Some(ref base_expr) = base_expr {
3216 check_expr_has_type(fcx, base_expr, expr_ty);
3217 if adt.adt_kind() == ty::AdtKind::Enum {
3218 span_err!(tcx.sess, base_expr.span, E0436,
3219 "functional record update syntax requires a struct");
3224 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3226 let tcx = fcx.ccx.tcx;
3229 hir::ExprBox(ref subexpr) => {
3230 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3232 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3236 check_expr_with_expectation(fcx, subexpr, expected_inner);
3237 let referent_ty = fcx.expr_ty(&**subexpr);
3238 fcx.write_ty(id, tcx.mk_box(referent_ty));
3241 hir::ExprLit(ref lit) => {
3242 let typ = check_lit(fcx, &**lit, expected);
3243 fcx.write_ty(id, typ);
3245 hir::ExprBinary(op, ref lhs, ref rhs) => {
3246 op::check_binop(fcx, expr, op, lhs, rhs);
3248 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3249 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3251 hir::ExprUnary(unop, ref oprnd) => {
3252 let expected_inner = match unop {
3253 hir::UnNot | hir::UnNeg => {
3260 let lvalue_pref = match unop {
3261 hir::UnDeref => lvalue_pref,
3264 check_expr_with_expectation_and_lvalue_pref(
3265 fcx, &**oprnd, expected_inner, lvalue_pref);
3266 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3268 if !oprnd_t.references_error() {
3271 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3272 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3274 None => match try_overloaded_deref(fcx, expr.span,
3275 Some(MethodCall::expr(expr.id)),
3276 Some(&**oprnd), oprnd_t, lvalue_pref) {
3279 fcx.type_error_message(expr.span, |actual| {
3280 format!("type `{}` cannot be \
3281 dereferenced", actual)
3289 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3291 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3292 oprnd_t = op::check_user_unop(fcx, "!", "not",
3293 tcx.lang_items.not_trait(),
3294 expr, &**oprnd, oprnd_t, unop);
3298 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3300 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3301 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3302 tcx.lang_items.neg_trait(),
3303 expr, &**oprnd, oprnd_t, unop);
3308 fcx.write_ty(id, oprnd_t);
3310 hir::ExprAddrOf(mutbl, ref oprnd) => {
3311 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3313 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3314 if fcx.tcx().expr_is_lval(&**oprnd) {
3315 // Lvalues may legitimately have unsized types.
3316 // For example, dereferences of a fat pointer and
3317 // the last field of a struct can be unsized.
3318 ExpectHasType(mt.ty)
3320 Expectation::rvalue_hint(tcx, mt.ty)
3326 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3327 check_expr_with_expectation_and_lvalue_pref(fcx,
3332 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3333 let oprnd_t = if tm.ty.references_error() {
3336 // Note: at this point, we cannot say what the best lifetime
3337 // is to use for resulting pointer. We want to use the
3338 // shortest lifetime possible so as to avoid spurious borrowck
3339 // errors. Moreover, the longest lifetime will depend on the
3340 // precise details of the value whose address is being taken
3341 // (and how long it is valid), which we don't know yet until type
3342 // inference is complete.
3344 // Therefore, here we simply generate a region variable. The
3345 // region inferencer will then select the ultimate value.
3346 // Finally, borrowck is charged with guaranteeing that the
3347 // value whose address was taken can actually be made to live
3348 // as long as it needs to live.
3349 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3350 tcx.mk_ref(tcx.mk_region(region), tm)
3352 fcx.write_ty(id, oprnd_t);
3354 hir::ExprPath(ref maybe_qself, ref path) => {
3355 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3356 fcx.to_ty(&qself.ty)
3359 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3361 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3362 // Create some fake resolution that can't possibly be a type.
3363 def::PathResolution {
3364 base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3365 last_private: LastMod(AllPublic),
3366 depth: path.segments.len()
3369 tcx.sess.span_bug(expr.span,
3370 &format!("unbound path {:?}", expr))
3373 if let Some((opt_ty, segments, def)) =
3374 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3375 expr.span, expr.id) {
3376 if def != def::DefErr {
3377 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3380 instantiate_path(fcx,
3389 fcx.write_ty(id, fcx.tcx().types.err);
3393 // We always require that the type provided as the value for
3394 // a type parameter outlives the moment of instantiation.
3395 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3396 fcx.add_wf_bounds(&item_substs.substs, expr);
3399 hir::ExprInlineAsm(ref ia) => {
3400 for &(_, ref input) in &ia.inputs {
3401 check_expr(fcx, &**input);
3403 for out in &ia.outputs {
3404 check_expr(fcx, &*out.expr);
3408 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3409 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3410 hir::ExprRet(ref expr_opt) => {
3412 ty::FnConverging(result_type) => {
3415 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3416 result_type, fcx.tcx().mk_nil()) {
3417 span_err!(tcx.sess, expr.span, E0069,
3418 "`return;` in a function whose return type is \
3422 check_expr_coercable_to_type(fcx, &**e, result_type);
3426 ty::FnDiverging => {
3427 if let Some(ref e) = *expr_opt {
3428 check_expr(fcx, &**e);
3430 span_err!(tcx.sess, expr.span, E0166,
3431 "`return` in a function declared as diverging");
3434 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3436 hir::ExprAssign(ref lhs, ref rhs) => {
3437 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3439 let tcx = fcx.tcx();
3440 if !tcx.expr_is_lval(&**lhs) {
3441 span_err!(tcx.sess, expr.span, E0070,
3442 "invalid left-hand side expression");
3445 let lhs_ty = fcx.expr_ty(&**lhs);
3446 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3447 let rhs_ty = fcx.expr_ty(&**rhs);
3449 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3451 if lhs_ty.references_error() || rhs_ty.references_error() {
3452 fcx.write_error(id);
3457 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3458 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3459 id, expr.span, expected);
3461 hir::ExprWhile(ref cond, ref body, _) => {
3462 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3463 check_block_no_value(fcx, &**body);
3464 let cond_ty = fcx.expr_ty(&**cond);
3465 let body_ty = fcx.node_ty(body.id);
3466 if cond_ty.references_error() || body_ty.references_error() {
3467 fcx.write_error(id);
3473 hir::ExprLoop(ref body, _) => {
3474 check_block_no_value(fcx, &**body);
3475 if !may_break(tcx, expr.id, &**body) {
3476 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3481 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3482 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3484 hir::ExprClosure(capture, ref decl, ref body) => {
3485 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3487 hir::ExprBlock(ref b) => {
3488 check_block_with_expected(fcx, &**b, expected);
3489 fcx.write_ty(id, fcx.node_ty(b.id));
3491 hir::ExprCall(ref callee, ref args) => {
3492 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3494 // we must check that return type of called functions is WF:
3495 let ret_ty = fcx.expr_ty(expr);
3496 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3498 hir::ExprMethodCall(name, ref tps, ref args) => {
3499 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3500 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3501 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3503 fcx.write_error(id);
3506 hir::ExprCast(ref e, ref t) => {
3507 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3508 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3511 // Find the type of `e`. Supply hints based on the type we are casting to,
3513 let t_cast = fcx.to_ty(t);
3514 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3515 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3516 let t_expr = fcx.expr_ty(e);
3517 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3519 // Eagerly check for some obvious errors.
3520 if t_expr.references_error() || t_cast.references_error() {
3521 fcx.write_error(id);
3522 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3523 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3525 // Write a type for the whole expression, assuming everything is going
3527 fcx.write_ty(id, t_cast);
3529 // Defer other checks until we're done type checking.
3530 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3531 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3532 deferred_cast_checks.push(cast_check);
3535 hir::ExprType(ref e, ref t) => {
3536 let typ = fcx.to_ty(&**t);
3537 check_expr_eq_type(fcx, &**e, typ);
3538 fcx.write_ty(id, typ);
3540 hir::ExprVec(ref args) => {
3541 let uty = expected.to_option(fcx).and_then(|uty| {
3543 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3548 let typ = match uty {
3551 check_expr_coercable_to_type(fcx, &**e, uty);
3556 let t: Ty = fcx.infcx().next_ty_var();
3558 check_expr_has_type(fcx, &**e, t);
3563 let typ = tcx.mk_array(typ, args.len());
3564 fcx.write_ty(id, typ);
3566 hir::ExprRepeat(ref element, ref count_expr) => {
3567 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3568 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3570 let uty = match expected {
3571 ExpectHasType(uty) => {
3573 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3580 let (element_ty, t) = match uty {
3582 check_expr_coercable_to_type(fcx, &**element, uty);
3586 let t: Ty = fcx.infcx().next_ty_var();
3587 check_expr_has_type(fcx, &**element, t);
3588 (fcx.expr_ty(&**element), t)
3593 // For [foo, ..n] where n > 1, `foo` must have
3595 fcx.require_type_meets(
3602 if element_ty.references_error() {
3603 fcx.write_error(id);
3605 let t = tcx.mk_array(t, count);
3606 fcx.write_ty(id, t);
3609 hir::ExprTup(ref elts) => {
3610 let flds = expected.only_has_type(fcx).and_then(|ty| {
3612 ty::TyTuple(ref flds) => Some(&flds[..]),
3616 let mut err_field = false;
3618 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3619 let t = match flds {
3620 Some(ref fs) if i < fs.len() => {
3622 check_expr_coercable_to_type(fcx, &**e, ety);
3626 check_expr_with_expectation(fcx, &**e, NoExpectation);
3630 err_field = err_field || t.references_error();
3634 fcx.write_error(id);
3636 let typ = tcx.mk_tup(elt_ts);
3637 fcx.write_ty(id, typ);
3640 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3641 check_expr_struct(fcx, expr, path, fields, base_expr);
3643 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3645 hir::ExprField(ref base, ref field) => {
3646 check_field(fcx, expr, lvalue_pref, &**base, field);
3648 hir::ExprTupField(ref base, idx) => {
3649 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3651 hir::ExprIndex(ref base, ref idx) => {
3652 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3653 check_expr(fcx, &**idx);
3655 let base_t = fcx.expr_ty(&**base);
3656 let idx_t = fcx.expr_ty(&**idx);
3658 if base_t.references_error() {
3659 fcx.write_ty(id, base_t);
3660 } else if idx_t.references_error() {
3661 fcx.write_ty(id, idx_t);
3663 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3664 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3665 Some((index_ty, element_ty)) => {
3666 let idx_expr_ty = fcx.expr_ty(idx);
3667 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3668 fcx.write_ty(id, element_ty);
3671 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3672 fcx.type_error_message(
3675 format!("cannot index a value of type `{}`",
3680 fcx.write_ty(id, fcx.tcx().types.err);
3685 hir::ExprRange(ref start, ref end) => {
3686 let t_start = start.as_ref().map(|e| {
3687 check_expr(fcx, &**e);
3690 let t_end = end.as_ref().map(|e| {
3691 check_expr(fcx, &**e);
3695 let idx_type = match (t_start, t_end) {
3696 (Some(ty), None) | (None, Some(ty)) => {
3699 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3700 t_end.references_error()) => {
3701 Some(fcx.tcx().types.err)
3703 (Some(t_start), Some(t_end)) => {
3704 Some(infer::common_supertype(fcx.infcx(),
3705 TypeOrigin::RangeExpression(expr.span),
3713 // Note that we don't check the type of start/end satisfy any
3714 // bounds because right now the range structs do not have any. If we add
3715 // some bounds, then we'll need to check `t_start` against them here.
3717 let range_type = match idx_type {
3718 Some(idx_type) if idx_type.references_error() => {
3722 // Find the did from the appropriate lang item.
3723 let did = match (start, end) {
3724 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3725 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3726 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3728 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3732 if let Some(did) = did {
3733 let def = tcx.lookup_adt_def(did);
3734 let predicates = tcx.lookup_predicates(did);
3735 let substs = Substs::new_type(vec![idx_type], vec![]);
3736 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3737 fcx.add_obligations_for_parameters(
3738 traits::ObligationCause::new(expr.span,
3740 traits::ItemObligation(did)),
3743 tcx.mk_struct(def, tcx.mk_substs(substs))
3745 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3750 // Neither start nor end => RangeFull
3751 if let Some(did) = tcx.lang_items.range_full_struct() {
3753 tcx.lookup_adt_def(did),
3754 tcx.mk_substs(Substs::empty())
3757 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3763 fcx.write_ty(id, range_type);
3768 debug!("type of expr({}) {} is...", expr.id,
3769 pprust::expr_to_string(expr));
3770 debug!("... {:?}, expected is {:?}",
3777 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3778 path_res: def::PathResolution,
3779 opt_self_ty: Option<Ty<'tcx>>,
3780 path: &'a hir::Path,
3782 node_id: ast::NodeId)
3783 -> Option<(Option<Ty<'tcx>>,
3784 &'a [hir::PathSegment],
3788 // Associated constants can't depend on generic types.
3789 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3793 node_id: ast::NodeId) -> bool {
3795 def::DefAssociatedConst(..) => {
3796 if ty.has_param_types() || ty.has_self_ty() {
3797 span_err!(fcx.sess(), span, E0329,
3798 "Associated consts cannot depend \
3799 on type parameters or Self.");
3800 fcx.write_error(node_id);
3809 // If fully resolved already, we don't have to do anything.
3810 if path_res.depth == 0 {
3811 if let Some(ty) = opt_self_ty {
3812 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3817 Some((opt_self_ty, &path.segments, path_res.base_def))
3819 let mut def = path_res.base_def;
3820 let ty_segments = path.segments.split_last().unwrap().1;
3821 let base_ty_end = path.segments.len() - path_res.depth;
3822 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3823 PathParamMode::Optional,
3826 &ty_segments[..base_ty_end],
3827 &ty_segments[base_ty_end..]);
3828 let item_segment = path.segments.last().unwrap();
3829 let item_name = item_segment.identifier.name;
3830 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3832 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3835 // Write back the new resolution.
3836 fcx.ccx.tcx.def_map.borrow_mut()
3837 .insert(node_id, def::PathResolution {
3839 last_private: path_res.last_private.or(lp),
3842 Some((Some(ty), slice::ref_slice(item_segment), def))
3845 method::report_error(fcx, span, ty,
3846 item_name, None, error);
3847 fcx.write_error(node_id);
3854 impl<'tcx> Expectation<'tcx> {
3855 /// Provide an expectation for an rvalue expression given an *optional*
3856 /// hint, which is not required for type safety (the resulting type might
3857 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3858 /// is useful in determining the concrete type.
3860 /// The primary use case is where the expected type is a fat pointer,
3861 /// like `&[isize]`. For example, consider the following statement:
3863 /// let x: &[isize] = &[1, 2, 3];
3865 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3866 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3867 /// expectation `ExpectHasType([isize])`, that would be too strong --
3868 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3869 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3870 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3871 /// which still is useful, because it informs integer literals and the like.
3872 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3873 /// for examples of where this comes up,.
3874 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3875 match tcx.struct_tail(ty).sty {
3876 ty::TySlice(_) | ty::TyTrait(..) => {
3877 ExpectRvalueLikeUnsized(ty)
3879 _ => ExpectHasType(ty)
3883 // Resolves `expected` by a single level if it is a variable. If
3884 // there is no expected type or resolution is not possible (e.g.,
3885 // no constraints yet present), just returns `None`.
3886 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3891 ExpectCastableToType(t) => {
3892 ExpectCastableToType(
3893 fcx.infcx().resolve_type_vars_if_possible(&t))
3895 ExpectHasType(t) => {
3897 fcx.infcx().resolve_type_vars_if_possible(&t))
3899 ExpectRvalueLikeUnsized(t) => {
3900 ExpectRvalueLikeUnsized(
3901 fcx.infcx().resolve_type_vars_if_possible(&t))
3906 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3907 match self.resolve(fcx) {
3908 NoExpectation => None,
3909 ExpectCastableToType(ty) |
3911 ExpectRvalueLikeUnsized(ty) => Some(ty),
3915 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3916 match self.resolve(fcx) {
3917 ExpectHasType(ty) => Some(ty),
3923 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3924 local: &'tcx hir::Local,
3925 init: &'tcx hir::Expr)
3927 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3929 let local_ty = fcx.local_ty(init.span, local.id);
3930 if let Some(m) = ref_bindings {
3931 // Somewhat subtle: if we have a `ref` binding in the pattern,
3932 // we want to avoid introducing coercions for the RHS. This is
3933 // both because it helps preserve sanity and, in the case of
3934 // ref mut, for soundness (issue #23116). In particular, in
3935 // the latter case, we need to be clear that the type of the
3936 // referent for the reference that results is *equal to* the
3937 // type of the lvalue it is referencing, and not some
3938 // supertype thereof.
3939 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3940 let init_ty = fcx.expr_ty(init);
3941 demand::eqtype(fcx, init.span, init_ty, local_ty);
3943 check_expr_coercable_to_type(fcx, init, local_ty)
3947 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3948 let tcx = fcx.ccx.tcx;
3950 let t = fcx.local_ty(local.span, local.id);
3951 fcx.write_ty(local.id, t);
3953 if let Some(ref init) = local.init {
3954 check_decl_initializer(fcx, local, &**init);
3955 let init_ty = fcx.expr_ty(&**init);
3956 if init_ty.references_error() {
3957 fcx.write_ty(local.id, init_ty);
3961 let pcx = pat_ctxt {
3963 map: pat_id_map(&tcx.def_map, &*local.pat),
3965 _match::check_pat(&pcx, &*local.pat, t);
3966 let pat_ty = fcx.node_ty(local.pat.id);
3967 if pat_ty.references_error() {
3968 fcx.write_ty(local.id, pat_ty);
3972 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3974 let mut saw_bot = false;
3975 let mut saw_err = false;
3977 hir::StmtDecl(ref decl, id) => {
3980 hir::DeclLocal(ref l) => {
3981 check_decl_local(fcx, &**l);
3982 let l_t = fcx.node_ty(l.id);
3983 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3984 saw_err = saw_err || l_t.references_error();
3986 hir::DeclItem(_) => {/* ignore for now */ }
3989 hir::StmtExpr(ref expr, id) => {
3991 // Check with expected type of ()
3992 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3993 let expr_ty = fcx.expr_ty(&**expr);
3994 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3995 saw_err = saw_err || expr_ty.references_error();
3997 hir::StmtSemi(ref expr, id) => {
3999 check_expr(fcx, &**expr);
4000 let expr_ty = fcx.expr_ty(&**expr);
4001 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
4002 saw_err |= expr_ty.references_error();
4006 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
4009 fcx.write_error(node_id);
4012 fcx.write_nil(node_id)
4016 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
4017 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
4018 let blkty = fcx.node_ty(blk.id);
4019 if blkty.references_error() {
4020 fcx.write_error(blk.id);
4022 let nilty = fcx.tcx().mk_nil();
4023 demand::suptype(fcx, blk.span, nilty, blkty);
4027 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4028 blk: &'tcx hir::Block,
4029 expected: Expectation<'tcx>) {
4031 let mut fcx_ps = fcx.ps.borrow_mut();
4032 let unsafety_state = fcx_ps.recurse(blk);
4033 replace(&mut *fcx_ps, unsafety_state)
4036 let mut warned = false;
4037 let mut any_diverges = false;
4038 let mut any_err = false;
4039 for s in &blk.stmts {
4041 let s_id = ::rustc_front::util::stmt_id(s);
4042 let s_ty = fcx.node_ty(s_id);
4043 if any_diverges && !warned && match s.node {
4044 hir::StmtDecl(ref decl, _) => {
4046 hir::DeclLocal(_) => true,
4050 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4055 .add_lint(lint::builtin::UNREACHABLE_CODE,
4058 "unreachable statement".to_string());
4061 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4062 any_err = any_err || s_ty.references_error();
4065 None => if any_err {
4066 fcx.write_error(blk.id);
4067 } else if any_diverges {
4068 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4070 fcx.write_nil(blk.id);
4073 if any_diverges && !warned {
4077 .add_lint(lint::builtin::UNREACHABLE_CODE,
4080 "unreachable expression".to_string());
4082 let ety = match expected {
4083 ExpectHasType(ety) => {
4084 check_expr_coercable_to_type(fcx, &**e, ety);
4088 check_expr_with_expectation(fcx, &**e, expected);
4094 fcx.write_error(blk.id);
4095 } else if any_diverges {
4096 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4098 fcx.write_ty(blk.id, ety);
4103 *fcx.ps.borrow_mut() = prev;
4106 /// Checks a constant appearing in a type. At the moment this is just the
4107 /// length expression in a fixed-length vector, but someday it might be
4108 /// extended to type-level numeric literals.
4109 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4110 expr: &'tcx hir::Expr,
4111 expected_type: Ty<'tcx>) {
4112 let tables = RefCell::new(ty::Tables::empty());
4113 let inh = static_inherited_fields(ccx, &tables);
4114 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4115 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4118 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4122 let tables = RefCell::new(ty::Tables::empty());
4123 let inh = static_inherited_fields(ccx, &tables);
4124 let rty = ccx.tcx.node_id_to_type(id);
4125 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4126 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4127 check_const_with_ty(&fcx, sp, e, declty);
4130 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4134 // Gather locals in statics (because of block expressions).
4135 // This is technically unnecessary because locals in static items are forbidden,
4136 // but prevents type checking from blowing up before const checking can properly
4138 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4140 check_expr_with_hint(fcx, e, declty);
4141 demand::coerce(fcx, e.span, declty, e);
4143 fcx.select_all_obligations_and_apply_defaults();
4144 upvar::closure_analyze_const(&fcx, e);
4145 fcx.select_obligations_where_possible();
4147 fcx.select_all_obligations_or_error();
4149 regionck::regionck_expr(fcx, e);
4150 writeback::resolve_type_vars_in_expr(fcx, e);
4153 /// Checks whether a type can be represented in memory. In particular, it
4154 /// identifies types that contain themselves without indirection through a
4155 /// pointer, which would mean their size is unbounded.
4156 pub fn check_representable(tcx: &ty::ctxt,
4158 item_id: ast::NodeId,
4159 designation: &str) -> bool {
4160 let rty = tcx.node_id_to_type(item_id);
4162 // Check that it is possible to represent this type. This call identifies
4163 // (1) types that contain themselves and (2) types that contain a different
4164 // recursive type. It is only necessary to throw an error on those that
4165 // contain themselves. For case 2, there must be an inner type that will be
4166 // caught by case 1.
4167 match rty.is_representable(tcx, sp) {
4168 Representability::SelfRecursive => {
4169 struct_span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation)
4170 .fileline_help(sp, "wrap the inner value in a box to make it representable")
4174 Representability::Representable | Representability::ContainsRecursive => (),
4179 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4180 let t = tcx.node_id_to_type(id);
4182 ty::TyStruct(def, substs) => {
4183 let fields = &def.struct_variant().fields;
4184 if fields.is_empty() {
4185 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4188 let e = fields[0].ty(tcx, substs);
4189 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4190 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4194 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4195 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4197 span_err!(tcx.sess, sp, E0077,
4198 "SIMD vector element type should be machine type");
4207 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4209 vs: &'tcx [hir::Variant],
4212 fn disr_in_range(ccx: &CrateCtxt,
4214 disr: ty::Disr) -> bool {
4215 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4217 ast::TyU8 => disr as u8 as Disr == disr,
4218 ast::TyU16 => disr as u16 as Disr == disr,
4219 ast::TyU32 => disr as u32 as Disr == disr,
4220 ast::TyU64 => disr as u64 as Disr == disr,
4221 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4224 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4226 ast::TyI8 => disr as i8 as Disr == disr,
4227 ast::TyI16 => disr as i16 as Disr == disr,
4228 ast::TyI32 => disr as i32 as Disr == disr,
4229 ast::TyI64 => disr as i64 as Disr == disr,
4230 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4234 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4235 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4239 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4240 vs: &'tcx [hir::Variant],
4242 hint: attr::ReprAttr) {
4243 #![allow(trivial_numeric_casts)]
4245 let rty = ccx.tcx.node_id_to_type(id);
4246 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4248 let tables = RefCell::new(ty::Tables::empty());
4249 let inh = static_inherited_fields(ccx, &tables);
4250 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4252 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4254 if let Some(ref e) = v.node.disr_expr {
4255 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4259 let def_id = ccx.tcx.map.local_def_id(id);
4261 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4262 for (v, variant) in vs.iter().zip(variants.iter()) {
4263 let current_disr_val = variant.disr_val;
4265 // Check for duplicate discriminant values
4266 match disr_vals.iter().position(|&x| x == current_disr_val) {
4268 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4269 "discriminant value `{}` already exists", disr_vals[i]);
4270 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4271 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4272 "conflicting discriminant here");
4277 // Check for unrepresentable discriminant values
4279 attr::ReprAny | attr::ReprExtern => (),
4280 attr::ReprInt(sp, ity) => {
4281 if !disr_in_range(ccx, ity, current_disr_val) {
4282 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4283 "discriminant value outside specified type");
4284 span_note!(&mut err, sp,
4285 "discriminant type specified here");
4290 ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4292 attr::ReprPacked => {
4293 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4296 disr_vals.push(current_disr_val);
4300 let def_id = ccx.tcx.map.local_def_id(id);
4301 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4303 if hint != attr::ReprAny && vs.len() <= 1 {
4305 span_err!(ccx.tcx.sess, sp, E0083,
4306 "unsupported representation for univariant enum");
4308 span_err!(ccx.tcx.sess, sp, E0084,
4309 "unsupported representation for zero-variant enum");
4313 do_check(ccx, vs, id, hint);
4315 check_representable(ccx.tcx, sp, id, "enum");
4318 // Returns the type parameter count and the type for the given definition.
4319 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4322 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4324 def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4325 let typ = fcx.local_ty(sp, nid);
4326 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4327 ty::GenericPredicates::empty())
4329 def::DefFn(id, _) | def::DefMethod(id) |
4330 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4331 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4332 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4336 def::DefAssociatedTy(..) |
4338 def::DefTyParam(..) |
4340 def::DefForeignMod(..) |
4342 def::DefSelfTy(..) |
4344 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4349 // Instantiates the given path, which must refer to an item with the given
4350 // number of type parameters and type.
4351 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4352 segments: &[hir::PathSegment],
4353 type_scheme: TypeScheme<'tcx>,
4354 type_predicates: &ty::GenericPredicates<'tcx>,
4355 opt_self_ty: Option<Ty<'tcx>>,
4358 node_id: ast::NodeId) {
4359 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4365 // We need to extract the type parameters supplied by the user in
4366 // the path `path`. Due to the current setup, this is a bit of a
4367 // tricky-process; the problem is that resolve only tells us the
4368 // end-point of the path resolution, and not the intermediate steps.
4369 // Luckily, we can (at least for now) deduce the intermediate steps
4370 // just from the end-point.
4372 // There are basically four cases to consider:
4374 // 1. Reference to a *type*, such as a struct or enum:
4376 // mod a { struct Foo<T> { ... } }
4378 // Because we don't allow types to be declared within one
4379 // another, a path that leads to a type will always look like
4380 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4381 // that only the final segment can have type parameters, and
4382 // they are located in the TypeSpace.
4384 // *Note:* Generally speaking, references to types don't
4385 // actually pass through this function, but rather the
4386 // `ast_ty_to_ty` function in `astconv`. However, in the case
4387 // of struct patterns (and maybe literals) we do invoke
4388 // `instantiate_path` to get the general type of an instance of
4389 // a struct. (In these cases, there are actually no type
4390 // parameters permitted at present, but perhaps we will allow
4391 // them in the future.)
4393 // 1b. Reference to an enum variant or tuple-like struct:
4395 // struct foo<T>(...)
4396 // enum E<T> { foo(...) }
4398 // In these cases, the parameters are declared in the type
4401 // 2. Reference to a *fn item*:
4405 // In this case, the path will again always have the form
4406 // `a::b::foo::<T>` where only the final segment should have
4407 // type parameters. However, in this case, those parameters are
4408 // declared on a value, and hence are in the `FnSpace`.
4410 // 3. Reference to a *method*:
4412 // impl<A> SomeStruct<A> {
4416 // Here we can have a path like
4417 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4418 // may appear in two places. The penultimate segment,
4419 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4420 // final segment, `foo::<B>` contains parameters in fn space.
4422 // 4. Reference to an *associated const*:
4424 // impl<A> AnotherStruct<A> {
4425 // const FOO: B = BAR;
4428 // The path in this case will look like
4429 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4430 // only will have parameters in TypeSpace.
4432 // The first step then is to categorize the segments appropriately.
4434 assert!(!segments.is_empty());
4436 let mut ufcs_associated = None;
4437 let mut segment_spaces: Vec<_>;
4439 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4440 def::DefSelfTy(..) |
4441 def::DefStruct(..) |
4442 def::DefVariant(..) |
4444 def::DefAssociatedTy(..) |
4446 def::DefPrimTy(..) |
4447 def::DefTyParam(..) => {
4448 // Everything but the final segment should have no
4449 // parameters at all.
4450 segment_spaces = vec![None; segments.len() - 1];
4451 segment_spaces.push(Some(subst::TypeSpace));
4454 // Case 2. Reference to a top-level value.
4457 def::DefStatic(..) => {
4458 segment_spaces = vec![None; segments.len() - 1];
4459 segment_spaces.push(Some(subst::FnSpace));
4462 // Case 3. Reference to a method.
4463 def::DefMethod(def_id) => {
4464 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4466 ty::TraitContainer(trait_did) => {
4467 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4469 ty::ImplContainer(_) => {}
4472 if segments.len() >= 2 {
4473 segment_spaces = vec![None; segments.len() - 2];
4474 segment_spaces.push(Some(subst::TypeSpace));
4475 segment_spaces.push(Some(subst::FnSpace));
4477 // `<T>::method` will end up here, and so can `T::method`.
4478 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4479 segment_spaces = vec![Some(subst::FnSpace)];
4480 ufcs_associated = Some((container, self_ty));
4484 def::DefAssociatedConst(def_id) => {
4485 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4487 ty::TraitContainer(trait_did) => {
4488 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4490 ty::ImplContainer(_) => {}
4493 if segments.len() >= 2 {
4494 segment_spaces = vec![None; segments.len() - 2];
4495 segment_spaces.push(Some(subst::TypeSpace));
4496 segment_spaces.push(None);
4498 // `<T>::CONST` will end up here, and so can `T::CONST`.
4499 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4500 segment_spaces = vec![None];
4501 ufcs_associated = Some((container, self_ty));
4505 // Other cases. Various nonsense that really shouldn't show up
4506 // here. If they do, an error will have been reported
4507 // elsewhere. (I hope)
4509 def::DefForeignMod(..) |
4514 segment_spaces = vec![None; segments.len()];
4517 assert_eq!(segment_spaces.len(), segments.len());
4519 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4520 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4521 // type parameters are not mandatory.
4522 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4524 debug!("segment_spaces={:?}", segment_spaces);
4526 // Next, examine the definition, and determine how many type
4527 // parameters we expect from each space.
4528 let type_defs = &type_scheme.generics.types;
4529 let region_defs = &type_scheme.generics.regions;
4531 // Now that we have categorized what space the parameters for each
4532 // segment belong to, let's sort out the parameters that the user
4533 // provided (if any) into their appropriate spaces. We'll also report
4534 // errors if type parameters are provided in an inappropriate place.
4535 let mut substs = Substs::empty();
4536 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4539 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4543 push_explicit_parameters_from_segment_to_substs(fcx,
4553 if let Some(self_ty) = opt_self_ty {
4554 if type_defs.len(subst::SelfSpace) == 1 {
4555 substs.types.push(subst::SelfSpace, self_ty);
4559 // Now we have to compare the types that the user *actually*
4560 // provided against the types that were *expected*. If the user
4561 // did not provide any types, then we want to substitute inference
4562 // variables. If the user provided some types, we may still need
4563 // to add defaults. If the user provided *too many* types, that's
4565 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4566 adjust_type_parameters(fcx, span, space, type_defs,
4567 require_type_space, &mut substs);
4568 assert_eq!(substs.types.len(space), type_defs.len(space));
4570 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4571 assert_eq!(substs.regions().len(space), region_defs.len(space));
4574 // The things we are substituting into the type should not contain
4575 // escaping late-bound regions, and nor should the base type scheme.
4576 assert!(!substs.has_regions_escaping_depth(0));
4577 assert!(!type_scheme.has_escaping_regions());
4579 // Add all the obligations that are required, substituting and
4580 // normalized appropriately.
4581 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4582 fcx.add_obligations_for_parameters(
4583 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4586 // Substitute the values for the type parameters into the type of
4587 // the referenced item.
4588 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4591 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4592 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4593 // is inherent, there is no `Self` parameter, instead, the impl needs
4594 // type parameters, which we can infer by unifying the provided `Self`
4595 // with the substituted impl type.
4596 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4597 assert_eq!(substs.types.len(subst::TypeSpace),
4598 impl_scheme.generics.types.len(subst::TypeSpace));
4599 assert_eq!(substs.regions().len(subst::TypeSpace),
4600 impl_scheme.generics.regions.len(subst::TypeSpace));
4602 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4603 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4604 fcx.tcx().sess.span_bug(span,
4606 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4612 debug!("instantiate_path: type of {:?} is {:?}",
4615 fcx.write_ty(node_id, ty_substituted);
4616 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4619 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4620 /// parameters are provided, then reports an error and clears the output vector.
4622 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4623 /// use inference variables. This seems less likely to lead to derived errors.
4625 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4626 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4627 /// here because we can easily use the precise span of the N+1'th parameter.
4628 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4629 fcx: &FnCtxt<'a, 'tcx>,
4630 space: subst::ParamSpace,
4632 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4633 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4634 segment: &hir::PathSegment,
4635 substs: &mut Substs<'tcx>)
4637 match segment.parameters {
4638 hir::AngleBracketedParameters(ref data) => {
4639 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4640 fcx, space, type_defs, region_defs, data, substs);
4643 hir::ParenthesizedParameters(ref data) => {
4644 span_err!(fcx.tcx().sess, span, E0238,
4645 "parenthesized parameters may only be used with a trait");
4646 push_explicit_parenthesized_parameters_from_segment_to_substs(
4647 fcx, space, span, type_defs, data, substs);
4652 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4653 fcx: &FnCtxt<'a, 'tcx>,
4654 space: subst::ParamSpace,
4655 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4656 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4657 data: &hir::AngleBracketedParameterData,
4658 substs: &mut Substs<'tcx>)
4661 let type_count = type_defs.len(space);
4662 assert_eq!(substs.types.len(space), 0);
4663 for (i, typ) in data.types.iter().enumerate() {
4664 let t = fcx.to_ty(&**typ);
4666 substs.types.push(space, t);
4667 } else if i == type_count {
4668 span_err!(fcx.tcx().sess, typ.span, E0087,
4669 "too many type parameters provided: \
4670 expected at most {} parameter{}, \
4671 found {} parameter{}",
4673 if type_count == 1 {""} else {"s"},
4675 if data.types.len() == 1 {""} else {"s"});
4676 substs.types.truncate(space, 0);
4682 if !data.bindings.is_empty() {
4683 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4684 "unexpected binding of associated item in expression path \
4685 (only allowed in type paths)");
4689 let region_count = region_defs.len(space);
4690 assert_eq!(substs.regions().len(space), 0);
4691 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4692 let r = ast_region_to_region(fcx.tcx(), lifetime);
4693 if i < region_count {
4694 substs.mut_regions().push(space, r);
4695 } else if i == region_count {
4696 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4697 "too many lifetime parameters provided: \
4698 expected {} parameter{}, found {} parameter{}",
4700 if region_count == 1 {""} else {"s"},
4701 data.lifetimes.len(),
4702 if data.lifetimes.len() == 1 {""} else {"s"});
4703 substs.mut_regions().truncate(space, 0);
4711 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4712 /// but intended for `Foo(A,B) -> C` form. This expands to
4713 /// roughly the same thing as `Foo<(A,B),C>`. One important
4714 /// difference has to do with the treatment of anonymous
4715 /// regions, which are translated into bound regions (NYI).
4716 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4717 fcx: &FnCtxt<'a, 'tcx>,
4718 space: subst::ParamSpace,
4720 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4721 data: &hir::ParenthesizedParameterData,
4722 substs: &mut Substs<'tcx>)
4724 let type_count = type_defs.len(space);
4726 span_err!(fcx.tcx().sess, span, E0167,
4727 "parenthesized form always supplies 2 type parameters, \
4728 but only {} parameter(s) were expected",
4732 let input_tys: Vec<Ty> =
4733 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4735 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4737 if type_count >= 1 {
4738 substs.types.push(space, tuple_ty);
4741 let output_ty: Option<Ty> =
4742 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4745 output_ty.unwrap_or(fcx.tcx().mk_nil());
4747 if type_count >= 2 {
4748 substs.types.push(space, output_ty);
4752 fn adjust_type_parameters<'a, 'tcx>(
4753 fcx: &FnCtxt<'a, 'tcx>,
4756 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4757 require_type_space: bool,
4758 substs: &mut Substs<'tcx>)
4760 let provided_len = substs.types.len(space);
4761 let desired = defs.get_slice(space);
4762 let required_len = desired.iter()
4763 .take_while(|d| d.default.is_none())
4766 debug!("adjust_type_parameters(space={:?}, \
4775 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4776 assert!(provided_len <= desired.len());
4778 // Nothing specified at all: supply inference variables for
4780 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4781 substs.types.replace(space, Vec::new());
4782 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4786 // Too few parameters specified: report an error and use Err
4788 if provided_len < required_len {
4790 if desired.len() != required_len { "at least " } else { "" };
4791 span_err!(fcx.tcx().sess, span, E0089,
4792 "too few type parameters provided: expected {}{} parameter{}, \
4793 found {} parameter{}",
4794 qualifier, required_len,
4795 if required_len == 1 {""} else {"s"},
4797 if provided_len == 1 {""} else {"s"});
4798 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4802 // Otherwise, add in any optional parameters that the user
4803 // omitted. The case of *too many* parameters is handled
4805 // push_explicit_parameters_from_segment_to_substs(). Note
4806 // that the *default* type are expressed in terms of all prior
4807 // parameters, so we have to substitute as we go with the
4808 // partial substitution that we have built up.
4809 for i in provided_len..desired.len() {
4810 let default = desired[i].default.unwrap();
4811 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4812 substs.types.push(space, default);
4814 assert_eq!(substs.types.len(space), desired.len());
4816 debug!("Final substs: {:?}", substs);
4819 fn adjust_region_parameters(
4823 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4824 substs: &mut Substs)
4826 let provided_len = substs.mut_regions().len(space);
4827 let desired = defs.get_slice(space);
4829 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4830 assert!(provided_len <= desired.len());
4832 // If nothing was provided, just use inference variables.
4833 if provided_len == 0 {
4834 substs.mut_regions().replace(
4836 fcx.infcx().region_vars_for_defs(span, desired));
4840 // If just the right number were provided, everybody is happy.
4841 if provided_len == desired.len() {
4845 // Otherwise, too few were provided. Report an error and then
4846 // use inference variables.
4847 span_err!(fcx.tcx().sess, span, E0090,
4848 "too few lifetime parameters provided: expected {} parameter{}, \
4849 found {} parameter{}",
4851 if desired.len() == 1 {""} else {"s"},
4853 if provided_len == 1 {""} else {"s"});
4855 substs.mut_regions().replace(
4857 fcx.infcx().region_vars_for_defs(span, desired));
4861 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4865 where F: Fn() -> Ty<'tcx>
4867 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4870 let alternative = f();
4873 if alternative.is_ty_var() || alternative.references_error() {
4874 fcx.type_error_message(sp, |_actual| {
4875 "the type of this value must be known in this context".to_string()
4877 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4878 ty = fcx.tcx().types.err;
4880 demand::suptype(fcx, sp, alternative, ty);
4888 // Resolves `typ` by a single level if `typ` is a type variable. If no
4889 // resolution is possible, then an error is reported.
4890 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4895 structurally_resolve_type_or_else(fcx, sp, ty, || {
4900 // Returns true if b contains a break that can exit from b
4901 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4902 // First: is there an unlabeled break immediately
4904 (loop_query(&*b, |e| {
4906 hir::ExprBreak(None) => true,
4910 // Second: is there a labeled break with label
4911 // <id> nested anywhere inside the loop?
4912 (block_query(b, |e| {
4913 if let hir::ExprBreak(Some(_)) = e.node {
4914 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4921 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4922 tps: &[hir::TyParam],
4924 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4927 // make a vector of booleans initially false, set to true when used
4928 if tps.is_empty() { return; }
4929 let mut tps_used = vec![false; tps.len()];
4931 for leaf_ty in ty.walk() {
4932 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4933 debug!("Found use of ty param num {}", idx);
4934 tps_used[idx as usize] = true;
4938 for (i, b) in tps_used.iter().enumerate() {
4940 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4941 "type parameter `{}` is unused",